# Enigmatic Code

Programming Enigma Puzzles

## Tantalizer 421: Present time

From New Scientist #971, 16th October 1975 [link]

“I say”, said young Tommy on Christmas morning, when we had each seen our own presents but no one else’s, “here is a poser based on the tea-strainer, bath hat, bath soap and gloves I gave Jane, Kate, Lucy and Maud. I shall now put three questions and each of the girls must give at least two true answers out of the three”.

He first asked, “Did I give you the tea-strainer?” and got the answers: Yes, Yes, No, No. Then he asked: “Did I give you something for the bath?”, getting the answers: Yes, No, Yes, No. The he asked: “Did I give you something to wear?”, getting the answers: No, Yes, Yes, Yes. (Answers are in alphabetical order of girls).

“Now”, he said to the rest of us, “I can tell you that exactly one girl is in a position to deduce what each other girl got. Can you tell me what each girl did get?”

Due to a typo in New Scientist this puzzle was published as Tantalizer No 42.

[tantalizer421]

### One response to “Tantalizer 421: Present time”

1. Jim Randell 18 September 2019 at 8:36 am

This Python program runs in 108ms.

Run: [ @repl.it ]

```from collections import defaultdict
from enigma import subsets, multiset, printf

gifts = ('TS', 'BH', 'BS', 'GS')

# questions
q1 = lambda x: x == 'TS' # "is tea strainer"
q2 = lambda x: x in ('BH', 'BS') # "for the bath"
q3 = lambda x: x in ('BH', 'GS') # "something to wear"

(Y, N) = (1, 0)
ans = [
(Y, Y, N), # J
(Y, N, Y), # K
(N, Y, Y), # L
(N, N, Y), # M
]

# check the girl with gift <g> gives at least 2 correct responses <rs>
def correct(g, rs):
return sum(q(g) == x for (q, x) in zip((q1, q2, q3), rs))

# record possible solutions
ss = list()

# choose an assignment for the gifts
for gs in subsets(gifts, size=len, select="P"):

# check each girl gives at least two true answers
if any(correct(g, rs) < 2 for (g, rs) in zip(gs, ans)): continue

ss.append(gs)
(J, K, L, M) = gs
printf("[J={J} K={K} L={L} M={M}]")

# for each girl accumulate the number of scenarios for each gift
r = defaultdict(multiset)
for s in ss:
for (i, x) in enumerate(s):

# look for scenarios where only one girl is has a unique gift
for gs in ss:
if sum(r[i][g] == 1 for (i, g) in enumerate(gs)) != 1: continue
(J, K, L, M) = gs
printf("J={J} K={K} L={L} M={M}")
```

Solution: Jane got the bath soap; Kate got the tea-strainer; Lucy got the gloves; Maud got the bath hat.

There are three assignments of gifts to girls where each of the girls gives at least 2 correct responses.

Lucy is always able to deduce what the other girls got knowing her own gift. But in one of the scenarios Maud will also be able to tell, and in another scenario both Jane and Kate can also tell. So the scenario where only Lucy can tell is the one we are interested in.

J=TS; K=GS; L=BS; M=BH
J=BS; K=TS; L=BH; M=GS
J=BS; K=TS; L=GS; M=BH [SOLUTION]

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