From The Sunday Times, 27th September 1970 [link]
Five friends, Archer, Brown, Carter, Dale and Eade, and their wives, Anne, Betty, Clara, Diana and Edna, meet on the first Wednesday of every month to dine together (at a round table) in a local hotel. They have a rule that no wife may sit next to, or immediately opposite, her husband. Archer, as M.C., sits always with his back to the fireplace.
We are concerned with the seating arrangements in January, April, July and October. On these four occasions no man, with the exception of the M.C., sat at any place more than once. In January the men sat in clockwise alphabetical order (men and women always sit alternately). Also, on these four evenings, the ladies sitting opposite Archer were successively: Betty, Clara, Diana and Edna.
In April, Diana sat at the same place she occupied in January, and in July, Anne sat at the same place that she occupied in April.
What was the seating arrangement in October? (Clockwise, A to A, using capital initials for the men and small initials for the women).
This puzzle was originally published with no title.
[teaser487]
Jim Randell 10:06 am on 19 July 2019 Permalink |
This puzzle can be solved directly using the [[
SubstitutedExpression()]] solver from the enigma.py library.The following run file executes in 131ms.
Run: [ @repl.it ]
Solution: MILLY = 17224.
LikeLike
GeoffR 10:46 am on 20 July 2019 Permalink |
Gave up using Geocode Solver after three minutes but Chuffed Solver produced a solution in a reasonable time.
@Jim: Any idea why solvers run-times can vary so much?
LikeLike
Jim Randell 11:10 am on 23 July 2019 Permalink |
@GeoffR: Using integer literals for the powers of 10 instead of [[
pow()]] seems to make the model acceptable to the [[gecode]] solver.LikeLike
GeoffR 12:20 pm on 23 July 2019 Permalink |
@Jim: Thanks for the reply, yes that suggestion now works OK for the Geoode solver. Perhaps the Chuffed solver works better for powers as it looks as though it is based on C++
LikeLike
Jim Randell 1:16 pm on 23 July 2019 Permalink |
I suspect that one of the solvers notices that they are constant terms and calculates them once, but the other one doesn’t and keeps re-evaluating them.
LikeLike
Frits 11:15 am on 18 September 2020 Permalink |
# concatenate list of integers to_num = lambda *args: int("".join(map(str, args))) # make sure loop variable value is not equal to previous ones def domain(v): # find already used loop values ... vals = set() # ... by accessing previously set loop variable names for s in lvd[v]: vals.add(globals()[s]) return [x for x in range(1,10) if x not in vals] # set up dictionary of for-loop variables lv = ['M', 'Y', 'E', 'N', 'T', 'I', 'V', 'A', 'L'] lvd = {v: lv[:i] for i, v in enumerate(lv)} sol = set() # Solve puzzle by testing all posssible values for M in range(1,10): for Y in domain('Y'): if (to_num(M, Y) % 14 != 0): continue for E in domain('E'): for N in domain('N'): for T in domain('T'): if (to_num(E, N, T) % 14 != 0): continue for I in domain('I'): if (to_num(I, N, E) % 14 != 0): continue for V in domain('V'): for A in domain('A'): for L in domain('L'): if (to_num(V, A, L) % 14 != 0): continue sol.add(to_num(M, I, L, L, Y)) for s in sol: print(s) # Output: # # 17224LikeLike
Frits 11:35 am on 18 September 2020 Permalink |
As VAL000000 is divisible by 14, ENT000 is divisible by 14 and INE is divisible by 14 we don’t need to verify that VALENTINE is divisible by 14.
LikeLike
Frits 2:31 pm on 30 November 2021 Permalink |
Using choose().
from enigma import choose # concatenate list of integers to_num = lambda *args: int("".join(map(str, args))) S = list(choose(range(1, 10), [None, (lambda M, Y: Y not in {M} and to_num(M, Y) % 14 == 0), (lambda M, Y, E: E not in {M, Y}), (lambda M, Y, E, N: N not in {M, Y, E}), (lambda M, Y, E, N, T: T not in {M, Y, E, N} and to_num(E, N, T) % 14 == 0), (lambda M, Y, E, N, T, I: I not in {M, Y, E, N, T} and to_num(I, N, E) % 14 == 0), (lambda M, Y, E, N, T, I, V: V not in {M, Y, E, N, T, I}), (lambda M, Y, E, N, T, I, V, A: A not in {M, Y, E, N, T, I, V}), (lambda M, Y, E, N, T, I, V, A, L: L not in {M, Y, E, N, T, I, V, A} and to_num(V, A, L) % 14 == 0 and to_num(V, A, L, E, N, T, I, N, E) % 14 == 0), ])) print("MILLY:", *set("".join(str(x) for x in [s[0], s[5], s[8], s[8], s[1]]) for s in S))LikeLike
Frits 4:28 pm on 30 November 2021 Permalink |
With list comprehensions.
# even digits are reserved for Y, T, E and L digits = set("123456789") odds = set("13579") evens = digits.difference(odds) # even digits are reserved for Y, T, E and L # so M must be odd MY = set(s for x in range(10, 100) if x % 14 == 0 and len(set((s := str(x)))) == 2 and s[0] in odds and '0' not in s) # list of 3 digit numbers divisible by 14 # middle digit (A or N) must be odd dgts3 = [s for x in range(100, 1000) if x % 14 == 0 and len(set((s := str(x)))) == 3 and s[1] in odds and '0' not in s] ooe = [x for x in dgts3 if x[0] in odds] # odd, odd, even # ENT and INE are both divisible by 14 # N and I must be odd ENT_INE = [(x, y) for x in dgts3 for y in ooe if y[2] + y[1] == x[:2] and y[0] != x[2]] ENT_INE_VAL = [(x, y, z) for x, y in ENT_INE for z in ooe if "".join(sorted(digits.difference(x + y + z))) in MY] sol = set() for ENT, INE, VAL in ENT_INE_VAL: t = ENT + INE + VAL M = odds.difference([x for x in t if x in odds]) Y = evens.difference([x for x in t if x in evens]) sol.add(M.pop() + t[3] + t[8] + t[8] + Y.pop()) for s in sol: print("MILLY:", s)LikeLike
GeoffR 11:39 am on 1 December 2021 Permalink |
from itertools import permutations for p1 in permutations('123456789', 2): M, Y = p1 MY = int(M + Y) if MY % 14 != 0: continue q1 = set('123456789').difference([M, Y]) # 1st part(VAL) of VALENTINE for p2 in permutations(q1, 3): V, A, L = p2 VAL = int(V + A + L) if VAL % 14 != 0:continue q2 = q1.difference([V, A, L]) # 2nd part(ENT) of VALENTINE for p3 in permutations(q2, 4): E, N, T, I = p3 ENT = int(E + N + T) if ENT % 14 != 0:continue # 3rd part(INE) of VALENTINE INE = int(I + N + E) if INE % 14 != 0: continue VALENTINE = int(V + A + L + E + N + T + I + N + E) # Stated condition, but not necessary #if VALENTINE % 14 != 0:continue MILLY = int(M + I + L + L + Y) print(f"MY={MY}, VALENTINE={VALENTINE}, MILLY={MILLY}") # MY=14, VALENTINE=392658756, MILLY=17224 # MY=14, VALENTINE=532896798, MILLY=17224LikeLike