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

Project Euler Problem 199

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