# Repeated Consecutive Digital Product Sum Convergence

Given a positive integer n (Example: n=1234444999)

• Separate into consecutive digit runs:
• [1, 2, 3, 4444, 999]
• Take the digital product of each run.
• [1, 2, 3, 4*4*4*4, 9*9*9] = [1, 2, 3, 256, 729]
• Sum it...
• 991
• Repeat until this converges to a single number:
• 1234444999
• 991
• 82
• 10
• 1
• Return last number.

# Test Cases

BASE CASES:
0 = 0
...
9 = 9

OTHER CASES:
1234444999                     = 1
222222222222222                = 8
111222333444555666777888999000 = 9
11122233344455566677788899     = 8
1112223334445                  = 6
14536                          = 1
99                             = 9


# Requested Example:

334455553666333
9+16+625+3+216+27
896
8+9+6
23
2+3
**5**


# Winning?

It's , lowest byte-count is the winner.

• Annnnnnnnnnnnnnnnnnnd... this is NOT the sandbox. Crap. Well, not much I can do now, sorry all ._. Jul 11 '17 at 22:19
• It would be good to have test cases where digits of the same kind aren't all in a consecutive chunk.
– xnor
Jul 11 '17 at 22:27
• Can we take input as a list of digits? Some languages can't support integers as high as 11122233344455566677788899. Jul 11 '17 at 22:51
• @ETHproductions you may state the maximum integer input allowed by your language and have your answer be valid if you can explain the bounding. Jul 11 '17 at 22:51
• Will the same digit evet appear in 2 different runs, eg: 33445555666333? Jul 12 '17 at 7:04

# 05AB1E, 76 5 bytes

Thanks to Emigna for saving a byte!

vSγPO


Uses the 05AB1E encoding. Try it online!

• I just now noticed for the first time that your avatar is a doge meme. Jul 11 '17 at 22:44
• @MagicOctopusUrn and you just made me notice that as well... Jul 12 '17 at 19:21
• You could replace gF with v. Jul 13 '17 at 15:54
• @Emigna Oohh of course! Thank you! :) Jul 13 '17 at 17:18

# Jelly, 9 bytes

DŒgP€SµÐL


Try it online

Here's how it works:

D  - input as a list of digits
Œg - group runs of equal elements
P€ - the product of each element
S  - the sum of the list
µ  - syntax stuff to separate the left from the right
ÐL - repeat until we get a result twice, then return that result.

• Why doesn't P automatically vectorize? That seems strange... Jul 13 '17 at 2:21
• No, P automatically vectorizes, so you don't need the €. Jul 13 '17 at 2:24
• No, P doesn't vectorize: tio.run/##y0rNyan8/9/l6KT0gOBDWw9P8Pn//78RKgAA Jul 13 '17 at 2:34
• Oh, I see - Œg is inconsistent when there's only a single group. What's the reasoning behind that? Jul 13 '17 at 2:53
• No clue at all! Jul 13 '17 at 16:52

# Mathematica, 55 42 bytes

#//.i_:>Tr[Times@@@Split@IntegerDigits@i]&


-13 bytes from @JungHwan Min. Thanx!

in case someone wants to use this as a random-digit-generator,
here is the tally of the first 100.000 numbers

{{1, 17320}, {2, 4873}, {3, 10862}, {4, 11358}, {5, 10853}, {6, 9688}, {7, 11464}, {8, 10878}, {9, 12704}}
or if you gamble, don't put your money on 2!

# Japt, 1715 13 bytes

e".+"_¬ò¦ x_×


Test it online! Takes input as a string.

Still not satisfied with this answer...

### Explanation

e".+"_  ¬ ò¦  x_  ×
e".+"Z{Zq ò!= xZ{Zr*1}}

e".+"                     Repeatedly replace all matches of /.+/ (the entire string)
Z{               }   Z with this function:
Zq                   Split Z into chars.
ò!=               Partition at inequality; that is, split into runs of equal items.
xZ{    }      Take the sum of: for each item in Z:
Zr*1         the item reduced by multiplication (i.e. the product).
This procedure is repeated until the same result is yielded twice.
Implicit: output result of last expression

• You can also just take it as an integer and state the maximum allowable input, sorry, I changed my answer after posting it to my default answer for that question. Jul 11 '17 at 22:58
• @MagicOctopusUrn Oh, hey, thanks. That saves two bytes, anyway... Jul 11 '17 at 23:00
• Also, the x_× combined with I'm unsatisfied made me laugh. Thanks ;). Jul 11 '17 at 23:02
• I thought ß might have been the way to go here. I was wrong! (At least at half 5 in the morn', sat on the bus to the airport I was!) Jul 12 '17 at 7:02
• "Still not unsatisfied" ... so ... you're satisfied finally? Jul 12 '17 at 21:38

# Python 3, 96 bytes

from itertools import*
f=lambda n:n*(n<10)or f(sum(int(k)**len([*g])for k,g in groupby(str(n))))


Try it online!

# Brachylog, 8 bytes

Ḋ|ẹḅ×ᵐ+↰


Try it online!

### Explanation

Ḋ          Input = Output = a digit
|         Or
ẹ        Split into a list of digits
ḅ       Group consecutive equal elements together
×ᵐ     Map multiply
+    Sum
↰   Recursive call

• You'd never expect Brachylog to outgolf Jelly here would you? Jul 12 '17 at 9:38
• @EriktheOutgolfer When Brachylog beats Jelly, my first assumption is that the Jelly answer isn't optimal Jul 12 '17 at 9:56
• Mine too, except I tried to do this in Jelly too. The thing is, well, 05AB1E still beats this. :) Jul 12 '17 at 9:59
• Well. it's one byte, and the Jelly answer is by me, yeah, I'd expect Brachylog to beat Jelly. Jul 12 '17 at 21:44

# Pyth, 11 bytes

us^M_MrjGT8


## JavaScript (ES6), 777367 65 bytes

Saved 2 bytes thanks to @CraigAyre

f=s=>s>9?f(''+eval(s.replace(/(.)\1*/g,s=>'+'+[...s].join*))):s


### How?

The input s is transformed into an arithmetic expression with:

s.replace(/(.)\1*/g, s => '+' + [...s].join*)


For instance, 1234444999 becomes +1+2+3+4*4*4*4+9*9*9.

We evaluate this expression and do a recursive call with the result until it's boiled down to a single decimal digit.

### Test cases

f=s=>s>9?f(''+eval(s.replace(/(.)\1*/g,s=>'+'+[...s].join*))):s

console.log(f("1234444999"                    )) // = 1
console.log(f("222222222222222"               )) // = 8
console.log(f("111222333444555666777888999000")) // = 9
console.log(f("11122233344455566677788899"    )) // = 8
console.log(f("1112223334445"                 )) // = 6
console.log(f("14536"                         )) // = 1
console.log(f("99"                            )) // = 9

• Can you save a couple of bytes by comparing against 9?: f=s=>s>9?f(''+eval(s.replace(/(.)\1*/g,s=>'+'+[...s].join*))):s Jul 12 '17 at 9:15
• @CraigAyre Seems like my approach was a bit overcomplicated indeed. Thanks! Jul 12 '17 at 9:33

# PHP, 113 bytes

for(;9<$a=&$argn;$a=$s){$s=0;preg_match_all('#(.)\1*#',$argn,$t);foreach($t[0]as$v)$s+=$v[0]**strlen($v);}echo$a;  Try it online! • Are you full-time PHP developer? Jul 11 '17 at 23:01 • @MagicOctopusUrn No I have experience over few years Jul 11 '17 at 23:05 ## Husk, 8 bytes ωöṁΠgmis  Takes and returns an integer. Try it online! ## Explanation Having a built-in for base 10 digits would be nice... ωöṁΠgmis ω Iterate until a fixed point is found ö the composition of the following four functions: s convert to string, mi convert each digit to integer, g group equal adjacent integers, ṁΠ take product of each group and sum the results.  • ...looks like incorporating a built-in for base 10 digits during the intervening 3 years was worth it, then: now 6 bytes. Nov 6 '20 at 16:35 # CJam, 22 bytes r_,{1/eWf%::i::#:+s}*  Try it online! # Haskell, 10370 69 bytes import Data.List until(<10)$sum.map product.group.map(read.pure).show


Try it online!

• You can shorten that a lot by using until(<10). Also the map(read.pure) can be moved before show, which saves parentheses. Jul 12 '17 at 13:33
• Yup, it is a lot better! Jul 17 '17 at 7:30
• You can use $ instead of the outer parentheses. Jul 17 '17 at 15:38 # K (ngn/k), 17 23 bytes +6 bytes from handling cases where the same digit is present in multiple chunks {+/*/'(&~=':x)_x:10\x}/  Try it online! • {...}/ run a converge reduction over the input • x:10\x convert input to a list of digits, updating x • (&~=':x) identify indices where the value differs from the previous element • (...)_x split the list of digits on those indices • */' take the product of each chunk • +/ add those products together Fails on inputs too large for 64-bit integers. # R, 114 104 bytes n=scan(,'');while(nchar(n)>1){n=el(strsplit(n,''));b=table(n);n=as.character(sum(strtoi(names(b))^b))};n  reads from stdin; returns the answer as a string. Try it online! • You could use paste instead of as.character. The former coerces its input into character type ;-) Jul 11 '17 at 22:52 # MATL, 11 bytes !UY'^sVtnq  Try it at MATL Online Explanation  % Implicitly grab input as a string  % Do...while loop !U % Convert the string to an array of numbers (the digits) Y' % Perform run-length encoding ^ % Raise the digits to the power corresponding to the number of times they % occurred consecutively s % Sum the result V % Convert to a string tn % Duplicate and determine the number of characters in the string q % Subtract one, causes the loop to continue until it's a single digit % Implicit end of do...while loop and display  # Perl 5, 50 bytes 49 bytes of code + -p flag. s/(.)\1*/"+".$&=~s%.%$&*%gr.1/ge while($_=eval)>9


Try it online!

# R, 97 96 bytes

a=scan(,"");while(nchar(a)>1){a=paste(sum(strtoi((b<-rle(el(strsplit(a,""))))$v)^strtoi(b$l)))}a


Slightly different approach than the other answer using R.

This answer makes use of the rle function, which compute[s] the lengths and values of runs of equal values in a vector.

-1 bytes thanks to @Giuseppe !

• ** is equivalent to ^ Jul 12 '17 at 0:52

# Braingolf, 25 bytes

!L1-Mv[RG(d&*)&+!L1-Mv>]R


Will add a TIO link once I get Dennis to pull the latest version, as using greedy operators inside (...) loops is currently broken on TIO

## Explanation

!L1-Mv[RG(d&*)&+!L1-Mv>]R  Implicit input from commandline args
!L1-M                      Push length of input minus 1 to stack2
v                     Switch to stack2
[.........!L1-Mv>]   While length of input > 1..
RG                  Split into digit runs
(d&*)             Product of digits of each item in stack
&+           Sum stack
Implicit output from stack


# Japt, 19 bytes

=ò¦ m¬®×Ãx)<A?U:ßUs


Try it online!

## Explanation:

=ò¦ m¬®×Ãx)<A?U:ßUs
=                    // Implicit U (input) =
ò¦                  //   Split the input into an array of consecutive digit runs
m¬               //   Split each inner array: ["1","22","333"] -> [["1"],["2","2"],["3","3","3"]]
®              //   Map; At each item:
×             //     Get the product of each run
Ã            //   }
x           //   Sum
<A        // <10
?       // If true:
U      //   return U
:     // Else:
ß    //   Run the program again; Pass:
Us  //     U, cast to a string


# Japt-h, 9 bytes

I/O as digit arrays

£=òÎx_×Ãì


Try it

£=òÎx_×Ãì     :Implicit input of digit array
£             :Map
=            :  Reassign to U
ò           :  Partition between elements where
Î          :    The sign of their difference in truthy (not zero)
_        :  After passing each through this function
×       :    Reduce by multiplication
Ã      :  End function
ì     :  Split to digit array
:  Implicit output of last element


# Groovy, 69 68 bytes

f={r->r>9?f((r=~/(.)\1*/)*.tap{}.sum{n->n[1]as int**n[0].size()}):r}


Requires Groovy 3.x.

## Explanation

If the input is single digit, returns it, else recursively calls the function on the next pass of the algorithm.

f={r->r>9?f(...):r}     : Recursively call algorithm if input > 9, else return input
r=~/(.)\1*/)            : Regex capture of each run, e.g. [["444", "4"], ["2", "2"]]
*.tap{}                 : Convert Matcher to List<List<Integer>> so we can call sum()
.sum{...}               : Apply the closure to each List element and sum them
n[1]as int**n[0].size() : <digit>^<run length> from e.g. ["444", "4"]
`