Library · The Fiddler: Solutions · Chapter 135
Can You Flip the Coins Exactly as You’d Expect?
Flip three fair coins. There are four possible outcomes: three heads (with probability ), two heads (), one head () and no heads ().
Now flip the three coins eight times. What is the probability that you get exactly one occurrence of three heads, three of two heads, three of one head and one of no heads, in any order?
The Fiddler, Zach Wissner-Gross, November 17, 2023(original post)
The official solution appeared in the post of December 1, 2023 and gives percent for the main puzzle and the pattern , at about percent, for the Extra Credit. Both agree with the answers below.
Solution
Count the ways first, then price each one. Write the eight rounds as a string of results such as where each symbol is the number of heads in that round. Because the rounds are independent, any one string with one , three s, three s and one has probability How many such strings are there? Arrange eight symbols in orders, then divide out the reorderings of the three equal s and of the three equal s, which do not produce new strings: Every one of these strings has the same probability, so Small as it is, this is the single most likely set of counts. The data matching the probabilities exactly is the best guess, but there are so many near misses that the bull’s-eye is rarely hit.
The computation
The program builds the chances for one round by listing all eight equally likely results of three coins. It then runs through all possible sequences of eight rounds, multiplies the chances along each, and adds up the sequences whose counts are one, three, three and one. Fractions keep it exact.
from fractions import Fraction
from itertools import product
from collections import Counter
# one round: count heads over the 8 equally likely coin triples
heads = Counter(sum(c) for c in product((0, 1), repeat=3))
p = {h: Fraction(n, 8) for h, n in heads.items()}
target = {3: 1, 2: 3, 1: 3, 0: 1}
total = Fraction(0)
pattern = Counter() # for the Extra Credit below
for seq in product(range(4), repeat=8):
pr = Fraction(1)
for h in seq:
pr *= p[h]
counts = Counter(seq)
if all(counts[h] == n for h, n in target.items()):
total += pr
key = tuple(sorted((counts[h] for h in range(4)),
reverse=True))
pattern[key] += pr
print("main:", total, float(total))
It prints
main: 25515/524288 0.04866600036621094
Extra Credit
Again flip three coins eight times. Among the four outcomes, the most frequent occurs times, the next times, then , then , so and (ties allowed). Which ordered quadruple is most likely?
Solution
The quadruple forgets which outcome had which count. So its probability is a sum over every way of handing the four counts to the four outcomes. Each hand-out is priced just as in the main puzzle: if the two likely outcomes (two heads and one head, each ) receive of the eight rounds between them, the hand-out has probability because each of the rounds contributes a factor and every round contributes .
There are only quadruples, and two forces pull against each other. Counts near the expected make each hand-out likely. Four different counts allow the most hand-outs, , while repeated counts allow fewer. Work out the two strongest candidates.
For the multinomial factor is . All hand-outs are different. The likely pair of outcomes receives some two of the counts, in either order, and the other pair receives the remaining two, in either order, so each choice of pair appears times: and the probability is percent.
For the multinomial factor is and there are hand-outs. The likely pair takes in hand-outs, in , in and in , giving and a probability of percent.
The same arithmetic for every quadruple gives the full table:
| quadruple | hand-outs | chance | quadruple | hand-outs | chance |
|---|---|---|---|---|---|
The pattern of the main puzzle, , is only seventh: its one great hand-out cannot make up for having just six. The winner is
The computation
The loop in The computation above already filed every sequence under its sorted counts. Print the most likely quadruples.
for key, pr in pattern.most_common(3):
print(key, pr, f"{float(pr):.4f}")
It prints
(4, 3, 1, 0) 45885/262144 0.1750
(3, 2, 2, 1) 36855/262144 0.1406
(5, 2, 1, 0) 33579/262144 0.1281