Brain-Teaser 491: [Family names]
From The Sunday Times, 25th October 1970 [link]
Each of the five families in Admirals Walk comprised three boys; one of the boys in each family had the same christian name as the surname of one of his neighbours, and no boy had the same christian and surname.
The three christian names of Mr. Arnold’s three sons all had the same initial as the surname of Lawrence, who lived opposite to Benjamin Thomas.
Mr. Gordon’s oldest son had a christian name with the same initial as Clement’s surname. Clement’s father played chess with Jasper Lawrence’s father.
Mr. Oliver was Arnold’s father’s business partner. Godfrey had measles. Mr. Oliver’s oldest son had the same christian name as Crispin’s surname, and also the same initial to his christian name as Arnold’s surname. Arnold lived next door to the man whose son Oswald played truant from school with his cousin Hector Lawrence, until Oswald’s brother Walter, a school prefect, caught them.
Gilbert and Oscar had red hair.
Oliver was in Borstal. What was his surname?
When originally published the condition relating to Mr. Oliver’s sons was given as:
Mr. Oliver’s oldest son had the same christian name as Crispin’s surname, and Mr. Oliver’s youngest son had the same initial to his christian name as Arnold’s surname.
However a correction was published with Brain-Teaser 493 stating:
It is regretted that in para. 3, line 7, “youngest” should have read “eldest”. However, as the correct initials of these boys can be proved independently and most solvers gave the correct answer, this answer will stand.”
I have made the correction in the puzzle text above, although instead of just changing “youngest” to “eldest”, as we are already talking about Mr. Oliver’s oldest son, I used “and also”.
This puzzle was originally published with no title.
[teaser491]
Jim Randell 9:11 am on 4 August 2019 Permalink |
There are 15 first names mentioned, so each boy must have a different first name.
This Python 3 program starts by filling out the full names we are given. Then it looks for three first names with the same initial for the Arnold family (which also gives us Lawrence’s surname). It then allocates the remaining names, and checks the remaining conditions.
It runs in 271ms.
Run: [ @repl.it ]
from collections import defaultdict from enigma import subsets, update, diff, multiset, Accumulator, join, printf # names we know (map: firstname -> lastname) names = { "Benjamin": "Thomas", "Hector": "Lawrence", "Jasper": "Lawrence" } # the surnames are all distinct by initial lastnames = dict((x[0], x) for x in ("Arnold", "Gordon", "Lawrence", "Oliver", "Thomas")) # the remaining first names firstnames = ["Clement", "Crispin", "Gilbert", "Godfrey", "Oscar", "Oswald", "Walter" ] firstnames.extend(lastnames.values()) # group firstnames by initial initial = defaultdict(list) for f in firstnames: initial[f[0]].append(f) # complete the families, ensuring no-one has the same first/last name def complete(ns, fs): # are we done? if not fs: yield ns else: # find an incomplete family to fill out s = multiset(ns.values()) r = Accumulator(fn=min) for v in lastnames.values(): n = 3 - s.get(v, 0) if n > 0: r.accumulate_data(n, v) (n, v) = (r.value, r.data) # choose names for ts in subsets(diff(fs, [v]), size=n): yield from complete(update(ns, ts, [v] * n), diff(fs, ts)) # collect results r = multiset() # the Arnold children share the same first initial for (k, vs) in initial.items(): if k == 'L': continue for fs in subsets(vs, size=3): if "Arnold" in fs: continue ns1 = update(names, fs, ["Arnold"] * 3) # Lawrence has one of these names as a surname ns1["Lawrence"] = lastnames[k] # complete the allocations for ns in complete(ns1, diff(firstnames, ns1.keys())): # "Clement's father played chess with Jasper Lawrence's father" # so Clement's surname is not Lawrence if ns["Clement"] == "Lawrence": continue # "Mr. Oliver was Arnold's father's business partner" # so Arnold's surname is not Oliver if ns["Arnold"] == "Oliver": continue # "Oswald played truant from school with his cousin Hector Lawrence" # so Oswald's surname is not Lawrence if ns["Oswald"] == "Lawrence": continue # "Arnold lived next door to ... Oswald" # so Arnold and Oswald have different surnames if ns["Arnold"] == ns["Oswald"]: continue # "... Oswald's brother Walter ..." # so Oswald and Walter have the same surname if ns["Oswald"] != ns["Walter"]: continue # "Mr. Oliver's oldest son had the same christian name as Crispin's surname ..." oliver_maj = ns["Crispin"] if ns[oliver_maj] != "Oliver": continue # "...and the same initial to his christian name as Arnold's surname" if oliver_maj[0] != ns["Arnold"][0]: continue # "Mr. Gordon's oldest son had a christian name with the same initial as Clement's surname" gordon_maj = list(k for (k, v) in ns.items() if v == "Gordon" and k[0] == ns["Clement"][0]) if not gordon_maj: continue # each family has a child whose name is the surname of one of the other families ss = sorted(lastnames.values()) fss = list() for v in ss: fss.append(set(x for (x, s) in ns.items() if s == v)) if not all(fs.intersection(ss) for fs in fss): continue # output families fmt = lambda s: join(sorted(s), sep=", ") for (s, fs) in zip(ss, fss): printf("{s}: {fs}", fs=fmt(fs)) printf("Oliver maj = {oliver_maj}; Gordon maj = {gordon_maj}", gordon_maj=fmt(gordon_maj)) printf() # record the answer (Oliver's surname) r.add(ns["Oliver"]) # output the answer for (s, n) in r.most_common(): printf("Oliver {s} [{n} solutions]")Solution: Oliver’s surname is Lawrence.
The families are:
Oswald Gordon and Oliver Thomas are the eldest sons in their respective families.
The originally published puzzle said that “Mr. Oliver’s youngest son had the same initial to his christian name as Arnold’s surname”, which cannot be satisfied with the rest of the conditions. The youngest of the Oliver children must be Clement or Oscar, and Arnold’s surname is Lawrence or Thomas.
With the change of the puzzle text to refer to the oldest son (who is Thomas Oliver), he shares the same initial (and indeed the same name) as Arnold, as Arnold and Crispin are brothers (both Thomases).
LikeLike