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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment