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))
def find_op(values, answer):
for ordered_values in permutations(values):
for operations in product(ops, repeat=len(values)-1):
result, formula = calc_result(ordered_values, operations)
if result == answer:
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))
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)
In [4]:
print "17 = {}".format(find_op([6, 6, 5, 2], 17))
In [7]:
print "0 = {}".format(find_op([1, 5, 2, 3], 0.7))
In [ ]: