Counting Solutions¶

Alex Bellos had another challenge:

I was half hoping a computer scientist would let me know exactly how many solutions there are with only the four basic operations. Maybe someone will.

As it stands, my program can't answer that question, because I only keep one expression for each value.

Also, I'm not sure what it means to be a distinct solution. For example, are ((10+9)+8) and (10+(9+8)) different, or are they same, because they both are equivalent to (10+9+8) ? Similarly, are ((3-2)-1) and (3-(2+1) different, or the same because they both are equivalent to (3 + -2 + -1) ? I think the notion of "distinct solution" is just inherently ambiguous, and each of these questions could reasonably be answered either way. My choice is to count each of these as distinct: every expression has exactly ten numbers, nine operators, and nine pairs of brackets, and if an expression differs in any character, it is different. But I won't argue with anyone who has a different definition of "distinct solution."

So how can I count expressions? One approach would be to go back to enumerating every equation (all 4862 × 49 = 1.2 bilion of them) and checking which ones equal 2016. That would take about 40 hours with my Python program, but I could get it under 40 minutes in a more efficient language.

Another approach is to count subexpressions as the table is filled in. We won't enumerate all the expressions, just count them. I'll introduce a second table, COUNTS , such that

COUNTS[(10, 9, 8)][27] == 2

because there are 2 ways to make 27 with the numbers (10, 9, 8) , namely, ((10+9)+8) and (10+(9+8)) . How do we compute the counts? By looking at every split and operator choice that can make the value, and summing up (over all of these) the product of the counts for the two sides. For example, there are 2 ways to make 27 with (10 ... 8) , and it turns out there are 3526 ways to make 1 with (7 ... 1) . So there are 2 × 3526 = 7052 ways to make 28 with this split by adding 27 and 1.