# Enigmatic Code

Programming Enigma Puzzles

## Tantalizer 473: Pigeon post

From New Scientist #1024, 28th October 1976 [link]

In the name of democracy the officers of our Pigeon Fanciers Club announce that they would not stand for re-election this year. This cheered the rest of us no end, until we found that it applied only individually. Collectively they planned to retain all five offices for the umpteenth year running.

To allay suspicions, the plot was a mite complex. There would be no direct swaps. Bumble would take the post of the man who was to become Organiser. Crumble would take the post of the man who was to become Treasurer. Dimwit would take the post of the man who would take Amble’s post. The current Vice-President would take the post vacated by the new President. Eggfrith would become Secretary, despite his wish to become the Organiser.

It all worked flawlessly, of course.

Who was and is what?

[tantalizer473]

### 2 responses to “Tantalizer 473: Pigeon post”

1. Jim Randell 13 September 2017 at 9:34 am

This Python program looks at all possibilities for both assignments of posts. It runs in 68ms.

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

# labels for the posts
jobs = "OPSTV"

# indices for the people
(A, B, C, D, E) = (0, 1, 2, 3, 4)

# consider initial jobs
for p1 in permutations(jobs):

# "E wishes to become O", so he isn't O to start with
if p1[E] == 'O': continue

# and the final jobs
for p2 in permutations(jobs):

# "E becomes S"
if p2[E] != 'S': continue

# no-one keeps the same job
if any(x == y for (x, y) in zip(p1, p2)): continue

# no-one swaps jobs
if any(p2[p1.index(j)] == p1[p2.index(j)] for j in jobs): continue

# "B takes the post of the man who becomes O"
if not(p2[B] == p1[p2.index('O')]): continue

# "C takes the post of the man who becomes T"
if not(p2[C] == p1[p2.index('T')]): continue

# "D takes the post of the man who takes A's post"
if not(p2[D] == p1[p2.index(p1[A])]): continue

# "The current V takes the post vacated by the new P"
if not(p2[p1.index('V')] == p1[p2.index('P')]): continue

printf("before = ({p1}), after = ({p2})", p1=join(p1, sep=", "), p2=join(p2, sep=", "))
```

Solution: Before: Amble was President, Bumble was Secretary, Crumble was Organiser, Dimwit was Vice-President, Eggfrith was Treasurer. After: Amble is Treasurer, Bumble is Vice-President, Crumble is President, Dimwit is Organiser, Eggfrith is Secretary.

2. arthurvause 28 September 2017 at 11:19 am

As there are no direct swaps and everyone changes post, the changes of post must be a 5-cycle, so we can test 5-cycles of posts and of people:

```

from itertools import permutations

# generate 5-cycles of people A,B,C,D,E where D is 3 steps on from A
people_cycles = [ ['A']+list(q) for q in permutations('BCDE')
if q[2] == 'D' ]

# generate 5-cycles of offices, O,T,V,P,S where S doesn't follow O and P is 2 steps on from V
for p in permutations('TVPS'):
offices = ['O']+list(p)
if offices[1] == 'S':
continue
if (offices.index('P') - offices.index('V'))%5 != 2:
continue

for people in people_cycles:

# adjust the offset so that Eggfrith becomes Secretary
s = people.index('E') - offices.index('S')
new_posts = [people[(i+s)%5] for i in xrange(5)]
#print "\t",s," new_p", new_p
if (offices.index('O') -new_posts.index('B'))%5 !=1:
continue
if (offices.index('T') -new_posts.index('C'))%5 !=1:
continue

print "Previous posts are", sorted([new_posts[i]+":"+offices[(i-1)%5] for i in xrange(5)])
print "New posts are", sorted([new_posts[i]+":"+offices[i] for i in xrange(5)])
```