def repeat(n, xs): return [xs for _ in range(n)] def sequence(xss, acc): if not xss: return acc return sequence(xss[1:], [a + [x] for x in xss[0] for a in acc]) def is_balanced(xs): """ Check if subsets are balanced. That means for every lower number there is a higher number that balances it out. """ ones_balanced, twos_balanced = True, True ones, twos = 0, 0 for x in xs: if x == 1: ones += 1 twos -= 1 elif x == 2: ones -= 1 twos += 1 if ones < 0: ones_balanced = False if twos < 0: twos_balanced = False return ones_balanced or twos_balanced def euler_106(): n = 12 # Generate all possible subsets where both subsets have the same number of # elements and at least two elements per subset. xs = repeat(n, [0, 1, 2]) xs = [x for x in sequence(xs, [[]]) if x.count(1) > 1 if x.count(1) == x.count(2)] return len([1 for x in xs if not is_balanced(x)]) // 2 if __name__ == "__main__": solution = euler_106() print("e106.py: " + str(solution)) assert(solution == 21384)