Sunday Times Teaser 2867 – Clumsy Meg
by Graham Smithers
Published September 3 2017 (link)
I arranged cards labelled ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE and TEN equally-spaced around the perimeter of a circular table. The arrangement was such that any two adjacent cards had exactly one letter in common.
That evening Meg entered the room and accidentally knocked two adjacent cards onto the floor. In her haste to put things right, she inadvertently put the two cards back the wrong way round. Surprisingly, the one-letter property still applied.
What were the two numbers directly opposite the two that she knocked on the floor?
One Comment
Leave one →
-
Brian Gladman permalink1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950from itertools import combinationsfrom collections import defaultdictnbrs = ('ONE', 'TWO', 'THREE', 'FOUR', 'FIVE','SIX', 'SEVEN', 'EIGHT', 'NINE', 'TEN')# list the possible partners for each numbern2p = defaultdict(list)for a, b in combinations(nbrs, 2):if len(set(a).intersection(b)) == 1:n2p[a].append(b)n2p[b].append(a)# create possible sequences around the circledef solve(x):# have all numbers been used?if len(x) == 10:# avoid duplicate solutionsif x[1] > x[9]:# if the first and last numbers partnerif x[-1] in n2p[x[0]]:yield xelse:# add another number to the sequencefor n in n2p[x[-1]]:# if not already usedif n not in x:yield from solve(x + [n])# list possible solutionssols = list(solve(['ONE']))# consider each solutionfor s in sols:# pick a position for swapping two adjacent valuesfor i in range(10):j = (i + 1) % 10# avoid duplicate solutionsif s[i] > s[j]:ss = s.copy()# swap the two numbersss[i], ss[j] = ss[j], ss[i]if i == 0:# rotate the revised sequence to put ONE firstss = ss[1:] + ss[:1]# is the revised sequence a solutionif ss in sols:print(f'{s[(i + 5) % 10]} and {s[(j + 5) % 10]}')