← Back to the problem

Kazakhstan FAIO 2025 · Correction by IOAI Training

Problem 2: Probability Theory 101

This page gives the full approach. Read it once you have searched.

Metric
exact answer
Evaluated on
written answers
Our score
0.4213 = 91/216, verified 4 ways
Expected level
the exact value to 4 decimals (10 points)

Expected level reached

We solved the problem ourselves: downloaded the data, ran the experiments and measured the score below. The statement and data belong to their organisers.

The problem in brief

You roll an ordinary six-sided die three times. What is the probability that at least one of the three rolls shows a six? The answer must be written as a decimal with four digits after the point. It is a warm-up question of the Fizmat AI Olympiad 2025 (Kazakhstan) online selection, and its real lesson is a reflex you will use constantly: when "at least one" appears, look at the opposite event.

How you are scored

One exact answer, worth 10 points. Ours, checked four independent ways in solution.py:

0.4213\boxed{0.4213}

The key idea

"At least one six" is the complement of "no six at all", and "no six" is easy because the rolls are independent. One roll avoids the six with probability 5/65/6; three independent rolls all avoid it with probability (5/6)3(5/6)^3. Therefore

P(at least one six)=1−P(no six)=1−(56)3=1−125216=91216≈0.421296.P(\text{at least one six}) = 1 - P(\text{no six}) = 1 - \left(\frac{5}{6}\right)^3 = 1 - \frac{125}{216} = \frac{91}{216} \approx 0.421296 .

Rounded to four decimals: 0.42130.4213.

Why is the direct route harder? "At least one six" splits into many cases: exactly one six, exactly two, exactly three, and each case in several positions. The opposite event is a single, clean case. The complement turns an "or" of many overlapping events into an "and" of independent ones, and independent "and"s multiply.

Checking it three other ways

Counting outcomes. The 63=2166^3 = 216 ordered results are equally likely (the classical definition P(A)=m/nP(A) = m/n of the statement). The outcomes without any six are 53=1255^3 = 125, so m=216−125=91m = 216 - 125 = 91. Splitting by the number kk of sixes, (3k)53−k\binom{3}{k} 5^{3-k} outcomes have exactly kk sixes:

sixes kk0123total
outcomes12575151216

and 75+15+1=9175 + 15 + 1 = 91, as expected.

Inclusion-exclusion. Let AiA_i be "roll ii is a six". Adding P(A1)+P(A2)+P(A3)=3/6P(A_1) + P(A_2) + P(A_3) = 3/6 counts the outcomes with two sixes twice and the one with three sixes three times, so we correct:

P(A1∪A2∪A3)=3⋅16−3⋅136+1216=108−18+1216=91216.P(A_1 \cup A_2 \cup A_3) = 3 \cdot \frac{1}{6} - 3 \cdot \frac{1}{36} + \frac{1}{216} = \frac{108 - 18 + 1}{216} = \frac{91}{216}.

Simulation. One million simulated triples of rolls give 0.4211±0.00100.4211 \pm 0.0010 (95 % interval), which contains 0.42130.4213.

The classic trap

The tempting answer is 3×16=0.53 \times \frac{1}{6} = 0.5. It adds the three events as if they could not happen together, but rolling two sixes is counted twice. The figure shows how badly this goes as the number of rolls grows: with 6 rolls the naive rule promises certainty, with 12 rolls a "probability" of 2.

Probability of at least one six in n rolls: the exact value 1 - (5/6)^n rises towards 1 but never reaches it, while the naive n/6 grows without limit and passes 1 at n = 6. At n = 3 the exact value is 91/216 = 0.4213.

This exact confusion puzzled the Chevalier de Méré in the 17th century and led Pascal and Fermat to lay the foundations of probability theory.

Results

approachvalueverdict
complement, 1−(5/6)31 - (5/6)^30.4213correct
counting 91 of 216 outcomes0.4213correct, agrees
inclusion-exclusion0.4213correct, agrees
Monte Carlo, 10610^6 triples0.4211±0.00100.4211 \pm 0.0010agrees
adding probabilities, 3/63/60.5000wrong: double counting
exactly one six only, 75/21675/2160.3472wrong: "at least one" includes two and three sixes
(1/6)3(1/6)^30.0046wrong: that is "three sixes"

What to remember

  • "At least one" means "use the complement": P(at least one)=1−P(none)P(\text{at least one}) = 1 - P(\text{none}).
  • Independent events multiply: P(no six in n rolls)=(5/6)nP(\text{no six in } n \text{ rolls}) = (5/6)^n.
  • Probabilities of overlapping events do not add; inclusion-exclusion corrects the double counting.
  • The same formula is everywhere in ML: if each of nn independent models (or test cases, or attempts) succeeds with probability pp, at least one succeeds with probability 1−(1−p)n1 - (1-p)^n. It is why "best of nn samples" from a language model (pass@n) climbs so fast, and why testing many hypotheses at once produces false discoveries.
Full code (solution.py)
"""FAIO 2025 (Kazakhstan) qualification, Problem 2 "Probability Theory 101".

Three rolls of a fair die: probability of at least one six, 4 decimals.
Four independent computations (complement, enumeration, inclusion-exclusion,
Monte Carlo) and the figure of the correction.  Run:  python solution.py
"""
from fractions import Fraction as F
from itertools import product
import math
import random
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

# 1. complement: "at least one six" is the opposite of "no six at all"
p_complement = 1 - F(5, 6) ** 3

# 2. brute force over the 6^3 = 216 equally likely outcomes
outcomes = list(product(range(1, 7), repeat=3))
p_enum = F(sum(6 in o for o in outcomes), len(outcomes))

# 3. inclusion-exclusion over the events A_i = "roll i is a six"
p_ie = 3 * F(1, 6) - 3 * F(1, 36) + F(1, 216)

# exactly k sixes (binomial), to see where the 91 outcomes come from
exact = {k: math.comb(3, k) * 5 ** (3 - k) for k in range(4)}     # counts out of 216
assert sum(exact[k] for k in (1, 2, 3)) == 91

assert p_complement == p_enum == p_ie == F(91, 216)
print("exact:", p_enum, "=", float(p_enum), "; counts of k sixes:", exact)

# 4. Monte Carlo
rng = random.Random(0); N = 1_000_000
hits = sum(any(rng.randint(1, 6) == 6 for _ in range(3)) for _ in range(N))
p_mc = hits / N; half = 1.96 * math.sqrt(p_mc * (1 - p_mc) / N)
print(f"Monte Carlo: {p_mc:.4f} +- {half:.4f}")
print("ANSWER:", f"{float(p_enum):.4f}")              # 0.4213

# figure: the complement rule against the tempting n/6
plt.rcParams.update({"font.size": 12, "axes.spines.top": False, "axes.spines.right": False})
ns = list(range(1, 13))
fig, ax = plt.subplots(figsize=(9, 4.4), dpi=150)
ax.plot(ns, [1 - (5 / 6) ** n for n in ns], "o-", color="#2e86ab", lw=2.2,
        label="exact: 1 - (5/6)^n")
ax.plot(ns, [n / 6 for n in ns], "s--", color="#d1495b", lw=1.8,
        label="wrong: n/6 (adds overlapping cases)")
ax.axhline(1, color="#999", lw=1)
ax.scatter([3], [91 / 216], s=140, facecolor="none", edgecolor="black", lw=2, zorder=5)
ax.annotate("n = 3: 91/216 = 0.4213", (3, 91 / 216), xytext=(4.5, 0.2),
            arrowprops=dict(arrowstyle="->"))
ax.set_xlabel("number of rolls n"); ax.set_ylabel("P(at least one six)")
ax.set_xticks(ns); ax.set_ylim(0, 2.05)
ax.set_title("At least one six in n rolls")
ax.legend(frameon=False, loc="upper left")
fig.tight_layout(); fig.savefig("figures/at_least_one.png", facecolor="white")
print("figure written")