Project Euler Problem 199
Three circles of equal radius are placed inside a larger circle such that each pair of circles is tangent to one another
Solution
Answer: 0.00396087
The key tool for this problem is Descartes’ Circle Theorem.
If four mutually tangent circles have curvatures (bendings)
$$k_i=\frac1{r_i}$$
(with the enclosing circle given a negative curvature), then:
$(k_1+k_2+k_3+k_4)^2 = 2(k_1^2+k_2^2+k_3^2+k_4^2)$
Solving for the fourth curvature gives
$$k_4 = k_1+k_2+k_3 \pm 2\sqrt{k_1k_2+k_2k_3+k_3k_1}.$$
For a gap-filling circle, we use the plus sign.
1. Geometry setup
Let the three initial equal circles have radius $1$, so their curvature is
$$k=1.$$
The outer enclosing circle has negative curvature $k_0$.
Applying Descartes to the four mutually tangent circles:
$$(k_0+1+1+1)^2 = 2(k_0^2+1+1+1).$$
Simplifying:
$$(k_0+3)^2 = 2(k_0^2+3)$$
$$k_0^2-6k_0-3=0$$
$$k_0 = 3\pm2\sqrt3.$$
The enclosing circle must have negative curvature, so
$$k_0 = 3-2\sqrt3 = -(2\sqrt3-3).$$
Hence its radius is
$$R=\frac1{2\sqrt3-3}.$$
The total area is therefore
$$A_{\text{outer}}=\pi R^2.$$
Initially covered area:
$$3\pi.$$
2. Recursive gap filling
Each gap is determined by three mutually tangent circles with curvatures
$(a,b,c)$.
The curvature of the largest circle fitting into that gap is
$$d=a+b+c+2\sqrt{ab+bc+ca}.$$
That new circle has area
$$\frac{\pi}{d^2}.$$
After inserting it, the gap splits into three smaller gaps:
$$(a,b,d),\quad (a,c,d),\quad (b,c,d).$$
So we recursively process those.
3. Initial gaps
There are 4 initial gaps:
- 1 central gap: $(1,1,1)$
- 3 outer gaps: $(-(2\sqrt3-3),1,1)$
We recurse for 10 iterations.
4. Python implementation
from math import sqrt, pi
# Curvature magnitude of enclosing circle
k0 = 2 * sqrt(3) - 3
# Total area of enclosing circle
A_outer = pi / (k0 ** 2)
def added_area(a, b, c, depth):
"""
Total area added by recursively filling the gap
determined by circles with curvatures a,b,c.
"""
if depth == 0:
return 0.0
# Descartes theorem (new circle curvature)
d = a + b + c + 2 * sqrt(a*b + b*c + c*a)
# Area of newly inserted circle
area = pi / (d ** 2)
# Recurse into the 3 new gaps
area += added_area(a, b, d, depth - 1)
area += added_area(a, c, d, depth - 1)
area += added_area(b, c, d, depth - 1)
return area
# Initial three circles
covered = 3 * pi
# Fill the central gap
covered += added_area(1, 1, 1, 10)
# Fill the three outer gaps
covered += 3 * added_area(-k0, 1, 1, 10)
# Fraction not covered
fraction_uncovered = 1 - covered / A_outer
print(f"{fraction_uncovered:.8f}")
5. Code walkthrough
Curvature setup
k0 = 2 * sqrt(3) - 3
This is the positive magnitude of the enclosing circle curvature.
The actual enclosing curvature used in recursion is -k0.
Recursive function
d = a + b + c + 2 * sqrt(a*b + b*c + c*a)
Computes the curvature of the new tangent circle.
Area contribution
area = pi / (d ** 2)
Because radius $r=1/d$, area is $\pi r^2 = \pi/d^2$.
Recursive subdivision
Each inserted circle creates 3 new gaps:
(a,b,d), (a,c,d), (b,c,d)
which are processed recursively.
6. Verification against the problem statement
For 3 iterations, the program gives
$$0.06790342$$
which matches the value in the problem statement exactly.
For 10 iterations, it gives
$$0.003960869448\ldots$$
Rounded to eight decimal places:
$$0.00396087$$
Answer: 0.00396087