Brain-Teaser 727: Right hand
From The Sunday Times, 22nd June 1975 [link]
When South, who was bored with being dummy, had left the card room of the Logic Club for good, West extracted four kings, three queens and two jacks from the pack, showed them round, shuffled them, and dealt three cards to each of the three.
“Forget the suits”, he said. “Let each of us look at his own three cards and see if he can make a sure statement about any kings, queens or jacks in the next man’s hand; we will use as evidence what we see in our own hands and what we hear each other say.
They played with the full rigours of logic. West began by announcing that he could say nothing about North’s hand; North then said that he could say nothing about East’s hand; thereupon East said that he could deduce the value of one card — and one only — in West’s hand.
What can you say about the cards that were dealt to East?
This puzzle is included in the book The Sunday Times Book of Brain-Teasers: Book 2 (1981).
[teaser727]


Jim Randell 9:18 am on 26 July 2022 Permalink |
There are 9 possible hands that could be dealt to W, and in each case W would be able to say something about the cards that are dealt to N:
So let’s use a tighter definition that each must declare if they know for certain cards that are held by the next player.
This reduces the list to:
And this allows us to find an answer to the puzzle.
This Python program runs in 58ms. (Internal runtime is 1.2ms).
Run: [ @replit ]
from collections import defaultdict from enigma import (multiset, join, printf) # format a hand fmt = lambda x: join(x).upper() # deal groups of <k> cards from <cards> def deal(cards, k, ss=[]): if not cards: yield ss else: # choose the first hand for hand in cards.subsets(size=3): yield from deal(cards.difference(hand), k, ss + [tuple(hand.sorted())]) # initial cards cards = multiset(K=4, Q=3, j=2) values = sorted(cards.keys()) # possible deals hands = list(deal(cards, 3)) # look at W's hand, record the number of Ks, Qs, Js in N's w = defaultdict(lambda: defaultdict(set)) for (W, N, E) in hands: for k in values: w[W][k].add(N.count(k)) # W can't be sure of any cards held by N Ws = set(W for (W, d) in w.items() if all(0 in d[k] for k in values)) printf("[W = {Ws}]", Ws=join(map(fmt, Ws), sep=", ", enc="{}")) # look at N's hand, record the number of Ks, Qs, Js in E's n = defaultdict(lambda: defaultdict(set)) for (W, N, E) in hands: if W not in Ws: continue for k in values: n[N][k].add(E.count(k)) # N can't be sure of any cards held by E Ns = set(N for (N, d) in n.items() if all(0 in d[k] for k in values)) printf("[N = {Ns}]", Ns=join(map(fmt, Ws), sep=", ", enc="{}")) # look at E's hand, record the number of Ks, Qs, Js in W's e = defaultdict(lambda: defaultdict(set)) for (W, N, E) in hands: if W not in Ws or N not in Ns: continue for k in values: e[E][k].add(W.count(k)) # E can be sure of exactly 1 card held by W for (E, d) in e.items(): if sorted(min(v) for v in d.values()) == [0, 0, 1]: printf("E = {E}", E=fmt(E))Solution: East held a King, a Queen, and a Jack.
LikeLike
John Crabtree 6:50 pm on 26 July 2022 Permalink |
In manually reaching the same solution, I concluded that West must hold at least one King, and that North must hold at least one King and one Queen. That gives three possible sets of hands.
Do you agree? Thanks.
LikeLike
Jim Randell 8:20 am on 27 July 2022 Permalink |
@John: Yes, I found three possible sets of hands:
LikeLike