Teaser 2868 – Prime Logic
by John Owen
Published September 10 2017 (link)
Three expert logicians played a game with a set of twenty-one cards each containing a different two-figure prime number. Each drew a card and held it up so that they could not see their own card but could see the others. Alf, Bert and Charlie in turn were then asked two questions, namely “Is your number the smallest of the three?” and “Is your number the largest of the three?”. In the first round all three answered “Don’t know” to both questions. The same happened in rounds two and three. In round four Alf answered “Don’t know” to the first question.
What did Alf answer to the second question and what numbers did Bert and Charlie have?
One Comment
Leave one →
-
Brian Gladman permalink12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758from collections import defaultdictfrom itertools import product# all two digit primesprimes = {x for x in range(11, 100, 2) if all(x % p for p in (3, 5, 7))}# In answering the question 'is your number the smallest of the three?',# if they see numbers held by the other two that are less than or equal# to their current inferred minimum, they would be able to answer 'no';# so when they answer "don't know" we can remove such numbers as possible# for the other two; being unable to answer the question 'is your number# the largest of the three?' similarly allows us to remove numbers for# the others that are greater than or equal to their inferred maximum.# run a round of the two questions for A, B and Cdef run_round(ss):# the person currently answering the questionsfor i, a in enumerate(ss):# the other two playersfor bc in (x for j, x in enumerate(ss) if j != i):# remove values for these players that are less than or# equal to the questioned player's inferred minimumwhile min(bc) <= min(a):bc.remove(min(bc))# remove values for these players that are greater than# or equal to the questioned player's inferred maximumwhile max(bc) >= max(a):bc.remove(max(bc))# A, B, and C are the sets of possible primes that they can each holdA, B, C = primes.copy(), primes.copy(), primes.copy()# run rounds one, two and threefor rounds in range(1, 4):run_round([A, B, C])# map possible values for B and C to lists of possible A valuesbc2a = defaultdict(set)for a, b, c in product(A, B, C):if len({a, b, c}) == 3:bc2a[tuple(sorted((b, c)))].add(a)# consider the result given A's first round four "don't know" answerfor bc, a_set in bc2a.items():# A can give an answer if he has only one possible numberif len(a_set) > 1:# A can answer if one of B's or C's numbers is less than or equal# to his inferred lowest numberif min(bc) <= min(a_set):continue# A can answer if all his inferred numbers are less than or equal# to those for B and Cif max(a_set) <= min(bc):continueans = 'No' if max(bc) >= max(a_set) else 'Yes'print(f'{ans}; (B, C) = {bc}; A in {a_set}.')