Сложите целое число, чтобы сэкономить место!

20

Безумный математик владеет обширной коллекцией чисел, и поэтому оставленное им пространство довольно ограничено. Чтобы сэкономить, он должен сложить целые числа, но, к сожалению, он действительно ленив. Ваша задача, если вы хотите помочь ему, - создать функцию / программу, которая складывает данное положительное целое число для нашего числового маньяка.

Как сложить целое число?

Если он делится равномерно на сумму его цифр, разделите его на сумму его цифр. Если он не удовлетворяет этому требованию, возьмите его остаток, разделив его на сумму цифр. Повторяйте процесс, пока не достигнете результата 1. Сложенное целое число - это количество операций, которые вам пришлось выполнить. Давайте возьмем пример (скажем 1782):

  1. Получить сумму цифр: 1 + 7 + 8 + 2 = 18. 1782равномерно делится на 18, так что следующий номер 1782 / 18 = 99.

  2. 99не нацело 9 + 9 = 18, поэтому мы берем остаток: 99 % 18 = 9.

  3. 9очевидно делится на 9, поэтому мы делим его и получаем 1.

Результат 3, потому что 3 операции были необходимы для достижения 1.

Правила и характеристики

  • Некоторые целые числа могут иметь сумму цифр 1, такую ​​как 10или 100. Ваша программа не должна обрабатывать такие случаи. Это означает, что вам будет гарантировано, что целое число, данное в качестве входных данных, не будет иметь сумму цифр, равную 1, и никакая операция с данным целым числом не приведет к числу, чья сумма цифр равна 1(за исключением 1самого себя, которое является " мишень "). Например, вы никогда не получите 10или 20как вход.

  • Входное значение будет положительным целым числом выше, чем 1.

  • Применяются стандартные лазейки .

  • Вы можете принимать входные данные и предоставлять выходные данные любым стандартным способом .


Тестовые случаи

Вход -> Выход

2 -> 1
5 -> 1
9 -> 1
18 -> 2
72 -> 2
152790 -> 2
152 -> 3
666 -> 3
777 -> 3
2010 -> 3
898786854 -> 4

Вот программа, которая позволяет вам визуализировать процесс и пробовать больше тестовых случаев.


Это , поэтому выигрывает самый короткий код на каждом языке (в байтах)!

Мистер Xcoder
источник
Вдохновленный этим вызовом , хотя на первый взгляд он может показаться не связанным.
Мистер Кскодер
3
Это будет работать как временное решение, но в долгосрочной перспективе математик должен действительно подумать о покупке одного из отелей Гильберта . Вы всегда можете найти неиспользованную комнату в одном из них.
Рэй
в то время 8987868546как допустимый ввод, он сломает ваш тестовый инструмент, а также многие (если не все) ответы ...
Миша
@MischaBehrend Ваш пример недопустим. Я думаю, вы ошиблись в моем последнем тесте. Действительный ввод был 898786854, а не 8987868546(вы добавили 6в конце)
г-н Xcoder
nvm ... должен прочитать все первое правило ... оставив это здесь, чтобы вы знали, почему я думал, что это действительно: это не было ошибкой ... я изменил это намеренно, чтобы протестировать эти сценарии ... и читать правила является допустимым входом. Сумма всех цифр 8987868546 не равна 1 ( правило 1 выполнено ) и 8987868546является положительным целым числом, превышающим 1 ( правило 2 выполнено ).
Миша

Ответы:

6

05AB1E , 13 12 байт

[¼DSO‰0Kθ©#®

Попробуйте онлайн!

объяснение

[               # start loop
 ¼              # increment counter
  D             # duplicate current value
   SO           # sum the digits in the copy
     ‰          # divmod the current value by its digit-sum
      0K        # remove 0 from the resulting list
        θ       # pop the last element
         ©      # store a copy in register
          #     # if the current value is 1, break
           ®    # push the copy from register
                # implicitly output counter
Emigna
источник
6

Python 2 , 63 57 байт

-1 благодаря полностью человеку
-1 благодаря мистеру Xcoder
-4 благодаря reffu

def f(n):a=sum(map(int,`n`));return n>1and-~f(n%a or n/a)

Попробуйте онлайн!

Arfie
источник
1
57 байт. Также мои извинения за то, что я сначала сделал этот ответ. Это имеет больше смысла в качестве комментария
reffu
5

Haskell, 85 78 байт

f 1=0
f n|r<1=1+f(n`div`s)|1<2=1+f r where s=sum(read.pure<$>show n);r=n`rem`s

Сохранено 7 байтов благодаря Брюсу Форте.

Попробуйте онлайн.

Кристиан Лупаску
источник
Сохраните еще несколько байтов, используя divModи опуская where: Попробуйте онлайн!
Лайкони
@Laikoni Ух ты, это значительное улучшение! Пожалуйста, отправьте это как другой ответ; это достаточно отличается от моего. Кстати: я искал трюк, чтобы избавиться от where. Я буду использовать это в будущем. :)
Кристиан Лупаску
sum[read[d]|d<-show n]сохраняет байт
nimi
5

JavaScript (ES6), 66 58 51 49 байт

Принимает ввод как целое число. Возвращает falseдля 0или 1и выдает ошибку переполнения, когда встречает любое число, цифры которого складываются до 1.

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1

Проверь это

o.innerText=(

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1

)(i.value=898786854);oninput=_=>o.innerText=f(+i.value)
<input id=i type=number><pre id=o>

мохнатый
источник
1
Не могли бы вы сохранить несколько байтов, суммируя цифры с помощью eval(array.join`+`)?
Джастин Маринер,
Я мог бы, @JustinMariner - вы меня на это ниндзя! Спасибо :)
Лохматый
4

Шелуха , 12 байт

←€1¡Ṡ§|÷%oΣd

Попробуйте онлайн!

объяснение

←€1¡Ṡ§|÷%oΣd  Implicit input, e.g. n=1782
    Ṡ§|÷%oΣd  This part defines the transformation.
         oΣ   Sum of
           d  digits: s=18
    Ṡ   %     n mod s: 0
     §|       or (take this branch if last result was 0)
       ÷      n divided by s: 99
   ¡          Iterate the transformation: [1782,99,9,1,1,1,...
 €1           Index of 1 (1-based): 4
←             Decrement: 3
              Print implicitly.
Zgarb
источник
3

Japt , 22 19 17 байт

-3 байта благодаря @Shaggy.
-2 байта благодаря @ETHproductions


ìx
>1©1+ßU%VªU/V

Попробуйте онлайн!

Джастин Маринер
источник
1
<ы> 20 байт </ с> 19 байт
Shaggy
1
На самом деле, вы можете изменить s_¬это, ìчтобы сохранить еще два байта :-)
ETHproductions
@ETHproductions О, это действительно круто, спасибо!
Джастин Маринер,
2

Сетчатка , 100 байт

$
;
{`(.+);
$1$*1;$&
(?<=;.*)\d(?=.*;)
$*
.*;1;(.*)
$.1
r`(1)*(\3)*;(1+);
$#1;$#2;1
0;(.*);|;.*;
$1;

Попробуйте онлайн! Ссылка включает только меньшие контрольные примеры, так как большие занимают слишком много времени.

Нил
источник
2

Mathematica, 73 байта

(t=#;For[r=0,t>1,r++,If[(s=Mod[t,g=Tr@IntegerDigits@t])<1,t=t/g,t=s]];r)&
J42161217
источник
Можно ==0заменить на <1?
Мистер Кскодер
@ Mr.Xcoder да, конечно! Я сделал сортировочную версию ...
J42161217
2

PHP, 68 + 1 байт

одинарный вывод:

for($n=$argn;$n>1;$n=$n%($s=array_sum(str_split($n)))?:$n/$s)echo 1;

десятичный вывод, 73 + 1 байт:

for($n=$argn;$n>1;$i++)$n=$n%($s=array_sum(str_split($n)))?:$n/$s;echo$i;

Запустите как трубу с -nRили попробуйте онлайн .


Для оператора Элвиса требуется PHP 5.3 или новее. Для более старых версий PHP заменить ?:на ?$n%$s:(+5 байт).

Titus
источник
2

Рубин, 46 байт

f=->n{s=n.digits.sum;n<2?0:1+f[n%s<1?n/s:n%s]}
м-chrzan
источник
2

Хаскелл , 94 93 89 88 байт

Это чувствует себя очень долго ..

length.fst.span(/=1).iterate g
g x|(d,m)<-x`divMod`sum[read[d]|d<-show x]=last$m:[d|m<1]

Попробуйте онлайн!

Спасибо @Laikoni & @nimi за то, что вы играете в гольф по 1 байту каждый!

ბიმო
источник
1

Желе , 12 байт

dDS$Ṛȯ/µÐĿL’

Попробуйте онлайн!

Эрик Outgolfer
источник
Интересный подход! Теперь мы ждем Джонатана: P
Мистер Xcoder
@ Mr.Xcoder На этот раз я так не думаю :)
Эрик Аутгольфер
И я тоже, это была шутка :)
Мистер Xcoder
1

Perl, 71 байт, 64 байта, 63 байта

-pl

$c=0;while($_>1){$s=0;$s+=$_ for/./g;$_=$_%$s?$_%$s:$_/$s;++$c};$_=$c

Попробуйте онлайн

РЕДАКТИРОВАТЬ: сохранено 7 байтов, благодаря комментарию Xcali

-p

while($_>1){$s=0;$s+=$_ for/./g;$_=$_%$s?$_%$s:$_/$s;++$c}$_=$c

РЕДАКТИРОВАТЬ: с 5.14 неразрушающего замещения s /// r

-pl

while($_>1){$s=eval s/\B/+/gr;$_=$_%$s?$_%$s:$_/$s;++$c}$_=$c
Науэль Фуйе
источник
Является ли -plна вершине должен быть флаг командной строки вместо этого?
Эрик Outgolfer
да, это варианты perl
Науэль Фуйе
Вы должны считать -plфлаг согласно этому посту .
Эрик Outgolfer
Я подсчитал 69 байтов +2 для опций pl, это правильно?
Науэль Фуйе
Вы можете немного поиграть в гольф. $cне нужно инициализировать. Начнется с undefнуля. Через некоторое время точка с запятой может идти. Кроме того, вам не нужно -l. Не требуется принимать несколько входов за один прогон.
Xcali
1

Дьялог АПЛ, 36 байт

{x←+/⍎¨⍕⍵⋄1=⍵:00=x|⍵:1+∇⍵÷x1+∇x|⍵}

Попробуйте онлайн!

Как?

{
   x←+/⍎¨⍕⍵       x = digit sum
   1=⍵:0          if arg = 1: bye
   0=x|⍵:1+∇⍵÷x   if arg divisible by x: recurse with arg/x
   1+∇x|⍵         recurse with arg mod x
}
Уриэль
источник
1

Gaia , 13 байт

-@{:ΣZ¤∨)‡}°\

Попробуйте онлайн!

объяснение

-              Push -1 (this will be the counter)
 @             Push input (the starting number)
  {:ΣZ¤∨)‡}°   Repeat this block until the results of 2 consecutive runs are the same:
   :            Copy the number
    Σ           Digital sum
     Z          Divmod number by digital sum
      ¤         Swap
       ∨        Logical or: left-most non-zero out of (number mod sum, number div sum)
        )‡      Increment the counter
            \  Delete the final 1, implicitly print the counter
Бизнес Кот
источник
1

Matlab, 150 байт

function[d]=X(x) 
d=0;while ~strcmp(x,'1')z='sum(str2num(x(:)))';a=eval(['rem(',x,',',z,')']);y=num2str(a*(a>0)+eval([x,'/',z])*(a==0));x=y;d=d+1;end

Входные данные должны быть даны функции в виде строки, такой как X ('152').

Функция работает при цикле и приращении d. x=y;Линия была необходима , чтобы избежать ошибки Matlab пытается прочитать и переписать значение переменной в то же время, по- видимому, который был для меня новым.

Ungolfed:

function[d]=X(x) 
d=0;
while ~strcmp(x,'1')
    z='sum(str2num(x(:)))';
    a=eval(['rem(',x,',',z,')']);
    y=num2str(a*(a>0)+eval([x,'/',z])*(a==0));
    x=y;
    d=d+1;
end
синтаксис
источник