Мультипликативная стойкость

46

Мультипликативная стойкость

  1. Умножьте все цифры в числе
  2. Повторяйте, пока у вас не останется ни одной цифры

Как объяснил Numberphile :

пример

  1. 277777788888899 → 2x7x7x7x7x7x7x8x8x8x8x8x8x9x9 = 4996238671872
  2. 4996238671872 → 4x9x9x6x2x3x8x6x7x1x8x7x2 = 438939648
  3. 438939648 → 4x3x8x9x3x9x6x4x8 = 4478976
  4. 4478976 → 4x4x7x8x9x7x6 = 338688
  5. 338688 → 3x3x8x6x8x8 = 27648
  6. 27648 → 2x7x6x4x8 = 2688
  7. 2688 → 2x6x8x8 = 768
  8. 768 → 7x6x8 = 336
  9. 336 → 3x3x6 = 54
  10. 54 → 5x4 = 20
  11. 20 → 2x0 = 0

Кстати, это текущая запись: наименьшее число с наибольшим количеством шагов.

Гольф

Программа, которая принимает любое целое число в качестве входных данных и затем выводит результат каждого шага, начиная с самого ввода, пока мы не нажмем одну цифру. Для 277777788888899 вывод должен быть

277777788888899
4996238671872
438939648
4478976
338688
27648
2688
768
336
54
20
0

(Подсчет количества шагов оставлен пользователю в качестве упражнения).

Больше примеров

От A003001 :

25
10
0

От A003001, а также:

68889
27648
2688
768
336
54
20
0

Из видео Numberphile :

327
42
8

Таким образом, был вопрос о аддитивной персистенции , но это мультипликативная персистентность. Кроме того, этот вопрос запрашивает количество шагов в качестве вывода, в то время как мне интересно увидеть промежуточные результаты.

SQB
источник
Бонус: найдите новую запись: наименьшее число с наибольшим количеством шагов. Предостережение: есть предположение, что 11 является наибольшим из возможных.
SQB
7
Вероятно, вам следует включить еще несколько тестов, которые не заканчиваются на . 0
Арно,
Пришел сделать этот пост, нашел его уже существующим, gg
cat
допустимый ввод одной цифры?
Дзайма
1
В видео Numberphile Мэтт Паркер утверждает, что поиски были выполнены до нескольких сотен цифр.
HardScale

Ответы:

7

Желе , 4 байта

DP$Ƭ

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

объяснение

D    | convert to decimal digits
 P   | take the product
  $  | previous two links as a monad
   Ƭ | loop until no change, collecting all intermediate results

В качестве бонуса, вот TIO, который найдет числа с наибольшим количеством шагов для заданного диапазона чисел. Хорошо масштабируется даже на TIO.

Ник Кеннеди
источник
15

TI-BASIC (TI-84), 30 32 31 байт

-1 байт благодаря @SolomonUcko!

While Ans>9:Disp Ans:prod(int(10fPart(Ans10^(seq(-X-1,X,0,log(Ans:End:Ans

Вход находится в Ans.
Выходные данные отображаются в виде запросов на вызов. Трейлинг Ansнеобходим для печати последнего шага.

Я признаю, я не думал об этой формуле сам, скорее я нашел это здесь и изменил это, чтобы лучше соответствовать проблеме.

РЕДАКТИРОВАТЬ: После перечитывания проблемы, я понял, что программа должна завершиться, если продукт состоит из одной цифры. Следовательно, 2 байта должны были быть добавлены для учета этого.

Пример:

24456756
        24456756
prgmCDGF8
        24456756
          201600
               0
11112
           11112
prgmCDGF8
           11112
               2

Объяснение:

While Ans>9               ;loop until the product is one digit
Disp Ans                  ;display the current product
prod(                     ;get the product of...
 int(                     ; the integer part of...
  10fPart(                ; ten times the fractional part of...
  Ans                     ; each element in the following list times the
                          ;  current product
  10^(                    ; multiplied by the list generated by using each
                          ;  element of the following list as an exponent
                          ;  for 10^n
   seq(-X-1),X,0,log(Ans  ; generate a list of exponents from -1 to -L where
                          ;  L = the length of the current product
End
Ans                       ;leave the final product in "Ans" and implicitly
                          ; print it

Визуальная модель:
Ans начинается как 125673.
Эта модель охватывает только логику умножения цифр; все остальное легче понять.

seq(-X-1,X,0,log(Ans  =>  seq(-X-1,X,0,5.0992
   {-1 -2 -3 -4 -5 -6}
10^(...
   {.1 .01 .001 1E-4 1E-5 1E-6}
Ans...
   {12567.3 1256.73 125.673 12.5673 1.25673 .125673}
fPart(...
   {.3 .73 .673 .5673 .25673 .125673}
10...
   {3 7.3 6.73 5.673 2.5673 1.25673}
int(...
   {3 7 6 5 2 1}
   (the digits of the number, reversed)
prod(...
   1260
   (process is repeated again)

seq(-X-1,X,0,log(Ans  =>  seq(-X-1,X,0,3.1004
   {-1 -2 -3 -4}
10^(...
   {.1 .01 .001 1E-4}
Ans...
   {126 12.6 1.26 .126}
fPart(...
   {0 .6 .26 .126}
10...
   {0 6 2.6 1.26}
int(...
   {0 6 2 1}
prod(...
   0
   (product is less than 10.  loop ends)

Примечания:

TI-BASIC - это токенизированный язык. Количество символов не равно количеству байтов.

10^(это этот один байт маркера .

Эта программа не обеспечивает правильную последовательность продуктов с целыми числами длиной более 14 цифр из-за ограничений десятичной точности на калькуляторах TI.

Тау
источник
Можете ли вы сохранить байт, выйдя 10^(наружу seq(и пропустив закрывающую скобку?
Соломон Уко
Да, я верю в это!
Тау
11

К (нгн / к) , 9 байт

{*/.'$x}\

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

{ }\ продолжайте применять функцию в фигурных скобках, пока последовательность не сходится

$x отформатировать аргумент в виде строки (список символов)

.'оценивать каждый (другие диалекты k требуют двоеточия, .:')

*/ раз, то есть продукт

СПП
источник
8

R , 59 байт

n=scan();while(print(n)>9)n=prod(n%/%10^(nchar(n):1-1)%%10)

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

Так как print invisiblyвозвращает входные данные, мы можем использовать print(n)внутри whileцикла для имитации do-whileцикла. Это вдохновлено одним из моих советов для игры в гольф в R .

Заголовок помогает предотвратить печать больших чисел в научной записи.

Giuseppe
источник
7

Python 2 ,  46  43 байта

-3 благодаря xnor (цепное сравнение)

def f(n):print n;n>9>f(eval('*'.join(`n`)))

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

Джонатан Аллан
источник
Вы можете сделать >вместо and.
xnor
@ xnor спасибо, легко забыть, что сработает.
Джонатан Аллан
5

PowerShell , 54 байта

for($a=$args;$a-gt9){$a;$a=("$a"|% t*y)-join"*"|iex}$a

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


Итерационный метод, который сначала записывает входной аргумент, затем преобразует его в строку и передает в массив символов. Этот массив объединяется одиночными звездочками и выполняется как команда с псевдонимом выражения invoke. Так как это записывает начальный номер до последнего числа больше 0 (20, в данном тестовом сценарии), я добавляю $aокончание к концу для вывода.

KGlasier
источник
5

C # (интерактивный компилятор Visual C #) , 79 74 68 байт

void f(int a){Print(a);if(a>9)f((a+"").Aggregate(1,(j,k)=>k%48*j));}

Я стараюсь держаться подальше от рекурсии в C # из-за того, как долго объявление метода, но в этом случае оно экономит по сравнению с циклом.

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

Воплощение невежества
источник
5

PHP , 63 байта

<?=$n=$argn;while($n>9)echo"
",$n=array_product(str_split($n));

Итерационная версия, вызов с php -nFвводом из STDIN.

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

PHP ,72 71 байт

function h($n){echo"$n
",($n=array_product(str_split($n)))>9?h($n):$n;}

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

Рекурсивная версия, как функция.

Ввод: 277777788888899

277777788888899
4996238671872
438939648
4478976
338688
27648
2688
768
336
54
20
0

Вход: 23

23
6
640 КБ
источник
5

Python 2 , 61 62 59 байт

def f(n):print n;n>9and f(reduce(int.__mul__,map(int,`n`)))

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

-3 байта, благодаря Джонатану Аллану

TFeld
источник
Не работает для входных данных, которые не заканчиваются на 0 на их последней итерации, например 23
Embodiment of Ignorance
int.__mul__на три байта меньшеlambda a,b:a*b
Джонатан Аллан
@JonathanAllan Спасибо! Я знал, что должно быть что-то подобное
TFeld
Изменить, f(reduce(int.__mul__,map(int,`n`)))чтобы f(eval('*'.join(`n`)))сохранить 13 байтов.
Mypetlion
@mypetlion ... Я уже сделал это в другом посте.
Джонатан Аллан
5

Perl 5 ( -n -M5.01), 32 30 25 байт

say$_=eval;s/\B/*/g&&redo

25 байт

30 байт

32 байта

Науэль Фуйе
источник
Вы должны упомянуть, что это использует-lpF//
Grimmy
1
@ Грими, я мог бы сэкономить 2 байта, не используя -lpF//, обновление
Науэль Фуйе
5

MathGolf , 9 10 байт

h(ôo▒ε*h(→

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

Теперь он правильно обрабатывает входные данные, которые состоят из одной цифры. Не идеально, но по крайней мере это правильно.

объяснение

h(            check length of input number and decrease by 1
  ö       →   while true with pop using the next 6 operators
   p          print with newline
    ▒         split to list of chars/digits
     ε*       reduce list by multiplication
       h(     length of TOS without popping, subtracted by 1 (exits when len(TOS) == 1)
maxb
источник
Выходные данные для ввода одной цифры должны быть одной копией числа - поясняется в комментариях
dzaima
@dzaima Я посмотрю на это и
обновлю
4

APL (NARS), 19 символов, 38 байтов

{⍵≤9:⍵⋄∇×/⍎¨⍕⍵⊣⎕←⍵}

контрольная работа:

   f←{⍵≤9:⍵⋄∇×/⍎¨⍕⍵⊣⎕←⍵}
   f 23     
23
6
   f 27648     
27648
2688
768
336
54
20
0
RosLuP
источник
4

Japt -R , 9 байт

Ужасно неэффективно - даже не пытайтесь запустить первый контрольный пример!

_ì ×}hN â

Попробуй

_ì ×}hN â     :Implicit input of integer U
      N       :Starting with the array of inputs (i.e., [U])
     h        :Do the following U times, pushing the result to N each time
_             :Take the last element in N and pass it through the following function
 ì            :  Convert to digit array
   ×          :  Reduce by multiplication
    }         :End function
        â     :Deduplicate N
              :Implicitly join with newlines and output
мохнатый
источник
3

Брахилог , 7 байт

ẉ?Ḋ|ẹ×↰

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

объяснение

ẉ          Write the input followed by a linebreak
 ?Ḋ        If the input is a single digit, then it's over
   |       Otherwise
    ẹ      Split the input into a list of digits
     ×     Multiply them together
      ↰    Recursive call with the result of the multiplication as input
Fatalize
источник
Я сам попробовал. Забыли про Ḋ. В остальном у меня было то же самое.
Кроппеб
3

JavaScript (Babel Node) , 46 байт

f=a=>a>9?[a,...f(eval([...a+''].join`*`))]:[a]

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


JavaScript (Babel Node) , 44 байта

Если вход может быть принят как строка

f=a=>a>9?[a,...f(''+eval([...a].join`*`))]:a

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

Луис Фелипе Де Иисус Муньос
источник
@Arnauld Да, я только что отредактировал и добавил неправильный код. Я все еще ищу что-то, используя только строки вместо массивов
Луис Фелипе Де Иисус Муньос
3

PowerShell , 64 59 байт

for($a="$args";9-lt$a){$a;$a="$(($a|% t*y)-join'*'|iex)"}$a

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

Итерационный метод. Принимает ввод и сохраняет его $a, затем входит в forцикл, пока длина $aсоставляет два или более (то есть, это больше, чем 9). Внутри цикла мы выводим $aи затем пересчитываем его, конвертируя его в toCharArra y, joinобъединяя его с *, и затем iex(сокращенно Invoke-Expressionи аналогично eval). Как только мы выходим из цикла, у нас остается одна цифра для печати, поэтому мы $aснова помещаем ее в конвейер.

-5 байт благодаря KGlasier.

AdmBorkBork
источник
Вы можете использовать сравнение 9-lt$aвместо того, $a.length-1чтобы сохранить 5 байтов. И если вы все время не играете на струнных, вы можете отрезать приличный кусок. Проверьте мою попытку PowerShell, если хотите!
KGlasier
3

Древесный уголь , 13 байт

θW⊖Lθ«≔IΠθθ⸿θ

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

θ

Напечатайте ввод в первый раз.

W⊖Lθ«

Повторите, пока длина ввода не 1.

≔IΠθθ

Замените вход цифровым произведением, приведенным к строке.

⸿θ

Напечатайте ввод в новой строке.

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

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

.+~(\`

.
$&$*
^
.+¶$$.(

Попробуйте онлайн! Объяснение:

.+~(\`

Печатайте текущее значение в отдельной строке в начале каждого цикла, пока оно не перестанет изменяться, и не печатайте неизменное значение дважды. Оцените текущее значение в конце каждого цикла.

.
$&$*

Добавьте *после каждой цифры.

^
.+¶$$.(

Завершите преобразование ввода в выражение, которое соответствует цифровому продукту.

Для справки, Retina может сделать это в одну строку (25 байт):

.+"¶"<~[".+¶$.("|'*]'*L`.
Нил
источник
3

C (gcc) , 58 байт

f(n,t){for(;n=printf("%d\n",t=n)>2;)for(;n*=t%10,t/=10;);}

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

Итерационный подход оказывается на 1 байт короче.

f(n,t){
    for(;n=printf("%d\n",t=n)   //print and update current number
            >2;)                //until only one digit is printed
        for(;n*=t%10,t/=10;);   //n*= product of digits of t (step)
}

C (gcc) , 61 59 байт (рекурсивно)

f(n){printf("%d\n",n)>2&&f(p(n));}p(n){n=n?n%10*p(n/10):1;}

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

Кажется, что рекурсия короче, чем итерация для печати и шага ...

attinat
источник