"""
mjd's 17 puzzle.
Given 5 integers a, b, c, d, and e, find an expression that combines
a, b, c, and d with arithmetic operations (+, -, *, and /) to get e.

Darius Bacon
"""

from __future__ import division
from fractions import Fraction
from itertools import product

def puzzle(target, nums):
    for e in exprs_over(tuple(map(Fraction, nums))):
        try:
            v = eval(e)
        except ZeroDivisionError:
            pass
        else:
            if v == target:
                print e

commutative_ops    = ('+', '*')
noncommutative_ops = ('-', '/')
all_ops = commutative_ops + noncommutative_ops

def exprs_over(nums):
    if len(nums) == 1:
        yield nums[0]
    elif 1 < len(nums):
        for L, R in splits(nums):
            if not L or not R: continue
            for x, y in product(exprs_over(L), exprs_over(R)):
                for op in all_ops:
                    yield '(%s %s %s)' % (x, op, y)
                for op in noncommutative_ops:
                    yield '(%s %s %s)' % (y, op, x)

def splits(xs):
    if not xs:
        yield (), ()
    else:
        for L, R in splits(xs[1:]):
            yield L+(xs[0],), R
yield L, R+(xs[0],)
