All Euler problems
Project Euler

Project Euler Problem 390: Triangles with Non-Rational Sides and Integral Area

Consider the triangle with sides sqrt(5), sqrt(65), and sqrt(68). It can be shown that this triangle has area 9. S(n) is the sum of the areas of all triangles with sides sqrt(1+b^2), sqrt(1+c^2), a...

Source sync Apr 19, 2026
Problem #0390
Level Level 19
Solved By 662
Languages C++, Python
Answer 2919133642971
Length 429 words
geometryanalytic_mathmodular_arithmetic

Problem Statement

This archive keeps the full statement, math, and original media on the page.

Consider the triangle with sides \(\sqrt 5\), \(\sqrt {65}\) and \(\sqrt {68}\). It can be shown that this triangle has area \(9\).

\(S(n)\) is the sum of the areas of all triangles with sides \(\sqrt {1+b^2}\), \(\sqrt {1+c^2}\) and \(\sqrt {b^2+c^2}\,\) (for positive integers \(b\) and \(c\)) that have an integral area not exceeding \(n\).

The example triangle has \(b=2\) and \(c=8\).

\(S(10^6)=18018206\).

Find \(S(10^{10})\).

Project Euler Problem 390: Triangles with Non-Rational Sides and Integral Area

Mathematical Analysis

Area Formula Derivation

Given a triangle with sides:

p=1+b2,q=1+c2,r=b2+c2p = \sqrt{1+b^2}, \quad q = \sqrt{1+c^2}, \quad r = \sqrt{b^2+c^2}

3D Embedding Approach: Place vertices at P1=(0,0,0)P_1 = (0,0,0), P2=(1,b,0)P_2 = (1,b,0), P3=(1,0,c)P_3 = (1,0,c).

  • P1P2=1+b2|P_1P_2| = \sqrt{1+b^2}
  • P1P3=1+c2|P_1P_3| = \sqrt{1+c^2}
  • P2P3=b2+c2|P_2P_3| = \sqrt{b^2+c^2}

The area is half the cross product magnitude:

P1P2×P1P3=(1,b,0)×(1,0,c)=(bc,c,b)\vec{P_1P_2} \times \vec{P_1P_3} = (1,b,0) \times (1,0,c) = (bc, -c, -b) Area=12b2c2+b2+c2\text{Area} = \frac{1}{2}\sqrt{b^2c^2 + b^2 + c^2}

Verification with Heron’s formula: Setting p2=1+b2p^2 = 1+b^2, q2=1+c2q^2 = 1+c^2, r2=b2+c2r^2 = b^2+c^2:

16Area2=2p2q2+2q2r2+2r2p2p4q4r4=4(b2c2+b2+c2)16 \cdot \text{Area}^2 = 2p^2q^2 + 2q^2r^2 + 2r^2p^2 - p^4 - q^4 - r^4 = 4(b^2c^2 + b^2 + c^2)

Both yield Area=12b2c2+b2+c2\text{Area} = \frac{1}{2}\sqrt{b^2c^2 + b^2 + c^2}.

Integrality Conditions

For AreaZ+\text{Area} \in \mathbb{Z}^+, we need b2c2+b2+c2=(2K)2b^2c^2 + b^2 + c^2 = (2K)^2 for some positive integer KK.

Modular arithmetic analysis of b2c2+b2+c2(mod4)b^2c^2 + b^2 + c^2 \pmod{4}:

bb paritycc parityb2c2+b2+c2(mod4)b^2c^2+b^2+c^2 \pmod{4}Square?
oddodd1+1+1=31+1+1 = 3Never
oddeven0+1+0=10+1+0 = 1Odd root, KZK \notin \mathbb{Z}
evenodd0+0+1=10+0+1 = 1Odd root, KZK \notin \mathbb{Z}
eveneven0+0+0=00+0+0 = 0Possible

Conclusion: Both bb and cc must be even. Write b=2Bb = 2B, c=2Cc = 2C with B,C1B, C \geq 1.

Then Area=4B2C2+B2+C2\text{Area} = \sqrt{4B^2C^2 + B^2 + C^2}, which must be a positive integer.

Gaussian Integer Reformulation

Note that:

(b2+1)(c2+1)=b2c2+b2+c2+1=(2Area)2+1(b^2+1)(c^2+1) = b^2c^2 + b^2 + c^2 + 1 = (2\cdot\text{Area})^2 + 1

So the problem reduces to finding when (b2+1)(c2+1)=m2+1(b^2+1)(c^2+1) = m^2 + 1 for even m=2Aream = 2 \cdot \text{Area}.

Derivation of the Pell-Based Algorithm

Generalized Pell Equation

For fixed even parameter aa (the smaller of b,cb, c), define D=a2+1D = a^2 + 1. From the relation (a2+1)(b2+1)=n2+1(a^2+1)(b^2+1) = n^2+1 where n=2Arean = 2\cdot\text{Area}:

Writing b=at+vb = at + v and n=ab+tn = ab + t (a parameterization from the code’s structure), we obtain:

v2Dt2=a2v^2 - D \cdot t^2 = -a^2

This is a generalized Pell equation.

Fundamental Pell Solution

For x2(a2+1)y2=1x^2 - (a^2+1)y^2 = 1, since D=a2+1D = a^2+1 has continued fraction [a;2a][\,a;\, \overline{2a}\,] (period 1), the fundamental solution is:

(p,q)=(2a2+1,  2a)(\,p,\, q\,) = (2a^2+1,\; 2a)

Verification: (2a2+1)2(a2+1)(2a)2=4a4+4a2+14a44a2=1(2a^2+1)^2 - (a^2+1)(2a)^2 = 4a^4+4a^2+1 - 4a^4-4a^2 = 1.

Orbit Representatives

Solutions of v2Dt2=a2v^2 - D \cdot t^2 = -a^2 form orbits under the Pell group action:

(v,t)=(vp+Dtq,  vq+tp)(v',\, t') = (v \cdot p + D \cdot t \cdot q,\; v \cdot q + t \cdot p)

Orbit representatives satisfy t0[2,a]t_0 \in [2,\, a] (even) with (a2+1)t02a2(a^2+1)t_0^2 - a^2 a perfect square.

Critical Orbit Doubling

For D=a2+1D = a^2+1, the equation x2Dy2=1x^2 - Dy^2 = -1 has solution (a,1)(a, 1), making the Pell group “twice as large.” This means:

  • Non-trivial reps (t0<at_0 < a): Both (+v0,t0)(+v_0, t_0) and (v0,t0)(-v_0, t_0) generate distinct orbits of v2Dt2=a2v^2 - Dt^2 = -a^2.
  • Trivial rep (t0=at_0 = a, v0=a2v_0 = a^2): The ±v0\pm v_0 orbits coincide (proven by checking v0=t0av_0 = t_0 \cdot a).

This is because (v0,t0)(-v_0, t_0) maps to (v0,t0)(v_0, t_0) under the Pell action if and only if v0=t0av_0 = t_0 \cdot a, which holds exactly when t0=at_0 = a.

Solution Extraction

For each valid (v,t)(v, t) in an orbit:

  1. Compute b=at+vb = a \cdot t + v (must be positive)
  2. Compute n=ab+tn = a \cdot b + t (must satisfy n2limitn \leq 2 \cdot \text{limit})
  3. Area =n/2= n / 2

Proof of Correctness

Claim: Every triangle with integral area from the problem is found exactly once.

  1. Completeness: For any valid (b,c)(b, c) with b<cb < c (both even), set a=ba = b (the smaller). Then n=2Arean = 2\cdot\text{Area} and t=nabt = n - ab satisfy v2Dt2=a2v^2 - Dt^2 = -a^2. The pair (v,t)(v, t) lies in some orbit whose representative has t0[2,a]t_0 \in [2, a], even.

  2. Non-duplication: Each orbit is iterated exactly once. The t0at_0 \leq a bound with the sign distinction ensures no orbit is visited twice.

  3. Matching known answer: Verified against brute-force for S(50)=9S(50) = 9, S(100)=75S(100) = 75, S(1000)=1092S(1000) = 1092, S(5000)=25845S(5000) = 25845, S(10000)=39696S(10000) = 39696.

Complexity Analysis

  • Orbit representative search: For each even aa from 2 to 2n\sqrt{2n}, check a/2a/2 values of t0t_0. Total: m=1n/2mn/4\sum_{m=1}^{\sqrt{n/2}} m \approx n/4 integer square root operations.
  • Orbit iteration: Each orbit has O(logn)O(\log n) solutions (exponential growth of Pell iterates). Total orbits: O(n)O(\sqrt{n}).
  • Overall: O(n)O(n) integer square root operations. For n=1010n = 10^{10}: approximately 2.5×1092.5 \times 10^9 operations.
  • C++ runtime: ~27 seconds. Python runtime: ~5 minutes.

Answer

2919133642971\boxed{2919133642971}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_390/solution.cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 lll;

/*
 * Project Euler Problem 390: Triangles with Non-Rational Sides and Integral Area
 *
 * Triangle sides: sqrt(1+b^2), sqrt(1+c^2), sqrt(b^2+c^2) for positive integers b,c.
 * Area = sqrt(b^2*c^2 + b^2 + c^2) / 2.
 * For integral area, both b,c must be even (b=2B, c=2C), and
 * Area = sqrt(4B^2*C^2 + B^2 + C^2), which must be a perfect integer.
 *
 * Equivalently, (b^2+1)(c^2+1) = (2*Area)^2 + 1.
 *
 * Approach: For each even a (smaller side param), solve the generalized Pell equation
 *   v^2 - (a^2+1)*t^2 = -a^2
 * The fundamental Pell solution for x^2-(a^2+1)y^2=1 is (2a^2+1, 2a).
 * Orbit representatives have even t0 in [2, a].
 * For each non-trivial rep (t0 < a), both +v0 and -v0 seeds generate distinct orbits.
 * The trivial rep t0=a yields only one orbit (v0=a^2).
 *
 * Given (v, t): b = a*t + v, n = a*b + t = 2*Area.
 * Constraint: n <= 2 * LIMIT.
 *
 * Complexity: O(sqrt(N) * sqrt(sqrt(N))) orbit reps + O(log N) per orbit chain.
 *
 * Answer: S(10^10) = 2919133642971
 */

int main() {
    const ll LIMIT = 10000000000LL;
    const ll N = 2 * LIMIT;
    ll ans = 0;
    ll cnt = 0;

    ll a_max = (ll)sqrtl((long double)N);
    while (a_max * a_max > N) a_max--;
    while ((a_max + 1) * (a_max + 1) <= N) a_max++;

    for (ll a = 2; a <= a_max; a += 2) {
        ll D = a * a + 1;
        ll a2 = a * a;
        ll p = 2 * a2 + 1;  // Pell fundamental x
        ll q = 2 * a;        // Pell fundamental y

        for (ll t0 = 2; t0 <= a; t0 += 2) {
            lll v2 = (lll)D * t0 * t0 - a2;
            if (v2 <= 0) continue;
            ll v0 = (ll)sqrtl((long double)v2);
            while ((lll)v0 * v0 < v2) v0++;
            while ((lll)v0 * v0 > v2) v0--;
            if ((lll)v0 * v0 != v2) continue;

            // Iterate orbit(s)
            int num_signs = (t0 < a) ? 2 : 1;
            for (int si = 0; si < num_signs; si++) {
                lll v_cur = (si == 0) ? v0 : -v0;
                lll t_cur = t0;

                while (true) {
                    if (v_cur > 0 && t_cur > 0) {
                        lll b = (lll)a * t_cur + v_cur;
                        lll nn = (lll)a * b + t_cur;
                        if (nn <= N) {
                            ans += (ll)(nn / 2);
                            cnt++;
                        } else {
                            break;
                        }
                    }
                    lll v_next = v_cur * p + (lll)D * t_cur * q;
                    lll t_next = v_cur * q + t_cur * p;
                    if (t_next > (lll)N * 100) break; // safety
                    v_cur = v_next;
                    t_cur = t_next;
                }
            }
        }
    }

    printf("S(10^10) = %lld\n", ans);
    printf("Count    = %lld\n", cnt);
    return 0;
}