Brainteaser 1500: Lying about his age
From The Sunday Times, 9th June 1991 [link]
It’s Uncle Joe’s birthday today, but he’s reluctant to tell me how old he is. Here are some clues, although some of them aren’t true:
1. Every number of a true statement is a factor of Joe’s age.
2. Every number of a false statement is a factor of Joe’s age.
3. This is neither the first true nor the last false statement.
4. Of the two statements immediately before and after this one, just one is true and the other is false.
5. Of the two statements immediately before and after this one, just one is true and the other is false.
6. Each digit of Joe’s age is different and is the number of a statement which is false.
7. This is either the last true or the last false statement.
8. Every prime factor of Joe’s age is the number of a true statement.
How old is Joe?
[teaser1500]







Jim Randell 2:49 pm on 12 November 2023 Permalink |
The following Python program considers possible ages, and truth values for the statements.
The [[
Delay()]] class from the enigma.py library is used to calculate the digits and prime factors of the age only as necessary. (Although in the event this doesn’t save a great deal of processing).The program runs in 147ms. (Internal runtime is 73ms).
Run: [ @replit ]
from enigma import (Delay, irange, subsets, nsplit, prime_factor, map2str, printf) # the prime factors of <n> factors = lambda n: list(f for (f, _) in prime_factor(n)) # choose an age for n in irange(1, 121): # delay the evaluation of digits and factors _ds = Delay(nsplit, n) _fs = Delay(factors, n) # choose truth values for the statements for vs in subsets((False, True), size=8, select="M"): if all(vs): continue ss = dict(enumerate(vs, start=1)) # check the values: # 1. "every number of a true statement is a factor of the age" if ss[1] != all(n % k == 0 for (k, v) in ss.items() if v): continue # 2. "every number of a false statement is a factor of the age" if ss[2] != all(n % k == 0 for (k, v) in ss.items() if not v): continue # 3. "this is neither the first true nor the last false statement" if ss[3] != (not ((not any(vs[:2])) if ss[3] else all(vs[3:]))): continue # 4. "one of (3), (5) is true and one is false" if ss[4] != (ss[3] != ss[5]): continue # 5. "one of (4), (6) is true and one is false" if ss[5] != (ss[4] != ss[6]): continue # 6. "each digit of the age is different, and the number of a false statement" ds = _ds.value if ss[6] != (len(ds) == len(set(ds)) and all(not ss.get(d, 1) for d in ds)): continue # 7. "this is either the last true or the last false statement" if ss[7] != ((not ss[8]) if ss[7] else ss[8]): continue # 8. "every prime factor of the age is the number of a true statement" fs = _fs.value if ss[8] != all(ss.get(f, 0) for f in fs): continue # output solution printf("n={n} {ss}", ss=map2str(ss, enc="[]"))Solution: Joe is 72.
And the values of the statements are:
LikeLike