Hi Jim, I woke up this morning realising that my published code for this tantaliser is not very good.
I would hence be most grateful if you could substitute the attached version. best regards, Brian
from itertools import combinations, permutations, product # enumerate the names A, B, C, D, E, F, G = range(7) nms = dict(enumerate(('Alice', 'Beatrice', 'Constance', 'Deborah', 'Emily', 'Flavia', 'Gertrude'))) # enumerate the sins an, av, en, it, lu, pr, sl = range(7) sns = dict(enumerate(('anger', 'avarice', 'envy', 'intemperance', 'lust', 'pride', 'sloth'))) # all seven sins occur among Beatrice, Deborah, Emily, Gertrude so # we have the following arrangement of unknown sins (*), which must # be permutations of anger, avarice, envy, intemperance and pride # Beatrice: *, * # Deborah: lust, * # Emily: lust, * # Gertrude: sloth, * s1 = {an, av, en, it, pr} sol_g1 = set() for p in permutations(s1, 3): # the set of sins for Beatrice, Deborah, Emily and Gertrude tb, td, te, tg = s1.difference(p), {lu, p[0]}, {lu, p[1]}, {sl, p[2]} sol_g1.add(tuple(frozenset(x) for x in (tb, td, te, tg))) # the arrangement of unknown sins among Alice, Constance and Flavia is: # Alice: sloth, * # Constance: anger, * # Flavia: *, * # since each sin occurs against two names, there are 14 sins among all # seven names; the first group above has all seven sins plus lust, so # this group must have all seven sins minus lust; so the four unknowns # here must be permutations of avarice, envy, intemperance and pride s2 = {av, en, it, pr} sol_g2 = set() for q in permutations(s2, 2): # the set of sins for Alice, Constance and Flavia ta, tc, tf = {sl, q[0]}, {an, q[1]}, s2.difference(q) sol_g2.add(tuple(frozenset(x) for x in (ta, tc, tf))) for (tb, td, te, tg), (ta, tc, tf) in product(sol_g1, sol_g2): # map names to pairs of sins p2s = dict(zip(range(7), (ta, tb, tc, td, te, tf, tg))) # Constance, Emily and Flavia have no sin shared by any pair if any(p2s[x] & p2s[y] for x, y in combinations((C, E, F), 2)): continue # Alice and Gertrude admit sloth, Deborah and Emily admit lust if not (sl in p2s[A] and sl in p2s[G] and lu in p2s[D] and lu in p2s[E]): continue # Alice is not proud and Beatrice is not avaricious if pr in p2s[A] or av in p2s[B]: continue # Flavia is neither intemperate nor proud if p2s[F].intersection([it, pr]): continue # Deborah shows no anger; Constance and Deborah share a sin if an in p2s[D] or not p2s[C] & p2s[D]: continue u = [nms[x] for x in range(7) if it in p2s[x]] v = [nms[x] for x in range(7) if en in p2s[x]] print('Intemperance: {} and {}; Envy: {} and {}.'.format(*u, *v)) print() for n in range(7): print('{}: {}, {}'.format(nms[n], *(sns[s] for s in sorted(p2s[n]))))
-- https://mail.python.org/mailman/listinfo/python-list