#!/usr/bin/python # -*- coding: utf-8 -*- """Solve a puzzle: combine the bag of values {3, 3, 8, 8} to get 24. Use any number of +, -, *, / to compute them. Ugly brute force approach; wonder if it’s buggy. """ def trees(): values = [3, 3, 8, 8] indices = set(range(len(values))) ops = {'+': lambda a, b: a+b, '-': lambda a, b: a-b, '*': lambda a, b: a*b, '/': lambda a, b: 0 if b == 0 else a/b } return ('%s %s %s -> %s; %s %s %s -> %s; %s %s %s -> %s' % (left1, op1, right1, val1, left2, op2, right2, val2, left3, op3, right3, val3) for left1_pos in indices for left1 in [values[left1_pos]] for right1_pos in indices - {left1_pos} for right1 in [values[right1_pos]] for op1 in ops for val1 in [ops[op1](left1, right1)] for left2_pos in indices - {left1_pos, right1_pos} | set(['val1']) for left2 in [values[left2_pos] if left2_pos in indices else val1] for right2_pos in (indices | set(['val1'])) - {left1_pos, right1_pos, left2_pos} for right2 in [values[right2_pos] if right2_pos in indices else val1] for op2 in ops for val2 in [ops[op2](left2, right2)] for left3_pos in (indices | set(['val1', 'val2'])) - {left1_pos, right1_pos, left2_pos, right2_pos} for left3 in [val1 if left3_pos == 'val1' else val2 if left3_pos == 'val2' else values[left3_pos]] for right3_pos in (indices | set(['val1', 'val2'])) - {left1_pos, right1_pos, left2_pos, right2_pos, left3_pos} for right3 in [val1 if right3_pos == 'val1' else val2 if right3_pos == 'val2' else values[right3_pos]] for op3 in ops for val3 in [ops[op3](left3, right3)] if len(indices - {left1_pos, right1_pos, left2_pos, right2_pos, left3_pos, right3_pos}) == 0 and val3 == 24) if __name__ == '__main__': for item in trees(): print item