Brain-Teaser 488: [Truth and lies]
From The Sunday Times, 4th October 1970 [link]
The villagers of Titterton always tell the truth; those from Lilling always lie; those from Trulham alternate between truth and lie, starting with a truth; those from Litford also alternate, but start with a lie.
I recently met four men, one from each village:
Alf: “I’m from Trulham.”
Bert: “Alf’s from Lilling.”
Charlie: “Bert’s from Lilling.”
Dan: “Charlie’s from Lilling.”
Alf: “Dan’s from Titterton.”As I was sorting this out, in came three more men, each from one of other of the villages:
Edgar: “I’m from Dan’s village.”
Frank: “There are more chaps here from my village than from any other.”
George: “Frank’s lying. I’m from Bert’s village.”Name the men from Titterton, Trulham and Litford. (I should perhaps add that I live in Totworth and tell the truth invariably).
This puzzle was originally published with no title.
[teaser488]
Jim Randell 8:40 am on 21 July 2019 Permalink |
I assumed the puzzle text itself was a completely true account, and that the “alternators” were at the beginning of their cycle with their first quoted statements.
This Python program runs in 85ms.
Run: [ @repl.it ]
from enigma import (subsets, printf) # bT = always true (= Titterton) def bT(ss): return all(ss) # bF = always false (= Lilling) def bF(ss): return not any(ss) # bTF = alternate, T then F (= Trulham) def bTF(ss): return all(ss[0::2]) and not any(ss[1::2]) # bFT = alternate, F then T (= Litford) def bFT(ss): return all(ss[1::2]) and not any(ss[0::2]) # possible behaviours fns = (bT, bF, bTF, bFT) # solve the puzzle def solve(): # choose behaviours for A, B, C, D for (A, B, C, D) in subsets(fns, size=len, select='P'): # A: "I am from Trulham", "D is from Titterton" if not A([A is bTF, D is bT]): continue # B: "A is from Lilling" if not B([A is bF]): continue # C: "B is from Lilling" if not C([B is bF]): continue # D: "C is from Lilling" if not D([C is bF]): continue # choose behaviours for E, F, G for (E, F, G) in subsets(fns, size=3, select='M'): # E: "I am from D's village" if not E([E == D]): continue # F: "There are more from my village than any other" s = (A, B, C, D, E, F, G) n = dict((k, s.count(k)) for k in s) f = all(n[F] > n[x] for x in s if x != F) if not F([f]): continue # G: "F is lying" "I am from B's village" if not G([(not f), G == B]): continue yield s for s in solve(): (A, B, C, D, E, F, G) = (b.__name__ for b in s) printf("A={A} B={B} C={C} D={D} E={E} F={F} G={G}")Solution: The affiliations are:
LikeLike