Sunday Times Teaser 2403 – A Numbers Teaser
by John Owen
A pack of nine cards is numbered from 1 to 9. One card is placed on the forehead of each of four logicians so that they can see their colleague’s numbers but not their own.
In turn, each chooses to state either: (a) whether or not he knows his own number, or b) the sum of any two of the three numbers he can see.
One game went as follows:
Alf ’14’, Bert ‘Yes’, Chris ‘7’, Dave ‘No’, Alf ‘Yes’
What number did Dave hold?
One Comment
Leave one →

brian gladman permalink123456789101112131415161718192021222324252627282930313233343536373839from itertools import permutationsfrom collections import defaultdict as df_dict# Alf '14' > list 4tuples for which two of (B, C, D) sum to 14li = []for a, b, c, d in permutations(range(1, 10), 4):if b + c == 14 or b + d == 14 or c + d == 14:li += [(a, b, c, d)]# Bert 'Yes' > find the B values for each of the tuples (A, C, D) and# keep only 4tuples where B is uniquely determined by (A, C, D)di = df_dict(list)for a, b, c, d in li:di[(a, c, d)].append(b)li = [(a, b[0], c, d) for (a, c, d), b in di.items() if len(b) == 1]# Chris '7'  remove those for which no two of (A, B, D) sum to 7li = [(a, b, c, d) for (a, b, c, d) in li if 7 in (a + b, b + d, d + a)]# Dave 'No' > find the D values for each of the tuples (A, B, C) and# keep only values where D is NOT uniquely determined by (A, B, C)di = df_dict(list)for a, b, c, d in li:di[(a, b, c)].append(d)li = [(t, d_vals) for t, d_vals in di.items() if len(d_vals) > 1]# Alf 'Yes' > find values where A is uniquely determined by (B, C, D)di = df_dict(list)for (a, b, c), d_vals in li:for d in d_vals:di[(b, c, d)].append(a)# output the resultsfs = 'A = {0}, B = {1}, C = {2}, D = {3}'for (b, c, d), a_vals in di.items():if len(a_vals) == 1:print(fs.format(a_vals[0], b, c, d))