Problem 100 — Arranged Probability

solved Sat, 19 Jul 2025, 15:43 · level 5 · difficulty 13% projecteuler.net github

If a box contains twenty-one coloured discs, composed of fifteen blue discs and six red discs, and two discs were taken at random, it can be seen that the probability of taking two blue discs, $P(\text{BB}) = (15/21) \times (14/20) = 1/2$.

The next such arrangement, for which there is exactly $50\%$ chance of taking two blue discs at random, is a box containing eighty-five blue discs and thirty-five red discs.

By finding the first arrangement to contain over $10^{12} = 1\,000\,000\,000\,000$ discs in total, determine the number of blue discs that the box would contain.


Problem Analysis

The probability of drawing two blue discs in succession, without replacement, from a box of n total discs containing b blue discs is (b/n) * ((b-1)/(n-1)). Setting this equal to 1/2 and clearing denominators gives 2 * b * (b - 1) = n * (n - 1). Because both quantities count physical discs, only integer solutions matter, which makes this a Diophantine equation - a polynomial equation for which we seek integer solutions only. A naive search over all n up to 10^12 is hopeless, so the task is really to find hidden structure in this relation.

The decisive observation comes from completing the square on both sides. Multiplying out and rearranging yields (2n - 1)^2 - 2 * (2b - 1)^2 = -1. With the substitution x = 2n - 1 and y = 2b - 1 this is exactly x^2 - 2*y^2 = -1, a classic Pell equation. A Pell equation of the form x^2 - D*y^2 = ±1 has infinitely many integer solutions, all generated from a small fundamental solution by a fixed linear recurrence relation. Once this structure is recognised, the open-ended search collapses into a direct iteration: each step produces the next valid arrangement. Because the solutions grow geometrically (by a factor of roughly 3 + 2*sqrt(2) ≈ 5.83 per step), only about 40 iterations suffice to cross 10^12. The overall complexity is O(log T) in the threshold T, with each iteration performing constant-time arithmetic.

Solution Approach

Iterating the Pell equation recurrence (Python and C)

Both files implement the same algorithm: iterate the linear recurrence that generates successive solutions of the Pell equation x^2 - 2*y^2 = -1. The fundamental solution is (x, y) = (1, 1), which corresponds to the trivial arrangement n = 1, b = 1. From any solution the next is obtained by composing with the fundamental solution (3, 2) of the companion equation X^2 - 2*Y^2 = +1. Worked out in matrix form, this gives the recurrence relation:

x' = 3x + 4y
y' = 2x + 3y

I start at (x, y) = (1, 1) and apply the step in a loop. After each step I recover the disc counts with n = (x + 1) / 2 and b = (y + 1) / 2. These divisions are exact because x and y stay odd at every step - a parity that the recurrence preserves from odd starting values (each new value is an even multiple plus an odd multiple of two odd numbers, hence odd). The loop stops and returns b as soon as n first meets or exceeds the target total.

The two implementations are line-for-line equivalent. The chief language-specific difference is integer handling: Python uses arbitrary-precision integers automatically, while C declares long long (64-bit signed) explicitly. Since the answer 756872327473 and its corresponding total comfortably fit within 64 bits, the C version is safe with no big-integer machinery. The second difference is in how the recurrence step is written: Python uses a single tuple assignment, whereas C introduces two temporaries (nx, ny) so that the new x does not clobber the old x before y is computed.

workbench

Test cases

categoryinputanswer
dev total_discs = 21 15
dev total_discs = 120 85
main total_discs = 1000000000000 756872327473

Results

solutioncategoryanswerverdict avg seconds cavg seconds py
p0100_s0 dev 15 correct 0.000001 (63) 0.000001 (63)
p0100_s0 dev 85 correct 0.000001 (63) 0.000001 (63)
p0100_s0 main 756872327473 correct 0.000001 (63) 0.000004 (63)

Files

Tags & blogs

Blogs