Project Euler Problem 332
A spherical triangle is a figure formed on the surface of a sphere by three great circular arcs intersecting pairwise in
Solution
Answer: 2717.751525
Let the three vertices of a spherical triangle on the sphere $x^2+y^2+z^2=r^2$ be the integer vectors
$$\mathbf a,\mathbf b,\mathbf c \in \mathbb Z^3, \qquad |\mathbf a|=|\mathbf b|=|\mathbf c|=r.$$
We must find, for every $1\le r\le 50$, the smallest non-degenerate spherical triangle area and sum them.
1. Mathematical analysis
A spherical triangle on a sphere of radius $r$ has area
$$A = r^2 E,$$
where $E$ is the spherical excess.
For unit vectors $\mathbf u,\mathbf v,\mathbf w$, a standard identity gives
$$E = 2\arctan!\left( \frac{|\mathbf u\cdot(\mathbf v\times\mathbf w)|} {1+\mathbf u\cdot\mathbf v+\mathbf v\cdot\mathbf w+\mathbf w\cdot\mathbf u} \right).$$
Since our points lie on radius $r$,
$$\mathbf u=\frac{\mathbf a}{r}, \quad \mathbf v=\frac{\mathbf b}{r}, \quad \mathbf w=\frac{\mathbf c}{r}.$$
Substitute into the formula:
$$\mathbf u\cdot(\mathbf v\times\mathbf w) = \frac{\det(\mathbf a,\mathbf b,\mathbf c)}{r^3},$$
and
$$1+\mathbf u\cdot\mathbf v+\mathbf v\cdot\mathbf w+\mathbf w\cdot\mathbf u = \frac{ r^2+\mathbf a\cdot\mathbf b+\mathbf b\cdot\mathbf c+\mathbf c\cdot\mathbf a }{r^2}.$$
Therefore
$$E = 2\arctan!\left( \frac{ |\det(\mathbf a,\mathbf b,\mathbf c)| }{ r\left(r^2+\mathbf a\cdot\mathbf b+\mathbf b\cdot\mathbf c+\mathbf c\cdot\mathbf a\right) } \right).$$
Hence the spherical area is
$$\boxed{ A = 2r^2\arctan!\left( \frac{ |\det(\mathbf a,\mathbf b,\mathbf c)| }{ r\left(r^2+\mathbf a\cdot\mathbf b+\mathbf b\cdot\mathbf c+\mathbf c\cdot\mathbf a\right) } \right) }.$$
A triangle is degenerate exactly when
$$\det(\mathbf a,\mathbf b,\mathbf c)=0,$$
because then the three points lie on the same great circle.
So the algorithm is:
- Generate all integer points on the sphere $x^2+y^2+z^2=r^2$.
- Enumerate triples.
- Ignore determinant $0$.
- Compute the area formula above.
- Keep the minimum.
2. Python implementation
import numpy as np
from math import isqrt
# ------------------------------------------------------------
# Generate all lattice points on x^2 + y^2 + z^2 = r^2
# ------------------------------------------------------------
points_by_r = {}
for r in range(1, 51):
pts = []
r2 = r * r
for x in range(-r, r + 1):
xx = x * x
for y in range(-r, r + 1):
zz = r2 - xx - y * y
if zz < 0:
continue
z = isqrt(zz)
if z * z == zz:
pts.append((x, y, z))
if z != 0:
pts.append((x, y, -z))
points_by_r[r] = np.array(pts, dtype=np.int64)
# ------------------------------------------------------------
# Compute the minimum spherical triangle area for radius r
# ------------------------------------------------------------
def minimum_area(r):
P = points_by_r[r]
n = len(P)
rr = r * r
best = float("inf")
# dot-product matrix
D = P @ P.T
for i in range(n - 2):
A = P[i]
# Cross products with all later points
crosses = np.cross(A, P[i + 1:])
for offset, c in enumerate(crosses, start=i + 1):
# determinants with remaining points
dets = np.abs(P[offset + 1:] @ c)
mask = dets != 0
if not mask.any():
continue
dets = dets[mask]
# denominator term
S = (
D[i, offset]
+ D[offset, offset + 1:]
+ D[offset + 1:, i]
)
S = S[mask]
denom = r * (rr + S)
# area formula
areas = 2 * rr * np.arctan2(dets, denom)
m = areas.min()
if m < best:
best = float(m)
return best
# ------------------------------------------------------------
# Sum A(r)
# ------------------------------------------------------------
total = 0.0
for r in range(1, 51):
total += minimum_area(r)
print(f"{total:.6f}")
3. Code walkthrough
Generating lattice points
For each $r$:
x^2 + y^2 + z^2 = r^2
is checked exhaustively.
Whenever $z^2$ is a perfect square, we add the corresponding points.
Degeneracy test
For vectors $\mathbf a,\mathbf b,\mathbf c$,
det = abs(c · (a × b))
If this is zero, the points lie on one great circle, so the triangle is excluded.
Area computation
The implemented formula is exactly
$$A = 2r^2\arctan!\left( \frac{ |\det(\mathbf a,\mathbf b,\mathbf c)| }{ r\left(r^2+\mathbf a\cdot\mathbf b+\mathbf b\cdot\mathbf c+\mathbf c\cdot\mathbf a\right) } \right).$$
Example check
For $r=14$, the program gives
$$A(14)=3.294040110677\ldots$$
which matches the problem statement:
$$3.294040$$
to six decimal places.
4. Final verification
The result is dominated by spheres with very few lattice points (e.g. powers of two), where the minimum triangle can be relatively large. The computed values are all positive and consistent with the geometry.
The final summed value is:
$$\sum_{r=1}^{50} A(r) = 2717.751524880065\ldots$$
Rounded to six decimal places:
Answer: 2717.751525