# 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, showing that the single digit doesn't have to be 0:

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
Commented Mar 21, 2019 at 14:31
• You probably should include a few more tests cases that do not end with $0$. Commented Mar 21, 2019 at 14:33
• Came to make this post, found it already existing, gg
– cat
Commented Mar 21, 2019 at 14:55
• is a single digit valid input? Commented Mar 21, 2019 at 18:30
• In the Numberphile video, Matt Parker states that searches have been done to several hundred digits. Commented Mar 21, 2019 at 21:46

# 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? Commented Apr 1, 2019 at 11:15
• Yes, I believe so! Commented Apr 1, 2019 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). Commented Apr 11, 2021 at 19:28

# 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.

# dzaima/APL, 14 11 bytes

∪{×/⍎¨⍕⍵}⍡≡


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!

{$_,{[*] .comb}…10>*}  Try it online! # Python 2, 46 43 bytes -3 thanks to xnor (chained comparison) def f(n):print n;n>9>f(eval('*'.join(n)))  Try it online! • You can do > in place of and. – xnor Commented Mar 22, 2019 at 5:42 • @xnor thanks, easy to forget that will work. Commented Mar 22, 2019 at 7:42 # Wolfram Language (Mathematica), 39 bytes 0Print@#+#>9&&#0@@Times@@@RealDigits@#&  Try it online! -6 bytes from @att • 42 bytes if you don't mind using Echo. Commented Jul 28, 2019 at 22:01 • 39 bytes – att Commented Apr 12, 2021 at 3:56 # Julia 0.7, 36 33 bytes f(n)=n>9?[n;f(prod(digits(n)))]:n  Try it online! Thanks to H.PWiz for -3 bytes. • You can use [n;f(prod(digits(n)))] Commented Apr 20, 2019 at 1:32 • -4 bytes by using an unary operator (for example !n=...) Commented Dec 19, 2022 at 17:13 # V (vim), 29 bytes qqlYp:s/./&*/g C<C-r>=<C-r>"<BS> <esc>|@qq@q  Try it online! • Looks like you can change the l to a h (as in Razetime's answer), to remove the | Commented Apr 9, 2021 at 10:37 # JavaScript (ES6), 45 bytes Returns an array of integers. f=n=>[n,...n>9?f(eval([...n+''].join*)):[]]  Try it online! # PowerShell, 54 bytes for($a=$args;$a-gt9){$a;$a=("$a"|% t*y)-join"*"|iex}$a


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 Commented May 3, 2020 at 14:12 • @RichardDonovan Yes, you're right - thank you for your obsrevation! I don't know how to fix it. Commented May 3, 2020 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. Commented Apr 11, 2021 at 11:52 # 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 Commented Mar 21, 2019 at 15:40 • int.__mul__ is three bytes less than lambda a,b:a*b Commented Mar 21, 2019 at 17:17 • @JonathanAllan Thanks! I knew there had to be something like that Commented Mar 21, 2019 at 19:05 • Change f(reduce(int.__mul__,map(int,n))) to f(eval('*'.join(n))) to save 13 bytes. Commented Mar 21, 2019 at 20:34 • @mypetlion ...I already did that in another post. Commented Mar 21, 2019 at 20:52 # Ruby, 3835 34 bytes f=->n{p(n)>9&&f[eval n.digits*?*]}  Try it online! 1 byte saved by by G B. # 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// Commented Mar 22, 2019 at 8:24
• @Grimy i could save 2 bytes without using -lpF//, updating Commented Mar 22, 2019 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 Commented Mar 21, 2019 at 18:38
• @dzaima I'll look into it, and update the answer when it's solved
– maxb
Commented Mar 22, 2019 at 8:11

# APL(NARS), 19 chars, 38 bytes

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


test:

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


# Charcoal, 13 bytes

θＷ⊖Ｌθ«≔ＩΠθθ⸿θ


Try it online! Link is to verbose version of code. Explanation:

θ


Print the input for the first time.

Ｗ⊖Ｌθ«


Repeat while the length of the input is not 1.

≔ＩΠθθ


Replace the input with its digital product cast to string.

⸿θ


Print the input on a new line.