Teaser 2643: Pack points
From The Sunday Times, 19th May 2013 [link] [link]
Five cubs were awarded points for effort. Enid’s son and Master Smith had 17 points between them, Masters Jones and Robinson had a total of 16, Ivan and Master Robinson together had 14, and the two youngest of the cubs had a total of 13. John and Master Brown had a total of 12 points, Brenda’s son and Mike had 11 points between them, Ken and his best friend had a total of 10, Ann’s son and Debbie’s son together had 9, Christine’s son and Nigel had a total of 8, and Master Perkins and Debbie’s son together had 6.
In alphabetical order of their mothers’ Christian names, what were the names of the five cubs (Christian name and surname)?
[teaser2643]
Jim Randell 9:21 am on 19 October 2023 Permalink |
If we use variables A, B, C, D, E to correspond to the points allocated (according to mothers name), then we can allocate the first names and surnames of the cubs to the same set of variables to give us a set of simultaneous linear equations, which we can attempt to solve to give the points values.
I used the [[
Matrix.linear()]] solver from the enigma.py library to find assignments that give non-negative points values. (Although there are no further solutions if negative values are permitted).I also ensure that the pairings mentioned in the text all consist of distinct cubs. (Although, again, there are no further solutions if a pairing can refer to the same cub twice).
The following Python program runs in 375ms.
Run: [ @replit ]
from enigma import (Matrix, subsets, catch, printf) # suppose the points are: A, B, C, D, E (according to mothers name) # then we can map the first and surnames to these values # variables vs = "ABCDE" # a function to construct equations def eq(vs, k, fn=Matrix.equation(vs)): r = fn(vs, k) assert {0, 1}.issuperset(r[0]) # reject coefficients that aren't 0 or 1 return r # validate point values def valid(x): assert not x < 0 return x # for firstnames I, J, K, M, N for (I, J, K, M, N) in subsets(vs, size=len, select='P'): # for surnames P, R, S, T (= Brown), U = (Jones) for (P, R, S, T, U) in subsets(vs, size=len, select='P'): # try to solve the equations r = None try: # construct equations eqs = [ eq(['E', S], 17), # Enid + Smith = 17 eq([U, R], 16), # Jones + Robinson = 16 eq([I, R], 14), # Ivan + Robinson = 14 eq([J, T], 12), # John + Brown = 12 eq(['B', M], 11), # Brenda + Mike = 11 eq(['A', 'D'], 9), # Ann + Debbie = 9 eq(['C', N], 8), # Christine + Nigel = 8 eq([P, 'D'], 6), # Perkins + Debbie = 6 ] # solve the equations r = Matrix.linear(eqs, valid=valid) except (ValueError, AssertionError): pass if r is None: continue # check there is a pair = 13 (two youngest), and a pair = 10 (Ken + friend) v = dict(zip(vs, r)) if not any(v[x] + v[K] == 10 for x in vs if x != K): continue if not any(v[x] + v[y] == 13 for (x, y) in subsets(vs, size=2)): continue # output solution mn = { 'A': 'Anne', 'B': 'Brenda', 'C': 'Christine', 'D': 'Debbie', 'E': 'Enid' } fn = { I: 'Ivan', J: 'John', K: 'Ken', M: 'Mike', N: 'Nigel' } sn = { P: 'Perkins', R: 'Robinson', S: 'Smith', T: 'Brown', U: 'Jones' } for k in vs: printf("{fn} {sn} = {v} points [{mn}]", mn=mn[k], fn=fn[k], sn=sn[k], v=v[k]) printf()Solution: The names of the cubs are:
So the youngest two are Mike and Ken (= 13 points in total), and Ivan must be Ken’s best friend (= 10 points in total).
LikeLike