mathematical permutation calculations

Today on car talk, they asked the question, given the numbers 2, 3, 4, and 5, and a selection of mathematical operations, which mathematical arrangement yields the number 26. Rather than try to reverse-engineer the answer intelligently, I wrote a Python program to brute force the answer. Here it is for your amusement.


#!python
# the question is, what mathematical operation or operations,
# each used only once, on the four numbers 2,3,4,5 will result
# in the number 26
from __future__ import print_function
import itertools, operator

def apply_funcs(functions):
"""
Return a function that will cycle through the functions
for each set of arguments passed in.
>>> funcs = apply_funcs([operator.add, operator.sub])
>>> reduce(funcs, [1,2,3,4]) == 1+2-3+4
True
"""
functions = itertools.cycle(functions)
return lambda *args: next(functions)(*args)

def calculate_result(numbers, ops):
return reduce(apply_funcs(ops), numbers)

numbers = map(int,'2345')
ops = [getattr(operator, op) for op in 'add sub mul truediv pow'.split()]
n_ops = len(numbers)-1
candidates = itertools.product(
itertools.permutations(numbers),
itertools.permutations(ops, n_ops),
)
is_target_result = lambda candidate: calculate_result(*candidate) == 26
target_combinations = filter(is_target_result, candidates)
map(print, target_combinations)

"""
((3, 2, 5, 4), (<built-in function truediv>, <built-in function add>, <built-in
function mul>))
((5, 2, 3, 4), (<built-in function pow>, <built-in function sub>, <built-in function add>))
((5, 2, 4, 3), (<built-in function pow>, <built-in function add>, <built-in function sub>))
"""
Written on May 23, 2009