# what a drag ... arg_list = [1.0, 3.0, 4.0, 6.0] rez = 24 def perm(lst): if not lst: return [[]] ret = [] for x in lst: p = perm(filter(lambda a: a != x, lst)) ret += [[x] + a for a in p] return ret def rep_comb(lst, n): if not (lst and n): return [[]] ret = [] rc = rep_comb(lst, n-1) for x in lst: ret += [[x] + a for a in rc] return ret def assocs(args, ops): if not ops: return [('!', args[0], 0)] rets = [] for i in xrange(len(ops)): exp_list1 = assocs(args[:i+1], ops[:i]) exp_list2 = assocs(args[i+1:], ops[i+1:]) for e1 in exp_list1: for e2 in exp_list2: rets.append((ops[i], e1, e2)) return rets class math_error(Exception): pass op_list = ['+', '-', '*', '/'] def eval(exp): (op, a, b) = exp if op == '!': return a a, b = eval(a), eval(b) if op == '+': return a + b elif op == '-': return a - b elif op == '*': return a * b elif op == '/': if b == 0: raise math_error() return a / b def exp_tostr(exp): (op, a, b) = exp if op == '!': return str(int(a)) return "(%s %s %s)" % (exp_tostr(a), op, exp_tostr(b)) for args in perm(arg_list): for ops in rep_comb(op_list, len(arg_list) - 1): for exp in assocs(args, ops): try: if eval(exp) == rez: print exp_tostr(exp) except math_error: pass