Teaser 3257: Powers of deduction
From The Sunday Times, 23rd February 2025 [link] [link]
One evening, Sherlock Holmes challenges Watson and Mycroft to a game of Cluedo.
He places one each of the six “person” cards, six “weapon” cards and nine “room” cards into the murder bag, shuffles the rest and deals them out equally.
Mycroft sees his cards and says, “If I guessed what was in the murder bag now, my chance of being correct is one in an integer that is a power greater than two”.
“I’m saying nothing”. Watson replies. “I’d only give something away”.
“Commendably prudent”, Sherlock says, “but the same is true for you”.
Watson studies his cards, then looks agitated. “How could you know that?”
“Sherlock isn’t cheating”. Mycroft reassures him. “He didn’t even know how many person cards you’re holding”.
How many room cards is Mycroft holding?
[teaser3257]
Jim Randell 8:14 am on 23 February 2025 Permalink |
After the culprit is selected there are 5 person, 5 weapon and 8 room cards remaining, and these are distributed among the 3 players (so, 6 cards each).
If a player is holding p person cards, w weapon cards, and r room cards, then the probability of making a correct accusation from the cards he is not holding is:
This Python program finds possible (p, w, r) hands that have a 1/(n^k) chance of giving a correct guess, where k > 2.
from enigma import (decompose, irange, inf, powers, first, lt, printf) # there are only a few higher powers than squares to consider (M, pows) = (6 * 6 * 9, set()) for k in irange(3, inf): ps = first(powers(2, inf, k), count=lt(M)) if not ps: break pows.update(ps) # find hands of 6 cards, with a 1/power chance of a correct guess for (p, w, r) in decompose(6, 3, increasing=0, sep=0, min_v=0): if p > 5 or w > 5: continue N = (6 - p) * (6 - w) * (9 - r) if N not in pows: continue # output possible hands printf("p={p} w={w} r={r} -> N={N}")The only cards that give a required 1/power chance are:
Mycroft declares he has one of these hands, and Sherlock declares Watson has one of these hands. It is not possible for there to be more than one (3 3 0) hand, but if there are a (3 3 0) and a (1 1 4) then the remaining hand is also a (1 1 4), and if there are two (1 1 4) hands then the remaining hand is a (3 3 0), and so Sherlock also has one of these hands.
Hence the three hands are (1 1 4) (1 1 4) (3 3 0) (in some order). So when Mycroft declares he has one of these, Sherlock can see that he (Sherlock) also has one, and so Sherlock can declare that Watson must too have one of these hands.
Which means Mycroft and Sherlock both know that each of them has one of these three hands, and if either of them has (3 3 0) they know the other two must both have (1 1 4).
So Sherlock must be holding (1 1 4) (as Mycroft states that he does not know which of the possible hands Watson is holding), and the only way Mycroft can be certain that Sherlock has (1 1 4) is if he (Mycroft) is holding (3 3 0).
And so: Mycroft = (3 3 0), Watson = (1 1 4), Sherlock = (1 1 4).
Solution: Mycroft is holding no room cards.
LikeLike
Jim Randell 9:44 pm on 23 February 2025 Permalink |
I’ve not seen another solution to this puzzle yet, so here is a complete solution.
The following Python program runs in 60ms. (Internal runtime is 476µs).
from enigma import ( namedtuple, decompose, irange, inf, powers, first, lt, subsets, filter_unique, unpack, intersect, seq2str, printf ) # there are only a few higher powers than squares to consider (M, pows) = (6 * 6 * 9, set()) for k in irange(3, inf): ps = first(powers(2, inf, k), count=lt(M)) if not ps: break pows.update(ps) # find hands of 6 cards, with a 1/power chance of a correct guess Hand = namedtuple('Hand', 'p w r') hs = list() for (p, w, r) in decompose(6, 3, increasing=0, sep=0, min_v=0): if p > 5 or w > 5: continue N = (6 - p) * (6 - w) * (9 - r) if N not in pows: continue # output possible hands printf("[({p}, {w}, {r}) -> N={N}]") hs.append(Hand(p, w, r)) # collect possible scenarios ss = list() # M and W each have one of these hands for (M, W) in subsets(hs, size=2, select='M'): # and S has the remaining cards S = Hand(5 - M.p - W.p, 5 - M.w - W.w, 8 - M.r - W.r) if S.p < 0 or S.w < 0 or S.r < 0: continue ss.append((M, W, S)) # find situations where S _cannot_ determine W.p ss1 = filter_unique(ss, unpack(lambda M, W, S: S), unpack(lambda M, W, S: W.p)).non_unique # find situations where M _can_ fully determine S's hand ss2 = filter_unique(ss, unpack(lambda M, W, S: M), unpack(lambda M, W, S: S)).unique # look for common situations for (M, W, S) in intersect([ss1, ss2]): printf("M={M} W={W} S={S}", M=seq2str(M), W=seq2str(W), S=seq2str(S))LikeLike