# Enigmatic Code

Programming Enigma Puzzles

## Tantalizer 422: Holy matrimony

From New Scientist #972, 23rd October 1975 [link]

When the five ministers at St. Saviour’s all got divorced, it was a relief. When all announced a remarriage, it was a surprise. When the brides were revealed to be the five ex-wives, it was a sensation. Still, the priggish Dinah was not the first to remarry and there were no direct swaps, so I daresay the decencies were preserved.

The weddings were held on successive Saturdays. Peter’s took place earlier than Anne’s and later than Quentin’s. Barbara’s was later than Tristram’s and earlier than Celia’s.

Peter married Simon’s ex-wife. Barbara got hitched to the man whose former wife married Emily’s ex-husband. Quentin paired up with the lady whose former husband married Dinah. Ronald was spliced with the lady whose ex-husband married Celia.

Who, pray, is now married to whom?

[tantalizer422]

### One response to “Tantalizer 422: Holy matrimony”

1. Jim Randell 4 September 2019 at 8:30 am

This Python program runs in 171ms.

Run: [ @repl.it ]

```from enigma import subsets, join, printf

# wives and husbands
wives = list("ABCDE")
husbands = list("PQRST")

# make a pairing map (x -> y, y -> x)
def pairs(xs, ys):
d = dict(zip(xs, ys))
d.update(zip(ys, xs))
return d

# make the second marriage pairing
for s1 in subsets(husbands, size=len, select="P"):
m2 = pairs(s1, wives)

# collect possible orderings for the weddings
ws = list()
for s3 in subsets(wives, size=len, select="P"):
w = dict((x, i) for (i, x) in enumerate(s3, start=1))

# ordering constraints
# "D was not the first to remarry"
if w['D'] == 1: continue
# "P's wedding was earlier than A's and later than Q's
if not(w[m2['Q']] < w[m2['P']] < w['A']): continue
# "B's wedding was later than T's and earlier than C's
if not(w[m2['T']] < w['B'] < w['C']): continue

ws.append(w)

if not(ws): continue

# make the first marriage pairing
for s2 in subsets(husbands, size=len, select="P"):
m1 = pairs(s2, wives)

# no-one keeps their partner
if any(m1[x] == m2[x] for x in wives): continue

# no-one makes a direct swap
if any(m2[m1[m2[m1[x]]]] == x for x in wives): continue

# we know some constraints between first and second marriages
# "P married S's ex-wife"
if not(m2[m1['S']] == 'P'): continue
# "B married the man whose former wife married E's ex-husband"
if not(m1[m2['B']] == m2[m1['E']]): continue
# "Q married the lady whose former husband married D"
if not(m1[m2['Q']] == m2['D']): continue
# "R married the lady whose ex-husband married C"
if not(m2[m1[m2['R']]] == 'C'): continue

# output solution
for x in wives:
printf("{x}: divorced {d}, married {m}", d=m1[x], m=m2[x])
printf("[order = {ws}]", ws=join((join(sorted(w.keys(), key=(lambda k: w[k]))) for w in ws), sep=", "))
printf()
```

Solution: The pairings are: Emily and Quentin, Dinah and Tristram, Barbara and Ronald, Celia and Peter, Anne and Simon.

And these are given in the order of the weddings (starting with the earliest).

The previous pairings were:

Anne and Quentin
Barbara and Peter
Celia and Simon
Dinah and Ronald
Emily and Tristram

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