Enigmatic Code

Programming Enigma Puzzles

Enigma 1219: Fare’s fair

From New Scientist #2374, 21st December 2002 [link]

I asked four experts what they were planning to eat for their Christmas lunch (main course and dessert). Their replies were:

Ainsley: “I’m having turkey. I’m not having Christmas pudding.”
Gary: “I’m having turkey. I’m not having Christmas pudding.”
Jamie: “I’m having turkey. I’m not having Christmas pudding.”
Rick: “Ainsley is having turkey. I’m not having Christmas pudding.”

Ainsley: “Gary is having goose. Rick is having chocolate mousse.”
Gary: “Ainsley is having duck. Jamie is having mince pies.”
Jamie: “Rick is having salmon. Ainsley is having trifle.”
Rick: “Jamie is having turkey. Gary is not having mince pies.”

They are each planning to have a different one of those four main courses and a different one of those four desserts. At least one of the four experts told the truth throughout, at least one lied throughout, and the rest gave exactly one correct statement in each pair.

What is Rick planning to have for his Christmas lunch (main course and dessert)?

[enigma1219]

One response to “Enigma 1219: Fare’s fair”

1. Jim Randell 10 July 2015 at 9:46 am

This Python program examines all possible permutations of main courses and desserts. It runs in 37ms.

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

# mains
mains = ('turkey', 'goose', 'duck', 'salmon')

# desserts
desserts = ('pudding', 'mousse', 'pies', 'trifle')

# label the experts
experts = (A, G, J, R) = (0, 1, 2, 3)

# assign the mains
for (m, d) in product(permutations(mains), permutations(desserts)):

# determine the values of the statements
ss = (
(m[A] == 'turkey', d[A] != 'pudding', m[G] == 'goose',  d[R] == 'mousse'), # A
(m[G] == 'turkey', d[G] != 'pudding', m[A] == 'duck',   d[J] == 'pies'),   # G
(m[J] == 'turkey', d[J] != 'pudding', m[R] == 'salmon', d[A] == 'trifle'), # J
(m[A] == 'turkey', d[R] != 'pudding', m[J] == 'turkey', d[G] != 'pies'),   # R
)

# at least one of the experts told the truth throughout
true = lambda s: all(s)
ts = list(x for x in experts if true(ss[x]))
if not ts: continue

# at least one of the experts lied throughout
false = lambda s: not any(s)
fs = list(x for x in experts if false(ss[x]))
if not fs: continue

# the others gave one true and one false answer in each pair (xor)
xor = lambda s: (s[0] ^ s[1]) and (s[2] ^ s[3])
if not all(x in ts or x in fs or xor(ss[x]) for x in experts): continue

printf("[mains = {m}, desserts = {d}]")
printf("[statements = {ss}]")
printf("[all true = {ts}, all false = {fs}]")
printf("Rick: main = {m}, dessert = {d}", m=m[R], d=d[R])
printf()
```

Solution: Rick is planning on having Salmon as his main course and Trifle as his dessert.

There is only one possible assignment of main courses and desserts:

Ainsley: Duck; Christmas Pudding.
Gary: Turkey; Chocolate Mousse.
Jamie: Goose; Mince Pies.
Rick: Salmon; Trifle.

Ainsley lied in all four of his statements.
Gary told the truth in all four of his statements.
Jamie’s first two statements were a lie and a truth, and his second two statements were a truth and a lie.
Rick’s first two statements were a lie and a truth, and his second two statements were also a lie and a truth.