Brainteasers & Puzzles

Rainbow Hats

Seven prisoners, seven hat colours, each sees the others but not his own. Can they guarantee that at least one guesses right?

solvedmedium2 min

Seven prisoners will be hatted tomorrow. The executioner puts a hat on each, every hat one of the seven rainbow colours, chosen however he likes. Each prisoner sees the other six hats but never his own, and no one may communicate. Each writes a single guess of his own colour. If at least one guess is right the whole room goes free, otherwise all are executed. They have tonight to agree on a plan.

Can they guarantee freedom?

Reveal solutionHide solution

#The shared invariant

Yes. Number the prisoners 00 through 66, code the colours 00 through 66, and let xix_i be prisoner ii's colour. No two prisoners see the same thing, but they can all reason about one global quantity, the total

S=j=06xj(mod7).(1)S = \sum_{j=0}^{6} x_j \pmod 7. \tag{1}

No one knows SS, since each prisoner is missing his own term. The plan covers every possible value of SS at once. Prisoner ii bets that the total is ii.

#The guess

Prisoner ii sums the six hats he sees and names the colour that would make the total equal to his own index,

gi=(ijixj)mod7.(2)g_i = \Bigl(i - \sum_{j \neq i} x_j\Bigr) \bmod 7. \tag{2}

This uses only the six hats he can see, so it is a legal move.

#Why one guess always lands

Prisoner ii is right exactly when gi=xig_i = x_i, which rearranges to

ijixjxi(mod7),that isij=06xjS(mod7).(3)i - \sum_{j \neq i} x_j \equiv x_i \pmod 7, \qquad\text{that is}\qquad i \equiv \sum_{j=0}^{6} x_j \equiv S \pmod 7. \tag{3}

The total SS is one definite value in {0,,6}\{0, \dots, 6\}, so exactly one index matches it. Whatever the executioner chooses, prisoner SS names his own colour and the room goes free. The seven bets tile the seven residues with no overlap and no gap, so the number of correct guesses is always exactly one.

Each prisoner guesses the colour that makes the total code sum to his own index, modulo seven. The actual sum is 2, so prisoner 2 guesses right and the room goes free. Deal again and a different prisoner carries the round, but never zero.

#Checking every assignment

Seven colours on seven heads is only 777^7 cases, small enough to settle by exhaustion.

from itertools import product

N = 7

def guesses_right(hats: tuple[int, ...], i: int) -> bool:
    others = sum(h for j, h in enumerate(hats) if j != i) % N
    return (i - others) % N == hats[i]

def correct_count(hats: tuple[int, ...]) -> int:
    return sum(guesses_right(hats, i) for i in range(N))

print({correct_count(h) for h in product(range(N), repeat=N)})  # -> {1}

Every one of the 823,543823{,}543 assignments yields exactly one correct guess, never zero.

#Wider view

Nothing here is special to seven. With nn prisoners and nn colours the same sum modulo nn gives exactly one correct guess on every assignment, and that is the most they can force. Across all nnn^n assignments the correct guesses total nnn1=nnn \cdot n^{n-1} = n^n, an average of one per assignment, and this strategy meets that average on the nose every time.