views:

643

answers:

4

Write a function that given a string of digits and a target value, prints where to put +'s and *'s between the digits so they combine exactly to the target value. Note there may be more than one answer, it doesn't matter which one you print.

Examples:

"1231231234",11353 -> "12*3+1+23*123*4" 
"3456237490",1185  -> "3*4*56+2+3*7+490" 
"3456237490",9191  -> "no solution"

How to solve this problem? Thank you!

+1  A: 

This can be solved either by backtracking or by dynamic programming.

dirkgently
+8  A: 

If you have an N digit value, there are N-1 possible slots for the + or * operators. So brute force, there are 3^(N-1) possibilities. Testing all of these are inefficient.

BUT

Your examples are all 10 digits. 3^9 = 19683, so brute force is FINE! No need to get any fancier.

So all you need to do is iterate through all 19683 cases, each time building a string for that case, and evaluating the expression. Evaluating the expression is a straightforward task. Iterating is straightforward (just use an incrementing value, you can read the state of the first slot by (i%3), which gives you "no operator" "+" or "*", the state of the second slot is (i/3)%3, the state of the third slot is (i/9)%3 and so on.)

Even with crude parsing code, CPUs are fast.

The brute force option starts becoming ugly after about 20 digits, and you'd have to switch to be more clever.

SPWorley
+1 for estimating the cutover from brute force to cleverness.
RBerteig
+1  A: 

The "cleverer" approach (using dynamic programming) is basically this:

For each substring of the original string, figure out all possible values it can create. (e.g. in your first example "12" can become either 1+2=3 or 1*2=2)

There may be a lot of different combinations, but many of them will be duplicates. (Also, you should ignore all combinations that are greater than the target).

Thus, when you add a "+" or a "*", you can envision it as combining two substrings of the string. (and since you have the possible values for each substring, you can see if such a combination is possible)

These values can be generated similarly: try splitting the substring in all possible ways, and combine the different values in each half of the substring.

The total number of "states", then, is something like |S|^2 * target - for your example case, it's worse than the brute-force method. But if you had a string of length 1000 and a target of say 5000, then the problem would be solvable with dynamic programming.

v3
+1  A: 

Google Code Jam had an extended version of this problem last year (in Round 1C), called Ugly Numbers. You can visit that link and click "Contest Analysis" for some approaches to that problem, when extended to large numbers of digits.

Chris Jester-Young