Re: Enigma (Tantaliser 482)

2017-05-19 Thread BlindAnagram
On 19/05/2017 10:06, BlindAnagram wrote:
> 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

Apologies - posted in error

-- 
https://mail.python.org/mailman/listinfo/python-list


Enigma (Tantaliser 482)

2017-05-19 Thread BlindAnagram
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