# Enigmatic Code

Programming Enigma Puzzles

## Tantalizer 476: Take your partners

From New Scientist #1027, 18th November 1976 [link]

Amble, Bumble, Crumble and Dimwit had a jolly night of it at the Old Tyme ball. Each took his wife but did not dance with her. In fact each danced only three dances, changing partner each time, and spent the rest of the night in the bar.

In the Cha-Cha Amble danced with a wife larger than Mrs A and Bumble with a wife larger than Mrs B. Then came the rumba, with Crumble in the arms of a wife larger than Mrs C. Then they did the tango, in which Bumble had a wife smaller than Mrs B and Mrs B was squired by a man fatter than Amble. These were the three dances mentioned and no two men swapped partners [with each other] between the Cha-Cha and the rumba or between the rumba and the tango. No two wives are the same size.

What were the pairings for the rumba?

[tantalizer476]

### 2 responses to “Tantalizer 476: Take your partners”

1. Jim Randell 2 August 2017 at 8:11 am

Unless I’ve missed something I think this puzzle is flawed. I get three possible scenarios that satisfy the conditions given.

This Python program runs in 47ms.

```from itertools import permutations, combinations
from enigma import join, printf

# choose partners from s that aren't already allocated in ps
def choose(s, *ps):
for r in permutations(s):
if any(any(r[i] == n for (i, n) in enumerate(p)) for p in ps): continue
yield r

# choose an order for size (smallest to largest)
for s in permutations('ABCD'):
# size maps name -> measure
size = dict((n, i) for (i, n) in enumerate(s))

# choose partners for A
for A in choose('BCD'):

# dance 1: "A's partner was larger than Mrs A"
if not(size[A[0]] > size['A']): continue
# dance 3: "Mrs B's partner was fatter than A"
if A[2] == 'B': continue

# choose partners for B
for B in choose('ACD', A):

# dance 1: "B's partner was larger than Mrs B"
if not(size[B[0]] > size['B']): continue
# dance 3: "B's partner was smaller than Mrs B"
if not(size[B[2]] < size['B']): continue

# choose partners for C
for C in choose('ABD', A, B):

# dance 2: "C's partner was larger than Mrs C"
if not(size[C[1]] > size['C']): continue

# partners for D
for D in choose('ABC', A, B, C):

# determine the partners in each dance
p = list(zip(A, B, C, D))

# no partners are swapped in pairs between dance 1 and dance 2
# nor between dance 2 and dance 3
if any(
(p[0][x] == p[1][y] and p[1][x] == p[0][y]) or
(p[1][x] == p[2][y] and p[2][x] == p[1][y])
for (x, y) in combinations((0, 1, 2, 3), 2)
): continue

# output solution
f = join
printf("rumba = {r} [size={s}, A={A} B={B} C={C} D={D}]", r=f(p[1]), s=f(s), A=f(A), B=f(B), C=f(C), D=f(D))
```

The wives, in size order (smallest to largest) are:

[w1] = Mrs A < Mrs C < Mrs B < Mrs D
[w2] = Mrs C < Mrs A < Mrs B < Mrs D

And the partners in the dances are:

[p1] =

Dance 1: A & Mrs B, B & Mrs D, C & Mrs A, D & Mrs C
Dance 2: A & Mrs D, B & Mrs C, C & Mrs B, D & Mrs A
Dance 3: A & Mrs C, B & Mrs A, C & Mrs D, D & Mrs B

[p2] =

Dance 1: A & Mrs C, B & Mrs D, C & Mrs B, D & Mrs A
Dance 2: A & Mrs B, B & Mrs A, C & Mrs D, D & Mrs C
Dance 3: A & Mrs D, B & Mrs C, C & Mrs A, D & Mrs B

The valid combinations that provide a solution being:

[w1]+[p1]
[w1]+[p2]
[w2]+[p1]

Which gives two possible answers for the pairings of the rumba (Dance 2). We can write them as (A D) (B C) from [p1] and (A B) (C D) from [p2].

The published solution corresponds to [p1], and the stated order for the wives is [w2].

We could rescue the puzzle by adding the following text before the final question:

“If I told you the relative sizes of the wives you would be able to work out who danced with who.”

Then we would know for sure that the sizes of the wives must be [w2] and the partners [p1], giving the following answer:

Solution: In the rumba Amble danced with Mrs Dimwit, and Dimwit danced with Mrs Amble. Bumble danced with Mrs Crumble, and Crumble danced with Mrs Bumble.

2. Brian Gladman 2 August 2017 at 11:39 pm

My solution matches Jim’s so I agree that the puzzle is flawed.

```from itertools import combinations, permutations

# print header for the output
hdr = True
print(' ' * 25 + 'ChaCha:       Rumba:        Tango:')
print(' ' * 16 + '--men--> (A, B, C, D), (A, B, C, D), (A, B, C, D)')

# permute wives to give their size order
for ws in permutations('ABCD'):

# permute wives for the Cha-Cha
for wc in permutations('ABCD'):

# no-one dances with their own wife
if any(x == y for x, y in zip('ABCD', wc)):
continue
# A and B dance with ladies larger than their wives
if any(ws.index(wc[x]) <= ws.index(y) for x, y in zip((0, 1), 'AB')):
continue

# permute wives for the Rumba
for wr in permutations('ABCD'):

# no-one dances with their own wife
if any(x == y for x, y in zip('ABCD', wr)):
continue
# C dances with a lady larger than his wife
if ws.index(wr[2]) <= ws.index('C'):
continue

# all pairs change partners
if any(x == y for x, y in zip(wc, wr)):
continue
# no two husbands swap partners between the Cha-Cha and the Rumba
if any((wr.index(x), wr.index(y)) == (wc.index(y), wc.index(x))
for x, y in combinations('ABCD', 2)):
continue

# permute wives for the Tango
for wt in permutations('ABCD'):

# no-one dances with their own wife
if any(x == y for x, y in zip('ABCD', wt)):
continue
# B dances with a lady smaller than his wife and wife B doesn't
# dance with A
if ws.index(wt[1]) >= ws.index('B') or wt.index('B') == 0:
continue

# all pairs change partners again
if any(any(x == y for x, y in zip(w, wt)) for w in (wc, wr)):
continue
# no two husbands swap partners between the Rumba and the Tango
if any((wt.index(x), wt.index(y)) == (wr.index(y), wr.index(x))
for x, y in combinations('ABCD', 2)):
continue
# output the wives in order of size and the men's (A, B, C, D)
# partners in the ChaCha, the Rumba and the Tango respectively
dc, dr, dt = ', '.join(wc), ', '.join(wr), ', '.join(wt)
print(f"({' < '.join(ws)}) -women-> ({dc}), ({dr}), ({dt})")
```

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