Skip to content

Instantly share code, notes, and snippets.

@alterakey
Last active December 28, 2015 12:08
Show Gist options
  • Save alterakey/7498030 to your computer and use it in GitHub Desktop.
Save alterakey/7498030 to your computer and use it in GitHub Desktop.
Experimental solver for that challenge
# Experimental solver for that challenge
import sys
import re
import itertools
numbers = [1,1,5,8]
operators = ['+', '-', '*', '//']
class InversePolandEquationSolver(object):
def __init__(self, eq):
self.eq = eq
def solve(self):
return self.traverse(num=int, eq=eval)
def format(self):
return re.sub(r'^\(|\)$', '', self.traverse(num=None, eq=lambda x: '(%s)' % x))
def traverse(self, num=None, eq=None):
if num is None: num = lambda x: x
if eq is None: eq = lambda x: x
s = []
for t in self.eq:
if t in operators:
s.append(eq('%s%s%s' % (num(s.pop()), t, num(s.pop()))))
else:
s.append(t)
if len(s) != 1:
raise ValueError('invalid expression')
else:
return num(s[0])
def equations(operators, numbers):
def sanity_check(eq):
return not ( \
eq[-1] not in operators or \
eq[0] in operators or \
eq[1] in operators \
)
for i in range(1, len(numbers)):
for ops in itertools.product(operators, repeat=i):
for eq in itertools.ifilter(sanity_check, itertools.permutations(itertools.chain(numbers, ops))):
yield eq
def solutions(eqs):
for eq in eqs:
try:
solver = InversePolandEquationSolver(eq)
if solver.solve() == 10:
yield eq
except (ValueError, IndexError, ZeroDivisionError), e:
pass
if __name__ == '__main__':
for eq in set(solutions(equations(operators, numbers))):
print InversePolandEquationSolver(eq).format()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment