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

# Retina, 24 bytes

.+~(\

.
$&$*
^
.+¶$$.( Try it online! Explanation: .+~(\ Print the current value on its own line at the start of every loop until it stops changing and don't print the unchanged value twice. Evaluate the current value at the end of each loop. . &* Add a * after each digit. ^ .+¶$$.(

Finish turning the input into an expression that evaluates to the digital product.

Just for the record, Retina can do this in one line (25 bytes):

Try it online!

# Husk, 5 bytes

U¡oΠd

Try it online!

## Explanation

U¡oΠd
¡    iterate infinitely, collecting results of each iteration
o   combination of 2 functions
d get digits
Π  multiply all of them
U     cut at first duplicate value

# R, 59 55 bytes

Edit: -2 bytes thanks to Giuseppe, quickly superseded by -4 bytes (a different way) thanks to Robin Ryder

n=scan();while(print(n)>9)n=prod(utf8ToInt(c(n,""))-48)

Try it online!

A different method to Giuseppe's answer for the same number of bytes, here as a full recursive function instead of the (often-shorter) approach of taking input from the console using scan.

• This (and mine) can be shortened by using 0:log10(x) instead of the nchar thing, I believe. Apr 11, 2021 at 18:36

# POSIX Shell + Utilities, 59 bytes

echo $1 [${#1} = 1 ]||$0$(echo $1|fold -w1|paste -sd*|bc)$ cat cg; echo; wc -c cg
echo $1 [${#1} = 1 ]||$0$(echo $1|fold -w1|paste -sd*|bc) 59 cg$ ./cg 277777788888899
277777788888899
4996238671872
438939648
4478976
338688
27648
2688
768
336
54
20
0
$./cg 25 25 10 0$ ./cg 327
327
42
8
$./cg 68889 68889 27648 2688 768 336 54 20 0 # Go, 87 bytes import."fmt" func f(n int){Println(n) s:=1 if n<10{return} for;n>0;n/=10{s*=n%10} f(s)} Attempt This Online! # 05AB1E, 13 bytes ,[1svy*}Ð,gΘ# Try it online! Explanation: , //Print input [ //Begin infinite loop 1s //Set 1 to the item before the input in the stack v //Loop over the input y* //Add the current character to the stack and multiply } //End loop Ð //Triplicate result , //Print result gΘ //Check if length == 1 # //If so, end Leaving out the two prints can save two bytes while still outputting the result, thanks to implicit output. Without that restriction this would be 11. • Welcome to Code Golf, and nice answer! Dec 1, 2023 at 21:25 # java 8, 105 104 bytes -1 byte thanks to @Benjamin Urquhart, replacing '0' with 48 i->{String s="";for(;(s+=i+"\n")!=""&i>9;){long m=1;for(byte c:(""+i).getBytes())m*=c-48;i=m;}return s;} TIO • -1 byte by replacing '0' with 48 Mar 21, 2019 at 19:41 • With java 10 you could save a few bytes by writing var instead of String and so on. Mar 21, 2019 at 20:48 # ink, 66 bytes =p(n) {n}{n<10:->->} ~temp v=1 -(a)~v=v*n%10 ~n=n/10 {n:->a}->p(v) Try it online! # Explanation =p(n) // entry point - a stitch called p, with one parameter. {n} // print the value of n {n<10:->->} // if n is a single digit, divert to wherever we entered from ~temp v=1 // declate a variable v, where we keep track of the product, and set it to 1 -(a) // a labeled gather - we can jump here later ~v=v*n%10 // multiply v by (n mod 10) - the last digit in n ~n=n/10 // divide n by 10 - removing the last digit {n:->a} // if n is nonzero, go back to a ->p(v) // if we reach this, divert to the top, this time with n set to the value of v Doesn't feel very golfed, but I have no idea how you'd improve it. # Factor, 79 72 bytes : f ( x -- ) [ 10 >base [ 48 - ] map product dup dup . 9 > ] loop drop ; Try it online! # Python 2, 87 bytes b=input() while 1: a=str(b);print a;b=1 if len(a)<2:break for d in list(a):b*=int(d) Try it online! # SNOBOL4 (CSNOBOL4), 100 bytes P =INPUT O OUTPUT =N =P :(S) S P =GT(N,9) 1 :F(END) D N LEN(1) . D REM . N :F(O) P =P * D :(D) END Try it online! A nice round 100 bytes! P =INPUT ;* Store input to P O OUTPUT =N =P :(S) ;* print P and set N to P S P =GT(N,9) 1 :F(END) ;* if N > 9, set P (the digit product) to 1 D N LEN(1) . D REM . N :F(O) ;* take the first digit of N as D and set remaining digits to N ;* if N is an empty string, goto label O P =P * D :(D) ;* calculate the digit product, then return to D END # Racket, 107 bytes (define(f n)(if(> 10 n)(list n)(cons n(f(apply *(map(λ(x)(-(char->integer x)48))(string->list(~v n)))))))) Try it online! # C, 138 115 bytes long atol(char*);main(c,v)char**v;{long z=1,n=atol(v[1]);for(;printf("%ld\n",n),n>9;n=z,z=1)for(;z*=n%10,n/=10;);} Pass the number as a first command line argument. Thanks to attinat for help with saving some bytes. Ungolfed and prettyified: long atol(char *); main(c, v) char **v; { long z = 1,n = atol(v[1]); for(; printf("%ld\n", n), n > 9; n = z, z = 1) for(; z *= n % 10, n /= 10;); } • for can save you quite a few bytes. – att Mar 24, 2019 at 6:14 • Suggest int**v instead of char**v Apr 21, 2019 at 6:37 # Attache, 28 27 bytes {If[_>9,_'$@Prod@List@_,_]}

Try it online!

Oddly enough, the recursive approach, rather than a tacit approach, seems to be shortest. (There is a bug in NestListWhile involving currying, but even with the bugfix it'd be 3 bytes longer.)

## Explanation

{
If[ _ > 9 ,
?? if this is true, return a list
[
?? with the current number
_,
?? followed by this function called on the digital product
...$[ Prod[Digits[_]] ] ], ?? otherwise, return _ _ ] } ## Alternative 32 bytes: NestListWhile<~Prod@List,{_>9}~> # C# (.NET Core), 192 191 180 bytes using C=System.Console;class A{static void Main(string[] a){long i,k;var b=a[0];for(C.WriteLine(b);(k=b.Length)>1;C.WriteLine(b=i.ToString())){i=1;for(int j=0;j<k;)i*=b[j++]-48;}}} Try it online! Pretty much just naive looping. I feel like that's a bit of a silly way to do it but here we are. Had a weird issue early on where the input didn't match the output, because it was overflowing an int, so here we are with longs. I could upgrade it to BigInteger if I needed to, though that would cost a few bytes. I swear I always end up with off by ones when I do loops here, and it annoys me to no end. Ungolfed-ish version: using C=System.Console; class A{ static void Main(string[] a){ long i,k; var b=a[0]; for(C.WriteLine(b);(k=b.Length)>1;C.WriteLine(b=i.ToString())){ i=1; for(int j=0;j<k;)i*=b[j++]-48; } } } # Works for all integers less than int.MAX_VALUE digits long, C# (.NET Core), 204 bytes using C=System.Console;class A{static void Main(string[] a){System.Numerics.BigInteger i;int j,k;var b=a[0];for(C.WriteLine(b);(k=b.Length)>1;C.WriteLine(b=i.ToString())){i=1;for(j=0;j<k;)i*=b[j++]-48;}}} Try it online! • Saved 1 byte - moved C.WriteLine(b) into loop opening as well as iterator Mar 24, 2019 at 4:01 • Saved 11 bytes with assorted rearrangements. Mar 25, 2019 at 15:16 # Pyth, 9 bytes j.u*FsMN Try it here! If we're allowed to output as an array, the j at the start is unnecessary, giving 8 bytes. • You can also omit the N at the end, since Pyth implicitly adds lambda variables at the end of a program if needed. Jul 28, 2019 at 22:42 ## c++, lambda function, 72 bytes [](auto n){while(cout<<n<<endl&&n>9){auto t=n;for(n=1;n*=t%10,t/=10;);}} try it online ## Clojure, 73 bytes #(loop[i %](prn i)(if(> i 9)(recur(apply *(for[c(str i)](-(int c)48)))))) # Scala, 83 bytes def^(n:Long):Long={println(n);if(n>9)^((n+"").map(x=>(x-48).toLong).product)else n} Try it online! # Befunge-98 (FBBI), 43 42 bytes &;1\v>#;:.:9`!#@_; >$$^ ^#::< '*%ap25/a_ Try it online! The first line takes input, prints the values and runs until a value <=9 is reached. The third line computes the product of digits of an integer (26 bytes on its own). # Pip, 9 bytes W9<Pa$*:a

Try it online!

### Explanation

a is command-line argument (implicit)
W          While...
Pa      (print a's value)
9<        ... a is greater than 9, i.e. more than one digit:
\$      Fold
a   (the digits of) a
*     on multiplication
:    and assign back to a

Printing a in the loop header lets us output its value both before the loop and when the loop terminates.

# Factor + math.unicode, 40 bytes

[ [ .s >dec 48 v-n Π dup 9 > ] loop . ]

Try it online!

• [ ... dup 9 > ] loop loop while top of stack is greater than nine
• .s print stack non-destructively
• >dec convert number to string
• 48 v-n convert string to list of digits
• Π product of a list of numbers
• . print the leftover number (which will be the final output)