Here’s my solution to the problem for Jan. 1, 2013. The solution is written in Python.
The task:
As we begin the new year, we note that 109-8*7+654*3-2/1 = 2013. There are three other combinations of the numbers 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, in order, combined with the five operators NIL, +, -, * and / that also evaluate to 2013.
Your task is to write a program that finds all four expressions that evaluate to 2013.
My solution:
# This function generates equations based on the positions of the # operations in a list. After producing an equation, it sends the # equation to another function to be evaluated. It would be faster # if I only generated and checked solutions that didn't start with # '+', '*', or '/' (as solutions of this sort are not valid in my # scheme) but this presumably doesn't add a significant amount of # computation time, so it's unnecessary to worry about. def generateEqsAndSolve(): Ops = ['-', '', '+', '*', '/'] for x in (itertools.product(Ops, repeat=10)): processEq(list(x)) # Create an equation from the ordered list of operations. # Then solve for the value of the equation. def processEq(L): if L[0] == '*' or L[0] == '/' or L[0] == '+': return # Get the equation as a string. equation = '' for x in range(len(L)): if (L[x] == '-' or L[x] == '+') and x != 0: equation += ' ' equation += L[x] equation += str(10-x) equationLen = len(equation) # Evaluate the equation...p finalVal = 0.0 num = 0.0 i = 0 while i < equationLen: eqPart = '' if equation[i] == '-': i += 1 while equation[i] != ' ' and i < equationLen: eqPart += equation[i] i += 1 if not i < equationLen: break num = processNum(eqPart) num *= -1 elif equation[i] == '+' or equation[i] == '': i += 1 while equation[i] != ' ' and i < equationLen: eqPart += equation[i] i += 1 if not i < equationLen: break num = processNum(eqPart) finalVal += num i += 1 # If the equation has the value of 2013, print it! if math.fabs(finalVal - 2013) < .004: print equation return # Helper function that takes string representing # part of an eqaution produced in processEq and # returns the value of the part of the equation def processNum(eqPart): partLen = len(eqPart) i = 0 count = 0 strNum = '' num = 0 storedNum = 1.0 op = '' while i < partLen: if not eqPart[i].isdigit(): break strNum += eqPart[i] i += 1 storedNum = float(strNum) strNum = '' while i < partLen: op = eqPart[i] i += 1 while eqPart[i].isdigit() and i < partLen: strNum += eqPart[i] i += 1 if not i < partLen: break num = int(strNum) if op == '*': storedNum *= num else: storedNum /= num strNum = '' return storedNum