Question

You are given three things

1) An array of 'n' positive and negative integers. 2) A number 'x'. 3) Operators : '+', '-', '%', '/'

Form an expression with the array such that when you evaluate it, the result becomes 'x'.

For example, consider the array [5,3,-1,6,2,3] and x=2, one possible solution would be

5 / 3 + (-1) + 6 / 2 - 1

Assume the result of 5 / 3 is 1(Always the integer division).

I have one more complex variant of this.

In the complex variant of this problem, assume that BODMASS rule don't apply. So, at any point of time you traversed through elements 'm' and you have the intermediate result 'y'. You can apply any of the operators to the 'y' and a[m + 1].

For example, in the variant 1,

5 + 3 - 2 / 2 = 7 ( 2 / 2 evaluated first, so 5 + 3 - 1)

in the variant 2,

5 + 3 - 2 / 2 = 3 (5 + 3 = 8. The array reduced to 8 - 2 / 2. Now, 8 -2 = 6. And array reduced to 6 / 2 which evaluate to 3).

Algo/Math/DS experts?

Is this a NP hard?

Was it helpful?

Solution

There are 4 operators, so you have 4^(n-1) possible values for a set of n terms. You can construct a graph of the search space where each path represents a set of operator values and the end point is the result of the calculation.

Of all those end points, only those which give the correct answer will end at the correct end point.

Note, however, that if you start with the end point, you can traverse backward; only if you have a valid set of operators will you end on the first value.

So traverse it from both ends, and the two calculations will meet in the middle. This is a much smaller space, of 4^(n/2) = 2^n from each direction. To match the two sets of answers you will need to sort the lists you get in the middle, although you may prefer to do this at every step to permit you to prevent duplicate paths being followed. At this point it looks much like a maze traversal.

One known NP-complete problem is that of Boolean satisfiability, which is "the problem of determining if the variables of a given Boolean formula can be assigned in such a way as to make the formula evaluate to TRUE". I suspect that since the search space is demonstrably larger than that of a the boolean satisfiability problem, and that since a solution would also determine that a formula was satisfiable (and is thus at least as hard as solving the satisfiability), then the problem should be NP-complete.

In the maze sense, partial solutions whose values diverge from zero would be less likely to be the correct solution, and given an initial sweep of the parameters it should be clear what limits there are to size (i.e. all multiplies), which is not the case in the boolean problem.

Edit: To clarify the tree I mentioned at the beginning. Suppose our list is

 1 ? 2 ? 5 = X

Then the graph is something like this:

 r1 -->  r2  ---> r3 (X)

 1  +2    3  +5    8
             -5   -2
             *5   15
             /5    0

    -2   -1  +5    4
             -5   -6
             *5   -5
             /5    0

    *2    2  +5    7
             -5   -3
             *5   10
             /5    0

    /2    0  +5    5
             -5   -5
             *5    0
             /5    0

As you can see, if X is -5, then it could be 1 -2 *5 or 1 /2 -5. Working backwards, from -5:

-5 +5    0
   -5  -10
   *5  -25
   /5   -1

So if we had stepped from each end, we'd be at the middle column and the only common values would be -1 and 0, yielding the two paths with 8 calculations rather than the 16 going in one direction only.

A point that this raises, which I had missed, is that the integer division is not a 1:1 mapping, so stepping backward is ambiguous; -4/5 -> 0, -3/5 -> 0 etc up to 4/5 -> 0. 0 is the worst case because it is approached from either side of 0, but even 20/10 to 29/10 all map to the same value, 2. This is quite a hurdle; it raises the number of possible nodes when stepping backwards by the size of the number being divided, so for a 5, there are 3+5 = 8 possible states rather than 4.

OTHER TIPS

Here's an attempt at a recursive solution (for the simple version):

Gen {'x'} = {'x'}
Gen {'x', 'y'} = {'x + y', 'x - y', 'y - x', 'x / y', 'y / x', 'x % y', 'y % x'}
S0 = {a[0]}
Gen S(i + 1) = {j ∈ S(i) | Gen {j, a[i + 1]}}

Final answer would be: ∃ j ∈ S(n). x = [[ j ]]

That is, we incrementally build all the possible values (as expressions) and then finally evaluate all of them to see if one of them can produce x (evaluation can be done incrementally as well).

However, here I'm assuming that the values from a are used linearly when building the expression. Which I realized is not the case with your problem...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top