http://wordplay.blogs.nytimes.com/2015/09/07/24/

The numbers are: 1 3 4 6 ; find 24 The numbers are: 1 1 5 8 ; find 10

Operations: + – × /

``````

In [1]:

from operator import mul, add, sub, truediv
from itertools import product, permutations

ops = [
[ mul, "{a} x {b}" ],
[ add, "{a} + {b}" ],
[ sub, "{a} - {b}" ],
[ lambda a, b: sub(b, a), "{b} - {a}" ],
[ truediv, "{a} / {b}" ],
[ lambda a, b: truediv(b, a), "{b} / {a}" ],
]

# Implement search for all possible combinations with an operand stack (starting with input values in some order)
# and an operator stack. Apply the operators from the stack to the last two values, pushing on the result, until
# there is just one value remaing

def calc_result(values, ops):
values = list(values)
ops = list(ops)
top_str = str(values[-1])
while len(values) > 1:
a = values.pop()
b = values.pop()
op = ops.pop()
try:
r = op[0](a, b)
top_str = "({})".format(op[1].format(a=top_str, b=str(b)))
values.append(r)
except ZeroDivisionError:
return None, ""
return values[0], top_str

# Example use: print "10 = {}".format(find_op([1, 1, 5, 8], 10))
for ordered_values in permutations(values):
for operations in product(ops, repeat=len(values)-1):
result, formula = calc_result(ordered_values, operations)
return formula
if result and abs(result - answer) < .001:
return "~ {}".format(formula)
return False

``````
``````

In [2]:

print "10 = {}".format(find_op([1, 1, 5, 8], 10))
print "24 = {}".format(find_op([1, 3, 4, 6], 10))

``````
``````

10 = (8 / (1 - (1 / 5)))
24 = (((4 + 1) x 6) / 3)

``````
``````

In [3]:

values = [1, 3, 4, 6]
for result in range(1,50):
eq = find_op(values, result)
if eq:
print "{} = {}".format(result, eq)
else:
print "{}: none".format(result)

``````
``````

1 = (((4 - 6) + 3) x 1)
2 = (((4 / 6) x 3) x 1)
3 = (((4 / 6) x 3) + 1)
4 = (((6 - 4) + 3) - 1)
5 = (((6 - 4) + 3) x 1)
6 = (((6 - 4) x 3) x 1)
7 = (((6 + 4) - 3) x 1)
8 = (((6 x 4) / 3) x 1)
9 = (((6 x 4) / 3) + 1)
10 = (((4 + 1) x 6) / 3)
11 = (((6 - 3) x 4) - 1)
12 = (((6 + 4) + 3) - 1)
13 = (((6 + 4) + 3) x 1)
14 = (((6 + 4) + 3) + 1)
15 = (((6 x 3) - 4) + 1)
16 = (((6 - 3) + 1) x 4)
17 = (((4 x 3) + 6) - 1)
18 = (((4 x 3) + 6) x 1)
19 = (((4 x 3) + 6) + 1)
20 = (((6 x 4) - 3) - 1)
21 = (((6 x 4) - 3) x 1)
22 = (((6 x 4) - 3) + 1)
23 = (((6 x 3) + 4) + 1)
24 = (6 / (1 - (3 / 4)))
25 = (((6 + 1) x 4) - 3)
26 = (((6 x 4) + 3) - 1)
27 = (((6 x 4) + 3) x 1)
28 = (((6 x 4) + 3) + 1)
29 = (((6 + 4) x 3) - 1)
30 = (((6 + 4) x 3) x 1)
31 = (((6 + 4) x 3) + 1)
32 = (((6 + 3) - 1) x 4)
33 = (((6 + 4) + 1) x 3)
34: none
35 = (((6 + 3) x 4) - 1)
36 = (((6 + 3) x 4) x 1)
37 = (((6 + 3) x 4) + 1)
38: none
39: none
40 = (((6 + 3) + 1) x 4)
41 = (((4 + 3) x 6) - 1)
42 = (((4 + 3) x 6) x 1)
43 = (((4 + 3) x 6) + 1)
44: none
45: none
46: none
47: none
48 = (((3 - 1) x 6) x 4)
49: none

``````
``````

In [4]:

print "17 = {}".format(find_op([6, 6, 5, 2], 17))

``````
``````

17 = (((5 / 6) + 2) x 6)

``````
``````

In [7]:

print "0 = {}".format(find_op([1, 5, 2, 3], 0.7))

``````
``````

0 = (1 - ((3 / 2) / 5))

``````
``````

In [ ]:

``````