# Multiplicative persistence

## Multiplicative Persistence

1. Multiply all the digits in a number
2. Repeat until you have a single digit left

As explained by Numberphile:

### Example

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

This is the current record, by the way: the smallest number with the largest number of steps.

## Golf

A program that takes any whole number as input and then outputs the result of each step, starting with the input itself, until we hit a single digit. For 277777788888899 the output should be

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

(Counting the number of steps is left as an exercise to the user).

### More Examples

From A003001:

25
10
0

From A003001 as well:

68889
27648
2688
768
336
54
20
0

From the Numberphile video:

327
42
8

So there has been a question about Additive Persistence, but this is Multiplicative Persistence. Also, that question asks for the number of steps as output, while I'm interested in seeing the intermediate results.

• Bonus: find a new record: smallest number with the largest number of steps. Caveat: conjecture has it that 11 is the largest possible. – SQB Mar 21 '19 at 14:31
• You probably should include a few more tests cases that do not end with $0$. – Arnauld Mar 21 '19 at 14:33
• Came to make this post, found it already existing, gg – cat Mar 21 '19 at 14:55
• is a single digit valid input? – dzaima Mar 21 '19 at 18:30
• In the Numberphile video, Matt Parker states that searches have been done to several hundred digits. – HardScale Mar 21 '19 at 21:46

# Jelly, 4 bytes

DP$Ƭ Try it online! ### Explanation D | convert to decimal digits P | take the product$  | previous two links as a monad
Ƭ | loop until no change, collecting all intermediate results

As a bonus, here's a TIO which will find the numbers with the largest number of steps for a given range of numbers of digits. It scales well even on TIO.

# TI-BASIC (TI-84), 3032 31 bytes

-1 byte thanks to @SolomonUcko!

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

Input is in Ans.
Output is displayed as the challenge requests. The trailing Ans is needed to print the last step.

I will admit, I did not think of this formula myself, rather I found it here and modified it to better fit the challenge.

EDIT: Upon rereading the challenge, I realized that the program must terminate if the product is one digit. Hence, 2 bytes were to be added to account for this.

Example:

24456756
24456756
prgmCDGF8
24456756
201600
0
11112
11112
prgmCDGF8
11112
2

Explanation:

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

Visual Model:
Ans starts off as 125673.
This model only covers the logic behind multiplying the digits; everything else is easier to understand.

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)

Notes:

TI-BASIC is a tokenized language. Character count does not equal byte count.

10^( is this one-byte token.

This program will not provide the correct sequence of products with integers greater than 14 digits long due to the limitations of decimal precision on the TI calculators.

• Can you save a byte by moving 10^( outside seq( and omitting the closing parenthesis? – Solomon Ucko Apr 1 '19 at 11:15
• Yes, I believe so! – absoluteAquarian Apr 1 '19 at 13:08

# K (ngn/k), 9 bytes

{*/.'$x}\ Try it online! { }\ keep applying the function in curly braces until the sequence converges$x format the argument as a string (list of characters)

.' evaluate each (other dialects of k require a colon, .:')

*/ times over, i.e. product

# R, 59 57 bytes

n=scan();while(print(n)>9)n=prod(n%/%10^(0:log10(n))%%10)

Try it online!

Since print invisibly returns its input, we can use print(n) inside the while loop to simulate a do-while loop. This is inspired by one of my tips for golfing in R.

The header helps prevent large numbers from being printed in scientific notation.

• 55 bytes (with possibly room for improvement, if you can find a shorter way of converting to character). – Robin Ryder Apr 11 at 19:28

∪{×/⍎¨⍕⍵}⍡≡

Try it online!

# 05AB1E, 7 4 bytes

Δ=SP

Explanation:

Δ     # Loop until the number no longer changes:
=    #  Print the number with trailing newline (without popping the number itself)
#  (which will be the implicit input in the first iteration)
SP  #  Convert the number to a list of digits, and calculate its product

# Wolfram Language (Mathematica), 47 bytes

Most@FixedPointList[Times@@IntegerDigits@#&,#]&

Try it online!

Try it online!

Iterative method that first writes the input argument, then converts it into a string and pipes it into a character array. This array is joined by a single asterisks, and executed as a command with the invoke expression alias. Since this writes Starting number down to the last number greater than 0, (20, in the given test scenario), I add a final $a to the end to output. # PowerShell, 51 bytes filter f{$_
if($_-gt9){("$_"|% t*y)-join'*'|iex|f}}

Try it online!

# C# (Visual C# Interactive Compiler), 7974 68 bytes

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

I try to stay away from recursion in C# due to how long the method declaration is, but in this case it saves compared to a loop.

Try it online!

<?=$n=$argn;while($n>9)echo" ",$n=array_product(str_split($n)); Iterative version, call with php -nF input from STDIN. Try it online! # PHP, 72 71 bytes function h($n){echo"$n ",($n=array_product(str_split($n)))>9?h($n):$n;} Try it online! Recursive version, as function. Input: 277777788888899 277777788888899 4996238671872 438939648 4478976 338688 27648 2688 768 336 54 20 0 Input: 23 23 6 # J, 16 bytes ([:*/,.&.":)^:a: Try it online! • This doesn’t work for very large numbers as it then switches into floating point mode, even putting x on the end doesn’t help ([:*/,.&.":)^:a:3777788889999977777777777x 3.77779e24 3.4448e21 0 0 – Richard Donovan May 3 '20 at 14:12 • @RichardDonovan Yes, you're right - thank you for your obsrevation! I don't know how to fix it. – Galen Ivanov May 3 '20 at 18:12 • @GalenIvanov ([:*&x:/,.&.":)^:a: fixes it (you also need the x on the input), though I think your existing answer is still legal. – Jonah Apr 11 at 11:52 • @Jonah Thank you! – Galen Ivanov Apr 11 at 14:01 # Python 2, 6162 59 bytes def f(n):print n;n>9and f(reduce(int.__mul__,map(int,n))) Try it online! -3 bytes, thanks to Jonathan Allan • Doesn't work for inputs that don't end with a 0 on their last iteration, for example 23 – Gymhgy Mar 21 '19 at 15:40 • int.__mul__ is three bytes less than lambda a,b:a*b – Jonathan Allan Mar 21 '19 at 17:17 • @JonathanAllan Thanks! I knew there had to be something like that – TFeld Mar 21 '19 at 19:05 • Change f(reduce(int.__mul__,map(int,n))) to f(eval('*'.join(n))) to save 13 bytes. – mypetlion Mar 21 '19 at 20:34 • @mypetlion ...I already did that in another post. – Jonathan Allan Mar 21 '19 at 20:52 # perl 5 (-n-M5.01), 3230 25 bytes say$_=eval;s/\B/*/g&&redo

25 bytes

30 bytes

32 bytes

• You should mention that this uses -lpF// – Grimmy Mar 22 '19 at 8:24
• @Grimy i could save 2 bytes without using -lpF//, updating – Nahuel Fouilleul Mar 22 '19 at 8:42

# MathGolf, 9 10 bytes

h(ôo▒ε*h(→

Try it online!

Now it correctly handles inputs that are single digits. Not perfect, but at least it is correct.

## Explanation

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)
• The output for a single digit input should be one copy of the number - clarified in the comments – dzaima Mar 21 '19 at 18:38
• @dzaima I'll look into it, and update the answer when it's solved – maxb Mar 22 '19 at 8:11

# JavaScript (ES6), 45 bytes

Returns an array of integers.

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

Try it online!

# APL(NARS), 19 chars, 38 bytes

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

test:

f←{⍵≤9:⍵⋄∇×/⍎¨⍕⍵⊣⎕←⍵}
f 23
23
6
f 27648
27648
2688
768
336
54
20
0