Teaser 2844: Children’s children
From The Sunday Times, 26th March 2017 [link] [link]
The head teacher’s retirement celebration was attended by many former pupils. These included Adam, Brian, Colin and David, whose sons and grandsons had also attended the school – actually different numbers of grandsons for each of them, with Adam having the most. Their sons were Eric, Fred, George, Harry and Ivan, and the sons of the sons were John, Keith, Lawrence, Michael, Norman and Oliver.
Altogether Adam and Brian had sons Eric, Fred and one other; altogether Adam and Colin had sons George and one other; altogether Eric, George and Harry had sons Keith, Michael, Norman and one other; and altogether Harry and Ivan had sons Lawrence, Norman and one other.
The retirement gift was presented by the fathers of John’s and Oliver’s fathers.
Who were they?
As stated there are multiple solutions to this puzzle.
This puzzle was not included in the published collection of puzzles The Sunday Times Brainteasers Book 1 (2019).
There are now 600 puzzles available on S2T2.
[teaser2844]











Jim Randell 11:19 am on 16 December 2021 Permalink |
As stated the puzzle has multiple solutions.
The following Python program builds the 8 possible family trees that fit the described situation.
It runs in 85ms.
Run: [ @replit ]
from enigma import (subsets, peek, product, map2str, join, printf) # map ks to vs def make_map(ks, vs): for ss in subsets(ks, size=len(vs), select='M'): d = dict((k, list()) for k in ks) for (k, v) in zip(ss, vs): d[k].append(v) yield d # find viable father -> sons mappings def check_fs(fs): # "A, B have sons E, F and one other" s = fs['A'] + fs['B'] if not (len(s) == 3 and 'E' in s and 'F' in s): return False # "A, C have sons G and one other" s = fs['A'] + fs['C'] if not (len(s) == 2 and 'G' in s): return False # looks OK return True # collect viable maps ffs = list(fs for fs in make_map('ABCD', 'EFGHI') if check_fs(fs)) # find viable son -> grandsons maps def check_sg(sg): # "E, G, H have sons K, M, N and one other" s = sg['E'] + sg['G'] + sg['H'] if not (len(s) == 4 and 'K' in s and 'M' in s and 'N' in s): return False # "H, I have sons L, N and one other" s = sg['H'] + sg['I'] if not (len(s) == 3 and 'L' in s and 'N' in s): return False # looks OK return True # collect viable maps sgs = list(sg for sg in make_map('EFGHI', 'JKLMNO') if check_sg(sg)) # find the father of x in map d def father(x, d): return peek(k for (k, v) in d.items() if x in v) # choose the maps for (fs, sg) in product(ffs, sgs): # A, B, C, D have different numbers of grandsons s = list(sum(len(sg[s]) for s in fs[f]) for f in 'ABCD') if len(set(s)) != 4: continue # A has the most if s[0] != max(s): continue # grandfather of J and O gJ = father(father('J', sg), fs) gO = father(father('O', sg), fs) # they must be different people if gJ == gO: continue # output solution f = lambda s: join(s, sep="+") fmt = lambda m: map2str((k, f(v)) for (k, v) in m.items()) printf("{gs} [grandfather(J) = {gJ}; grandfather(O) = {gO}]", gs=f(sorted([gJ, gO]))) printf(" father -> sons: {fs}", fs=fmt(fs)) printf(" son -> grandsons: {sg}", sg=fmt(sg)) printf()Solution: One of the presenters is Adam, but the other can be any of: Brian, Colin, or David.
The originally published solution is: “Adam and David”, but a later correction was made (with Teaser 2846) noting there are three valid solutions to the puzzle (given above).
However, there is a unique solution if the end of the puzzle is changed to:
We can change the sense of the test at line 68 to ensure that the grandfathers of John and Oliver are the same person, and we find there are 2 possible family trees that lead to this situation, but in both cases the grandfather is Brian.
LikeLike
Hugh+Casement 8:34 am on 17 December 2021 Permalink |
Without trying Jim’s program, I think it’s like this:
A’s son is H whose sons are L, N, and either K or M. D’s son is I who has no son.
C’s son is G whose son is M or K (whichever is not H’s son).
Brian has sons E (who has no sons) and F who is the father of J and O.
LikeLike