Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Requires Python 2.7 for latest itertools functions.
- import itertools
- allnums = [3,3,7,7]
- # [3, 3, 7, '/', '+', 7, '*'] # RPN
- # == 3 + (3/7) * 7
- # == 24
- allnums = [1,3,4,6]
- # [6, 1, 3, 4, '/', '-', '/']) # RPN
- # == 6 / (1 - (3/4))
- # == 24
- target = 24
- allops = {
- "+": (lambda a,b: a+b),
- "-": (lambda a,b: a-b),
- "*": (lambda a,b: a*b),
- # Convert to floating point (and use epilson for comparison below) to
- # allow (approximate) fractional calculation.
- "/": (lambda a,b: float(a)/b),
- }
- def rpncalc(input):
- stack = []
- for i in input:
- if isinstance(i, str): # op
- try:
- b, a = stack.pop(), stack.pop()
- except IndexError:
- result = "illegal"
- break
- try:
- stack.append(allops[i](a, b))
- except ZeroDivisionError:
- result = "NaN"
- break
- else:
- stack.append(i)
- else:
- result = stack[-1]
- return result
- def doit():
- numperms = set()
- for perm in itertools.permutations(allnums, 4):
- if perm in numperms:
- continue
- numperms.add(perm)
- results = set()
- for opnames in itertools.product(allops.keys(), repeat=3):
- for nums in numperms:
- # This permutations isn't quite right: creates dupes in the whole
- # set because we've already done the other orders.
- for ordering in itertools.permutations(nums[2:] + opnames[:-1]):
- input = list(nums[:2])
- input += ordering
- input.append(opnames[-1])
- result = rpncalc(input)
- if not isinstance(result, (int, float)):
- pass
- else:
- print "rpncalc(%s) = %s" % (input, result)
- results.add(result)
- if abs(target - result) < 0.1: # epsilon
- print "Found it!"
- return
- print sorted(results)
- doit()
Add Comment
Please, Sign In to add comment