# Product of digit runs

We seem to quite like digit runs lately, so here's a fairly simple challenge.

Given a positive integer, split it into it's digit runs, and return the product.

For example:

11122333 would become 111, 22, 333, the product of which is 813186

Input may be taken as an integer, string, or list/array of digits/characters. Your entry must work for any number within it's representable range. I have tested this for 32-bit integers (2^32-1 max value) and the largest possible result I have found is 1099999989 from 1199999999, which is also within the 32-bit integer range. I have yet to find a number who's output is larger than the input.

For the purposes of this challenge, runs of length 1 are not counted.

If there is only 1 run, return the run. If there are no runs, do anything (undefined behaviour)

Standard I/O rules apply, output can be given as an integer or string.

## Testcases

11122333 -> 813186
1112333 -> 36963
1122855098 -> 13310
98776543 -> 77
1000000 -> 0
123456789 -> undefined
1 -> undefined
99445662 -> 287496
1199999999 -> 1099999989
999999999 -> 999999999


## Scoring

This is so fewest bytes in each language wins!

• "For the purposes of this challenge, runs of length 1 are not counted." This seems completely arbitrary. Commented Jul 11, 2017 at 11:57
• @Mayube Adding arbitrary constraints to make a trivial challenge barely less trivial does not seem like a desirable thing to do to me. Commented Jul 11, 2017 at 12:16
• Why are no runs undefined? I'm not really complaining, I don't think it matters much, but the product of the empty set is 1 in pretty much any definition of product. Commented Jul 11, 2017 at 13:20
• @WheatWizard I prefer to leave "invalid" inputs as either undefined, or remove them completely, I like undefined behaviour for cases like this as it sometimes allows answers to have a lot more flexibility. (Although admittedly perhaps not so much in this particular case) Commented Jul 11, 2017 at 13:23
• Proof that the output never exceeds the input: it suffices to show that if two positive integers A and B are concatenated to form the integer C, then A*B<C. But if B has d digits, then B<10^d, and so C = A*10^d + B ≥ A*10^d > A*B. Commented Jul 11, 2017 at 18:26

Since no one has done Haskell yet here's my take on it. Takes a string as input (of course).

import Data.List


Try it online!

This code almost looks as if it is not golfed, but I cannot find anyway to make it shorter.

• Your code fails on the test case f "1". Expected output is undefined Commented Jul 11, 2017 at 13:38
• @maple_shaft undefined does not mean they literally want undefined as the output, only that the behavior of the program is undefined. 1 is valid output for "1". Commented Jul 11, 2017 at 13:39
• You can check the length condition in the pattern match, like this: x@(_:_:_)<-, and the numeric type of product is enough for the defaulting rule to apply, so you don't need the type annotation. Commented Jul 11, 2017 at 14:20

# Japt, 10 8 bytes

Takes input as a string, outputs an integer or 1 for "undefined".

ò¦ fa_Ã×


Test it

• 2 bytes saved thanks to ETH
• Does this multiply by 10 or something? Commented Jul 11, 2017 at 12:15
• Incorrect output for 1112333, outputs 73926 when it should output 36963 Commented Jul 11, 2017 at 12:16
• @Mayube: Fixed now. Commented Jul 11, 2017 at 12:25
• @EriktheOutgolfer; I'd missed the rule about ignoring runs of length 1. Commented Jul 11, 2017 at 12:26
• I found a couple ways of dealing with that rule that only amount to 8 bytes: ò¦ fa_Ã× or ò¦ f>9 × Commented Jul 11, 2017 at 12:45

# 05AB1E, 6 5 bytes

-1 byte thanks to Erik the Outgolfer

γ9ÝKP


Try it online!

If we don't need to ignore runs of length one, 2 bytes:

γP


Try it online!

• Save a byte by using 9Ý instead of žhS. Commented Jul 11, 2017 at 12:22
• @EriktheOutgolfer Ah! I knew there was a way to do it in 2 bytes.
– Okx
Commented Jul 11, 2017 at 12:24

# JavaScript (ES6), 464538 35 bytes

Takes input as a string, outputs an integer or throws an error for "undefined".

s=>eval(s.match(/(.)\1+/g).join*)

• 7 bytes saved thanks to Herman.
• 3 bytes saved thanks to Craig.

## Try it

o.innerText=(f=
s=>eval(s.match(/(.)\1+/g).join*)
)(i.value="11122333");oninput=_=>o.innerText=f(i.value)
<input id=i><pre id=o>

• -9 bytes: s=>s.replace(/(.)\1+/g,m=>n*=m,n=1)&&n (I haven't tested it yet) Commented Jul 11, 2017 at 12:44
• Seems to do the job, thanks, @HermanLauenstein :) Was playing around to see if I could get it shorter using + instead of * but hadn't got there yet. Commented Jul 11, 2017 at 12:47
• Could you use eval to save a few bytes? s=>eval(s.match(/(.)\1+/g).join*) - throws an error if no runs Commented Jul 11, 2017 at 12:57
• Nice one, @CraigAyre. I was stupidly trying to see if I could save bytes by passing the replace through eval! Given the state of my golfing the past couple of days, it's a very good thing I have a holiday coming up tomorrow! Commented Jul 11, 2017 at 13:02

# Jelly, 7 bytes

ŒgḊÐfḌP


Try it online!

-1 thanks to Leaky Nun.

• 7 bytes? Commented Jul 11, 2017 at 12:35
• @LeakyNun Ooh clever trick... Commented Jul 11, 2017 at 12:38

# Perl 5, 25 bytes

24 bytes + -p flag.

s/(.)\1+/$.*=$&/eg;$_=$.


Try it online!

Quite straight forward: (.)\1+ matches the runs of more than one digit, and $.*=$& uses $. as accumulator for the multiplications (because its initial value is 1 and not 0). Finally, $_ is set to $. and implicitly printed thanks to -p flag. # Perl 6, 21 bytes {[*] .comb(/(.)$0+/)}


Test it

This returns 1 if there is no “digit runs” as that is the base case for multiplication.

The only change to allow one digit runs is to replace $0+ with $0* in the regular expression.

## Expanded:

{            # bare block lambda with implicit parameter ｢$_｣ [*] # reduce the following using &infix:<*> .comb( # pull out substrings that match the following # (implicit method call on ｢$_｣)

/
(.)  # any digit (character)
$0+ # at least one more of that digit / ) }  # Retina, 47 bytes (.)\1+$*_
Td
{(?<=^(_+) _*)_
$1 }^_+ _ _ _  This is slow on the larger test cases. Try it online! ### Explanation (.)\1+$*_


First, replace each run of 2 or more of the same digit with that many _s, followed by a space for separation.

Td


Then remove all remaining digits.

{(?<=^(_+) _*)_
$1 }^_+ _ _  Next, run these two stages in a loop. The first replaces every _ in the second run with the entire first run, effectively multiplying them. The second stage deletes the first run. _  Finally, output the number _s. • You can get this to 42 bytes by using the multiplication stage from Retinas wiki. – ovs Commented Jul 11, 2017 at 17:15 # C (gcc), 93 89 bytes There must be some more golfing to be done here... z,r;f(char*d){for(z=0;r=*d++;z=r/10?z?z*r:r:z)for(r-=48;r%10==*d-48;r=r*10+*d++-48);d=z;}  Try it online! # Mathematica, 61 bytes Times@@FromDigits/@Select[Split@IntegerDigits@#,Length@#>1&]&  # Python 2, 95 79 bytes -2 thanks to @LeakyNum l='0' p=1 for c in input()+' ':a=c in l;p*=int(l)**(len(l)>1>a);l=l*a+c print p  Try it online! • [1,int(l)][len(l)>1] is equivalent to int(l)**(len(l)>1) Commented Jul 11, 2017 at 12:41 • Would l='' instead of l='0' work? Commented Jul 11, 2017 at 12:42 • no, the int(l) would throw an error if the string was empty Commented Jul 11, 2017 at 12:43 # Python 2, 69 bytes lambda n:eval('*'.join(zip(*re.findall(r'((.)\2+)',n))[0])) import re  Try it online! # PHP, 62 bytes prints 1 if no run is found preg_match_all('#(.)\1+#',$argn,$t);echo array_product($t[0]);


Try it online!

# CJam, 18 Bytes

qe{0=1>},{:*i}%:*


Try it Online

q           e# read string - '1112333'
e          e# convert string to RLE - [[3,'1'],[1,'2'],[3,'3']]
{0=1>},     e# filter out runs of length one - [[3,'1'],[3,'3']]
{:*i}%      e# convert sub-arrays to runs - [111,333]
:*          e# multiply array elements - 36963


# Ruby, 41 bytes

p eval gets.scan(/(.)\1+/).map(&:join)*?*


Takes input from stdin, scans it for runs of length > 1, joins them on "*", evaluates and prints.

# Factor, 151 bytes

[ { } { } ] dip
[ 48 - 2dup swap in? [ suffix ] [ [ suffix ] dip 1array ] if ] each
suffix rest [ 0 swap [ swap 10 * + ] each ] map product


Getting a better grip on this language! Still don't think I'm using enough combinators...