In this challenge you'll be using be distributing a product over sums and differences of numbers, as explained here.

enter image description here


  Input      |     Output
23(12+42)    | (23*12)+(23*42)
9(62-5)      | (9*62)-(9*5)
4(17+8-14)   | (4*17)+(4*8)-(4*14)
15(-5)       | -(15*5)
2(3)         | (2*3)
8(+18)       | +(8*18)
8(-40+18)    | -(8*40)+(8*18)


The input will be a string of the form n(_), with a single positive unsigned integer n followed by a parenthesized expression _. This expression _ will consist of sums and difference of one of more positive-integer terms separated by + and - signs. The first term may be preceded by a + sign, a - sign, or by no sign.

In the output, the initial number n should be distributed to multiply each of the terms. Each term of a should be left-multiplied by n to produce the parenthesized expression (n*a), and these new terms should be combined with + and - signs in exactly the same way as the original terms were.

Invalid Inputs

These are examples of inputs you don't have to handle.

3(5 plus 3)
6(5 13)


This is , so shortest code in bytes wins.

  • \$\begingroup\$ It occurs to me that regex is really well-suited for this problem. If you're not OK with reg-ex solutions, you could ban it, though people might be working on it already. \$\endgroup\$
    – xnor
    Commented Aug 23, 2015 at 18:38
  • \$\begingroup\$ Are libraries allowed? \$\endgroup\$
    – orlp
    Commented Aug 23, 2015 at 18:47
  • \$\begingroup\$ @orlp To a certain extent which was discussed on meta. \$\endgroup\$
    – Downgoat
    Commented Aug 23, 2015 at 18:51
  • \$\begingroup\$ Interesting case: 8(-40+18) \$\endgroup\$
    – BrainSteel
    Commented Aug 23, 2015 at 19:48

16 Answers 16


JavaScript 65 bytes


This will take the input. Get the + or -, then the digits, then replace it in the correct order.


s=>   // Function with argument "s"
  (q= // Set q to...
    s.split(/[()]/) // Splits on parenthesis, returns array
  [1] // Gets second match or text inside brackets
  .replace(/ // Replaces string 
     (\D?)  // Try to match a non-digit, the +-/* (group 1)
     (\d+)  // Then match one or more digits (group 2)
      // $1 is group 1 and $2 is group 2 q[0] is the text before the parenthesis 


This only works in Firefox and Safari Nightly maybe Edge? because it uses ES6 features. You can run it by:

var t=s=>(q=s.split(/[()]/))[1].replace(/(\D?)(\d+)/g,`$1(${q[0]}*$2)`)

t("5(-6+7+3-8+9)"); // -(5*6)+(5*7)+(5*3)-(5*8)+(5*9)
  • \$\begingroup\$ (.?)(\d+) is broken. This fails on 23(12+42), producing 1(23*2)+(23*42). \$\endgroup\$
    – orlp
    Commented Aug 23, 2015 at 20:45
  • \$\begingroup\$ @orlp I have fixed that \$\endgroup\$
    – user42090
    Commented Aug 23, 2015 at 23:08
  • \$\begingroup\$ This code will only work in Firefox b/c of the arrow function, but that's fine \$\endgroup\$
    – bren
    Commented Aug 24, 2015 at 0:28
  • \$\begingroup\$ @SpeedyNinja It also works in Edge. For Chrome/Opera you need to enable "experimental JavaScript features". \$\endgroup\$ Commented Aug 24, 2015 at 3:38
  • \$\begingroup\$ \D? could be used instead of [+-]? \$\endgroup\$
    – edc65
    Commented Aug 24, 2015 at 7:45

Python 2.7, 110 108 Bytes

import re
print"".join("%s(%s*%s)"%(e[0],p[0][1],e[1])for e in p[1:])

The program takes input from stdin, searches for matches against - ([+-]?)(\d+) regex and creates the output string.
Testing it -

<< 23(12+42)
>> (23*12)+(23*42)

<< 9(62-5)
>> (9*62)-(9*5)

<< 4(17+8-14)
>> (4*17)+(4*8)-(4*14)

<< 15(-5)
>> -(15*5)

<< 2(3)
>> (2*3)

<< 8(+18)
>> +(8*18)

<< 8(-40+18)
>> -(8*40)+(8*18)

Retina, 40 bytes

<empty line>

Each line should go to its own file but you can run the code as one file with the -s flag. E.g.:

>echo -n "8(-40+18)"|retina -s distributing_numbers

The first two lines push the multiplier next to every number in the expected form:


The last two lines remove the unnecessary trailing part:


sed, 105 bytes

Just wanted to see if this can be done with sed.
Maybe a bit old school, but it works.

$ cat distnum.sed

$ cat distnum.txt

$ sed -f distnum.sed distnum.txt

Pip, 28 bytes



                              a is first cmdline arg (implicit)
DQa                           Remove (DeQueue) the closing paren from a
   UnxWa^'(                   Unify n and x with a split on open paren--Python equivalent
                              n is thus the number to be distributed, and x is the
                                addition/subtraction expression
           xR                 In x, replace...
             `\d+`            ... regex matching numbers...
                  '(.n.`*&)`  ... with the replacement pattern (n*&), where n is the
                                appropriate number and & substitutes the complete match
                              Print result (implicit)

Pip's Pattern objects mostly follow Python regex syntax, but the & replacement pattern is borrowed from sed.

Read more about Pip at the Github repository


rs, 77 bytes


Live demo and all test cases.

This is the first time rs's macros have actually been used!


REGXY, 45 bytes

Uses REGXY, a regex substitution based language.

  • \$\begingroup\$ How does the // work? I suppose it loops to the top until the string changes but I can't find in the esolang page why. \$\endgroup\$
    – randomra
    Commented Sep 6, 2015 at 8:35
  • \$\begingroup\$ It's a bit of a cheeky abuse of the vagueness in the language spec, but I've explained it here: codegolf.stackexchange.com/questions/52946/… \$\endgroup\$
    – Jarmex
    Commented Sep 6, 2015 at 19:18
  • 1
    \$\begingroup\$ I still don't get why doesn't the // create an infinite loop as nothing will always match so we always jump back to the first line. \$\endgroup\$
    – randomra
    Commented Sep 6, 2015 at 21:29
  • \$\begingroup\$ Y'know what? I actually have no idea why. You're absolutely right, thinking about it now it makes no logical sense, but it definitely compiles and runs in the provided interpreter. Even looking at the compiled Perl it generates confuses me, because it looks even clearer that it should be an infinite loop: pastebin.com/9q7M0tpZ \$\endgroup\$
    – Jarmex
    Commented Sep 6, 2015 at 22:09

Perl, 36 bytes

35 bytes code + 1 byte command line



echo "4(17+8-14)" | perl -p entry.pl

Pyth, 39 38 bytes

A terrible regex solution:

  • \$\begingroup\$ I can't seem to get this to run in the online interpreter. \$\endgroup\$
    – BrainSteel
    Commented Aug 23, 2015 at 19:41
  • \$\begingroup\$ @BrainSteel It works in the offline interpreter, it seems to be a problem with heroku. \$\endgroup\$
    – orlp
    Commented Aug 23, 2015 at 20:18
  • \$\begingroup\$ @orlp It's not a problem with heroku. Dynamic imports are disabled in safe mode, to reduce the likelihood of a hack, and the re module does a dynamic import. So re can't be used in safe mode, including online. \$\endgroup\$
    – isaacg
    Commented Aug 24, 2015 at 19:51

Ruby, 94 bytes


CJam, 50 bytes


Try it online

CJam does not have regex support, or anything beyond string searching and splitting that is very convenient for parsing expressions. So there's some labor involved here.


l__   Get input and push 2 copies for splitting.
'(#   Find index of '(.
_     Copy index, will be used twice.
@<    Get one copy of input to top, and slice to get first multiplier.
'*+   Append '* to first multiplier.
@@    Get another copy of input and '( index to top.
)>    Increment and slice to get everything after '(.
);    Remove trailing ').
'+/   Split at '+.
'-f/  Split each part at '-.
\     Swap first multiplier to top.
ff{   Apply block to nested list of second multipliers.
  1$    Copy term. Will use this copy as condition to skip empty second multipliers
        that result from unary + or -.
  '(    Opening parentheses.
  @@    Get first and second multiplier to top.
  ++    Concatenate it all.
  ')+   Concatenate closing parentheses.
  L     Push empty string for case where term is skipped.
  ?     Ternary if to pick term or empty string.
}     End of loop over list of second multipliers.
'-f*  Join sub-lists with '-.
'+*   Join list with '+.

gawk - 60 58


Phew... haven't worked with regexp in quite a while.


Perl 5, 70 60 55 44 Bytes + 1 penalty

A perl solution that only uses split and 1 regular expression.
Also calculates the longer inputs.



$ echo "8(9-10+11-12+13-14)"|perl -p distnums.pl   

A version that takes a parameter


A version that only uses regular expressions.


This one works via a capture group within a positive lookahead and lazy matching. Probably would have used a positive lookbehind if Perl 5 supported it, but alas. Took me a while to figure out that this kinda thing is possible with regex.

  • 1
    \$\begingroup\$ Hey Luk, You might be able to save some chars using -p command line option (I think this is +1 char vs 9 for ,<> and ;print) as split will work on $_ by default (which will be whatever is in <>) and print is included in the loop too! Hope that helps! \$\endgroup\$ Commented Sep 2, 2015 at 16:32
  • 1
    \$\begingroup\$ Thanks! It helped. The -p option simply didn't cross my mind. Probably since it's something that's rarely used outside a golfing context. Why do you think it's +1 char? This challenge doesn't mention anything about a penalties for using switches. \$\endgroup\$
    – LukStorms
    Commented Sep 2, 2015 at 19:09
  • \$\begingroup\$ I can't find the post now, but this meta post mentions scoring for Perl's flags. \$\endgroup\$ Commented Sep 2, 2015 at 19:18
  • 1
    \$\begingroup\$ My bad, looks like I came up and posted a very similar solution to you, which is effectively just a slightly more golfed version of yours! Basically you don't even need to capture the [+-] because you leave them intact in the substitution anyway: codegolf.stackexchange.com/a/57117/26977 \$\endgroup\$
    – Jarmex
    Commented Sep 6, 2015 at 19:22
  • \$\begingroup\$ That's cool. Because of you, Perl beats even the Pyth/Cjam solutions in this challenge. I shouldn't have cared about the invalid inputs anyway after that split removed the brackets. \$\endgroup\$
    – LukStorms
    Commented Sep 6, 2015 at 20:11

Retina, 50 51 43 bytes

I think this may be my first Retina program. If not, it's my first Retina program that's this complex (not that complex, really.) Each line goes in its own file.


I didn't actually test this with Retina, I tested it using a regex-replace tester multiple times, but it should work.

Description for first example:

Since there are an even number of files, Retina uses replace mode. The first replace (first two files) removes a number to be distributed and adds that distribution pair (23*12) to the end, giving 23(+42)(23*12). +` at the start tells Retina to repeatedly replace until the pattern doesn't match, and since this is matched again, the pattern replaces this with 23()(23*12)+(23*42). This doesn't match anymore, so the next 2 files are used for the next replace. This time, it merely removes the 23(). This works nicely: since products are appended to the end, I don't have to do anything weird if a number doesn't have a sign, since the only one that can be without a sign is the first number.

EDIT: $' in replacement represents the rest of the string after the match, so I can removing the trailing (.*)s.


k, 98 bytes

Not very golfed.

{,/(*x){(s#y),("*"/:(x;(s:(*y)in"+-")_y))/:$"()"}/:1_x@:&~~#:'x:((0,&~x in .Q.n)_x){x_'x?'y}/"()"}

Split on non-digit, remove parens, remove empty strings, then holding x constant as the first string, combine with * with each remaining string y, parenthesize, and move sign to the beginning if present; flatten output into a single string.


Pip, 23 bytes


Attempt This Online!


   a                    ; Command-line argument
    ^'(                 ; Split on open parenthesis
 DQ                     ; Get the last element of that list
H                       ; Take all but the last character
                        ; This gives us the expression inside the parentheses
       R:               ; Replace
         +XD            ; each regex match of a run of digits
                        ; with:
            '(          ;  Open parenthesis
              .         ;  concatenated to
               +a       ;  Convert a to number (gets the part before the open paren)
                 .      ;  concatenated to
                  `*&)` ;  Replacement pattern: * followed by match followed by )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.