Teaser 3340: Generations Jay, Kay, Elle and Em
From The Sunday Times, 27th September 2026 [link] [link]
Polygonian newborns are allocated a regular polygon talisman for the day of the month they are born (1st = triangle, 2nd = square to 31st = 33-agon). Super-auspicious birth dates occur when the talisman’s internal angle is a whole number of degrees and the month number (Jan = 1 to Dec = 12) divides into it exactly and the year is a multiple of it.
Polygonians, Em, her mam Elle, Elle’s mam Kay and Kay’s dad Jay dined out on Jay’s birthday in 2024. Chef said, “Congratulations, you’re looking fit Jay. You’ll live to 100”. Elle stated they all had super-auspicious birth dates and her 2024 birthday was in the month after next. Em added that she and Kay had their 2024 birthdays in the month before last.
Chef then deduced their birth dates with certainty.
Find Em’s birth date.
[teaser3340]







Jim Randell 6:11 am on 27 September 2026 Permalink |
This Python program generate all possible “super-auspicious” dates between 1925 and 2024, and then constructs possible (J, K, L, M) values according to the specified conditions. (I also included a minimum separation between generations, but this is not necessary to find the required answer).
This gives multiple candidate dates, but the chef knows a fact we don’t know, and that is the date on which Jay’s party is being held. So we look for candidates where knowing Jay’s birthday allows the all birthdates to be determined.
The program runs in 71ms. (Internal runtime is 413µs).
from enigma import ( defaultdict, namedtuple, irange, div, subsets, tuples, cproduct, filter_unique, unpack, sprintf, printf ) Date = namedtuple("Date", "y m d") # find "super-auspicious" dates (year -> month -> days) date = defaultdict(lambda: defaultdict(set)) for d in irange(1, 31): n = d + 2 # calculate internal angles of a regular n-gon a = div(360, n) if a is None: continue a = 180 - a # calculate possible months ms = list(m for m in irange(1, 12) if a % m == 0) # consider possible years for y in irange.round(1925, 2024, rnd='I', step=a): for m in ms: date[y][m].add(d) # record possible (J, K, L, M) dates ss = list() # now find possible birthyears for J, K, L, M for ys in subsets(sorted(date.keys()), size=4): # reject any sequences with <16 years between generations if any(b - a < 16 for (a, b) in tuples(ys, 2)): continue (Jy, Ky, Ly, My) = ys # choose a date for J for (Jm, Jds) in date[Jy].items(): if Jm < 3 or Jm > 10: continue # L's birthday is 2 months later Lm = Jm + 2 Lds = date[Ly].get(Lm) if not Lds: continue # M and K are 2 months earlier Mm = Km = Jm - 2 Mds = date[My].get(Mm) Kds = date[Ky].get(Km) if not (Mds and Kds): continue for (Jd, Kd, Ld, Md) in cproduct([Jds, Kds, Lds, Mds]): ss.append((Date(Jy, Jm, Jd), Date(Ky, Km, Kd), Date(Ly, Lm, Ld), Date(My, Mm, Md))) # the chef knows the date of the party rs = filter_unique(ss, unpack(lambda J, K, L, M: (J.m, J.d))) fmt = lambda t: sprintf("{t.y:04d}-{t.m:02d}-{t.d:02d}") # format a date for (J, K, L, M) in rs.unique: printf("J={J}, K={K}, L={L} M={M}", J=fmt(J), K=fmt(K), L=fmt(L), M=fmt(M))Solution: [To Be Revealed]
LikeLike