'''
October 2018 Puzzler
10/3/18
You are equipped with two 2's, a single 3, and a single 6 along with
the ability to combine them using only addition, subtraction,
multiplication, division, and exponentiation.
Your job is to create each of the integers from 26 to 38.
You may use any number of parentheses to control the order of
operations and do not have to use all four of the numbers each
time.
For Example: 60 = 6 * (2^3 + 2)
'''
from __future__ import print_function
import itertools as it
class Solution(object):
'''
A Solution is a solution to the puzzler.
'''
def __init__(self, value, equation):
self.value = value #Value is the result of the equation
self.equation = equation #The expression that evaluates to value
self.hash = hash(equation) #An unique integer for the expression
def __repr__(self):
'''
Text representation of a Solution object. For example:
"27 = 3 + (2 + 2) * 6"
'''
return str(self.value) + " = " + self.equation
def __eq__(self, other):
'''
Solutions are equal if the equations give identical hashes.
'''
return other.hash == self.hash
def __ne__(self, other):
return other.hash != self.hash
def __hash__(self):
return self.hash
def __gt__(self, other):
return self.value > other.value
def __lt__(self, other):
return self.value < other.value
def evaluate(equation):
'''
Evaluate equation. If the result is 26 to 38, create a Solution object
and add it to the answer set.
'''
try: #test for and ignore errors
result = eval(equation)
resultInt = int(result)
#Test that the result is an integer in the range(26, 39)
if result == resultInt and result in range(26, 39):
#if result == resultInt and result in range(1, 100):
answers.add(Solution(resultInt, equation))
except:
pass
if __name__ == "__main__":
answers = set() #Create a Set of solutions to remove duplicates
operands = it.permutations('2236') #All possible arrangements of operands
operators =[] #All possible arrangements of operators
for a in ['+', '-', '*', '/', '**']: # less all exponetiation (results too big)
for b in ['+', '-', '*', '/', '**']:
for c in ['+', '-', '*', '/', '**']:
if not (a=="**" and b=="**" and c=="**"):
operators.append([a, b, c])
for d in operands:
for t in operators:
#Two term equations
eqn = str(d[0]) + " " + str(t[0]) + " " + str(d[1])
evaluate(eqn)
#Three term equations
eqn = str(d[0]) + " " + str(t[0]) + " " + str(d[1]) \
+ " " + str(t[1]) + " " + str(d[2])
evaluate(eqn)
eqn = "(" + str(d[0]) + " " + str(t[0]) + " " + str(d[1]) + ")" \
+ " " + str(t[1]) + " " + str(d[2])
evaluate(eqn)
eqn = str(d[0]) + " " + str(t[0]) + " " + "(" + str(d[1]) \
+ " " + str(t[1]) + " " + str(d[2]) + ")"
evaluate(eqn)
#Four term equations
eqn = str(d[0]) + " " + str(t[0]) + " " + str(d[1]) \
+ " " + str(t[1]) + " " + str(d[2]) \
+ " " + str(t[2]) + " " + str(d[3])
evaluate(eqn)
eqn = "(" + str(d[0]) + " " + str(t[0]) + " " + str(d[1]) \
+ ") " + str(t[1]) + " " + str(d[2]) \
+ " " + str(t[2]) + " " + str(d[3])
evaluate(eqn)
eqn = str(d[0]) + " " + str(t[0]) + " (" + str(d[1]) \
+ " " + str(t[1]) + " " + str(d[2]) \
+ ") " + str(t[2]) + " " + str(d[3])
evaluate(eqn)
eqn = str(d[0]) + " " + str(t[0]) + " " + str(d[1]) \
+ " " + str(t[1]) + " (" + str(d[2]) \
+ " " + str(t[2]) + " " + str(d[3]) + ")"
evaluate(eqn)
eqn = "(" + str(d[0]) + " " + str(t[0]) + " " + str(d[1]) \
+ " " + str(t[1]) + " " + str(d[2]) \
+ ") " + str(t[2]) + " " + str(d[3])
evaluate(eqn)
eqn = str(d[0]) + " " + str(t[0]) + " (" + str(d[1]) \
+ " " + str(t[1]) + " " + str(d[2]) \
+ " " + str(t[2]) + " " + str(d[3]) + ")"
evaluate(eqn)
eqn = "(" + str(d[0]) + " " + str(t[0]) + " " + str(d[1]) \
+ ") " + str(t[1]) + " (" + str(d[2]) \
+ " " + str(t[2]) + " " + str(d[3]) + ")"
evaluate(eqn)
answers = sorted(answers)
#Print the Solutions
for answer in answers:
print(answer)
print("Number of solutions: ", len(answers))