# Enigmatic Code

Programming Enigma Puzzles

## Enigma 493b: Christmas cards

From New Scientist #1644, 24th December 1988 [link]

The five couples in Yuletide Close send cards to some of their neighbours. Some of them told me who (apart from themselves) send cards.

Alan: “The cards not involving us are the ones exchanged between Brian’s and Charles’s houses, the ones exchanged between Brian’s and Derek’s, the card from Charles to Derek (or the other way round, I’m not sure which) and the card from Brian to Eric (or the other way round).”

Brenda: “Apart from our cards, Alice and Emma exchange cards, as do Dawn and Christine, and Dawn sends Emma one.”

The Smiths: “The cards not involving us are the ones exchanged by the Thomases and the Unwins, those exchanged by the Williamses and the Vincents, the one from the Thomases to the Williamses and one between the Unwins and the Vincents (but I forget which way).”

No 3: “Nos 1 and 5 exchange cards, one card passes between Nos 2 and 4 (I don’t know which way) and No 2 sends one to No 1.”

Charles Thomas receives the same number of cards as he sends. On Christmas Eve, he goes on a round tour for drinks. He delivers one of his cards, has a drink there, takes one of their cards and delivers it, has a drink there, takes one of their cards and delivers it, has a drink there, takes one of their cards and delivers it, has a drink there, collects the card from them to him and returns home, having visited every house in the close.

Name the couples at 1-5 (for example: 1, Alan and Brenda Smith; 2, …).

Enigma 1321 is also called “Christmas cards”.

#### News

This completes the archive of Enigma puzzles from 1988. There is now a complete archive from the start of Enigma in 1979 to the end of 1988, and also from February 1999 to the final Enigma puzzle at the end of 2013. There are 1265 Enigma puzzles posted to the site, which is around 70.8% of all Enigma puzzles published.

[enigma493b] [enigma493]

### One response to “Enigma 493b: Christmas cards”

1. Jim Randell 1 April 2019 at 8:42 am

This Python program runs in 100ms.

Run: [ @repl.it ]

```from itertools import product, permutations
from enigma import irange, icount, seq_all_same, tuples, printf

# houses
houses = irange(1, 5)

# m records who sends cards to who
# m[(x, y)] = True; if x sends a card to y
#           = False; if x does not send a card to y
#           = None; if currently unknown
m0 = dict(((x, y), None) for (x, y) in product(houses, repeat=2) if x != y)

# update map m, for keys not involving x, according to vs
# return a new map, or None
def update(m, x, vs):
m1 = m.copy()
for (k, v) in m.items():
if x in k: continue
u = (k in vs)
if v is None:
m1[k] = u
else:
if v != u: return None
return m1

# house number 3 gives the following information
# for cards not involving house 3
vs1 = set([(1, 5), (5, 1), (2, 1)])
for vs in [[(2, 4)], [(4, 2)]]:
m1 = update(m0, 3, vs1.union(vs))
if m1 is None: continue

# assign females to the houses
for (fA, fB, fC, fD, fE) in permutations(houses):

# fB gives information about all cards not invloving fB
vs2 = set([(fA, fE), (fE, fA), (fD, fC), (fC, fD), (fD, fE)])
m2 = update(m1, fB, vs2)
if m2 is None: continue

# assign surnames to the houses
for (S, T, U, V, W) in permutations(houses):

# S gives information about all cards not involving S
vs3 = set([(T, U), (U, T), (W, V), (V, W), (T, W)])
for vs in [[(U, V)], [(V, U)]]:
m3 = update(m2, S, vs3.union(vs))
if m3 is None: continue

# assign males to the houses
for (mA, mB, mC, mD, mE) in permutations(houses):

# make sure there is someone called "Charles Thomas"
if not(mC == T): continue

# mA gives information about all cards not involving mA
vs4 = set([(mB, mC), (mC, mB), (mB, mD), (mD, mB)])
for vs in product([(mC, mD), (mD, mC)], [(mB, mE), (mE, mB)]):
m4 = update(m3, mA, vs4.union(vs))
if m4 is None: continue

# make sure Mr Thomas sends and receives the same number of cards
if not seq_all_same(icount(k for (k, v) in m4.items() if k[i] == T and v) for i in (0, 1)): continue

# choose an order for Mr Thomas's walk
for w in permutations(houses):
# he starts at his own house
if not(w[0] == T): continue
# and there is a corresponding chain of cards
if not all(m4[k] for k in tuples(w + w[:1], 2)): continue

printf("f={f}, m={m}, s={s}, w={w}", f=(fA, fB, fC, fD, fE), m=(mA, mB, mC, mD, mE), s=(S, T, U, V, W))
```

Solution: The residents of the close are:

1: Alan and Christine, Williams
2: Charles and Brenda, Thomas
3: Brian and Emma, Unwin
4: Derek and Alice, Smith
5: Eric and Dawn, Vincent

The card exchanges are (3 bidirectional, 3 unidirectional):

1 ↔ 5
2 ↔ 3
3 ↔ 4
2 → 1
4 → 2
5 → 3

Charles’s walk is: 2 → 1 → 5 → 3 → 4 → 2.

This site uses Akismet to reduce spam. Learn how your comment data is processed.