# 3 hats with numbers, where 2 hats sum to the third

I have outlined a puzzle below, and provided two sources which provide answers. I am disputing that the answer provided in the sources is correct, and I am looking for others to validate or invalidate my reasoning that the sources are incorrect.

# Puzzle

Three logicians (A,B and C) sit in a circle, each with a positive integer written on their hat. They can read the other two's hat number, but not their own. They are also told that two of the hat-numbers sum to equal the third. They take turns guessing what their own hat number is. The record of guesses is as follows:

• A: I don't know
• B: I don't know
• C: I don't know
• A: I don't know
• B: I don't know
• C: My number is 144

What are A and B's number?

# My issue

All sources below say that B = 3A => C = 4A => A = 36. My issue is that this is not the only valid answer. Equally valid is A = (3/5) B => C = (8 / 3) A => A = 54. I found this through exhaustive search (along 3 or 4 other I-believe-valid-answers). If you follow the chain of reasoning, you can find that C needed to wait 1 round to see if A would conclude that C would conclude A = B = 18. When A does not conclude this, then C is safe to assume they have only 1 valid choice: 144.

# Note

This is very similar to this puzzle, but it's not always A=B+C, it may be B=A+C or C=A+B.

• The answer given by the first link that you have posted says that, ". In order to identify numbers in this case, the numbers on the hats has to be in proportion i.e. multiples of other(s). Like if one has x then other must have 2x,3x etc." I can't understand why they need to be multiples ..Can you please explain ? May 17, 2021 at 21:11

I wrote an exhaustive search script with the following Python code:

def solve(data, n=6):
# Who's turn? A=0,B=1,C=2
i = (n - 1) % len(data)
return {
x
for x in {
# the new hat configuration, subbing in
# this round's candidates into the existing
# hat configuration.
(*data[:i], x, *data[i + 1 :])
for x in {
a + x * b
for aa, a in enumerate(data)
if aa != i
for bb, b in enumerate(data)
if bb != i
and bb != aa
for x in (-1, 1)
}
# must be valid hat number
if x > 0
}
# recursion termination condition
if n == 1
or
# All previous rounds must not have produced a single candidate
all(len(solve(x, n - j)) == 2 for j in range(1, n))
}

v = 144
for i in range(10000):
for data in ((i, v - i, v), (i, v + i, v), (i, i - v, v)):
s = solve(data)
if all(x >= 1 for x in data) and len(s) == 1 and next(iter(s))[-1] == v:
print(data)


32  112
36  108
54  90
64  80
108 36


The 36 108 solution matches that of the answers in the Question sources. But indeed the tree-search code above was able to find additional solutions, not mentioned in the sources. I was able to manually check 54 90 and 32 112 solution to confirm their validity.

# How it works

## The spirit

Every round, the current guesser needs to decide between two potential candidate-answers for themselves: a + b or |a - b|. If only one of the candidates is valid (i.e, positive integer), then the player can answer immediately with the only remaining candidate.

Otherwise, the current guesser must recall all prior rounds, and simulate the conclusions drawn by the previous players on their turns (including themselves from 3 rounds ago!!!). This is akin to a tree search, where a leaf node is pruned if a prior round would have deemed that candidate impossible. In turn, the player would then deduce that that entire half of the search tree is invalid, and must conclude that the other candidate is the valid one. If no leaf-pruning is possible across all rounds, then the player cannot determine their number and must pass.

## The code

The code assumes we are on round 6 for person C.

Exhaustive search of candidate (A,B,C) pairs are passed to a validator solve function, which returns all potential valid hats assuming n rounds have elapsed, and all previous rounds have produced "I don't know" answers.

Then we simply select candidates which returned only a single candidate.

• We aren't the place to get feedback on your code, and especially not a place to ask for feedback in an answer. ("ask" implies a question, and questions belong in questions) If this is meant to be more justification for your question, it belongs as an edit to your question. Answers are only for answers (preferably full, satisfactory answers, though this site allows limited partial answers). May 15, 2021 at 17:21
• @bobble Thanks for editing and improving the listing, and clarifying the community guidelines May 15, 2021 at 18:27
• There are indeed 5 possible answers May 15, 2021 at 20:25
• @Retudin do you have a solution method you can share? May 16, 2021 at 4:54

I did it (created the tree) by hand

A only knows he has a number >0 and thus he has the sumvalue if B = C
So the statement (only) excludes {2y,y,y} for any value y
B: B knows he has a number >0 and that {2y,y,y} is excluded
So the statement excludes {y,2y,y} and the other {2y,?,y) i.e. {2y,3y,y}
C:
The statement excludes {y,y,2y} as well as the other {2y,y,?},{y,2y,?} and {2y,3y,?}
i.e. {y,y,2y}, {2y,y,3y},{y,2y,3y} and {2y,3y,5y}
A:
The statement excludes the other {?,2y,y},{?,3y,y} and {?,y,2y},{?,y,3y},{?,2y,3y}, {?,3y,5y}
i.e. {3y,2y,y},{4y,3y,y},{3y,y,2y},{4y,y,3y},{5y,2y,3y}, {8y,3y,5y}
B:
Again, the statement excludes the other (B) value of the already excluded statements, >! i.e {y,3y,2y}, {2y,5y,3y},{y,4y,3y} and {2y,7y,5y} (from Cs statement) as well as
{3y,4y,y},{4y,5y,y},{3y,5y,2y},{4y,7y,3y},{5y,8y,3y}, {8y,13y,5y} (from As 2nd statement)
C:
This time, the statement means it is another (C) value of the already excluded statements, and it must be a divisor of 144
from 2nd A: -,-,{3y,y,4y},-,-,-
from 2nd B: {y,3y,4y},-, -,{2y,7y,9y} and -,{4y,5y,9y},{3y,5y,8y},-,-,-
(I added the dashes for solutions not divisible by 144)
Note: they could have asked for an unique solution (using e.g. 17,51,68 or 65,104,169)