Enigma (Tantaliser 482)
BlindAnagram
blindanagram at nowhere.com
Fri May 19 05:06:12 EDT 2017
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
-------------- next part --------------
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]))))
More information about the Python-list
mailing list