All Euler problems
Project Euler

Pythagorean Quadrilaterals

A quadrilateral ABCD inscribed in a circle of radius r is called pythagorean if its sides a, b, c, d satisfy a^2 + b^2 + c^2 + d^2 = 8r^2. A pythagorean lattice grid quadrilateral additionally requ...

Source sync Apr 19, 2026
Problem #0723
Level Level 35
Solved By 208
Languages C++, Python
Answer 1395793419248
Length 397 words
number_theorygeometrymodular_arithmetic

Problem Statement

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

A pythagorean triangle with catheti \(a\) and \(b\) and hypotenuse \(c\) is characterized by the well-known equation \(a^2+b^2=c^2\). However, this can also be formulated differently:

When inscribed into a circle with radius \(r\), a triangle with sides \(a\), \(b\) and \(c\) is pythagorean, if and only if \(a^2+b^2+c^2=8\, r^2\).

Analogously, we call a quadrilateral \(ABCD\) with sides \(a\), \(b\), \(c\) and \(d\), inscribed in a circle with radius \(r\), a pythagorean quadrilateral, if \(a^2+b^2+c^2+d^2=8\, r^2\).

We further call a pythagorean quadrilateral a pythagorean lattice grid quadrilateral, if all four vertices are lattice grid points with the same distance \(r\) from the origin \(O\) (which then happens to be the centre of the circumcircle).

Let \(f(r)\) be the number of different pythagorean lattice grid quadrilaterals for which the radius of the circumcircle is \(r\). For example \(f(1)=1\), \(f(\sqrt 2)=1\), \(f(\sqrt 5)=38\) and \(f(5)=167\).

Two of the pythagorean lattice grid quadrilaterals with \(r=\sqrt 5\) are illustrated below:

PIC

PIC

Let \(\displaystyle S(n)=\sum _{d \mid n} f(\sqrt d)\). For example, \(S(325)=S(5^2 \cdot 13)=f(1)+f(\sqrt 5)+f(5)+f(\sqrt {13})+f(\sqrt {65})+f(5\sqrt {13})=2370\) and \(S(1105)=S(5\cdot 13 \cdot 17)=5535\).

Find \(S(1411033124176203125)=S(5^6 \cdot 13^3 \cdot 17^2 \cdot 29 \cdot 37 \cdot 41 \cdot 53 \cdot 61)\).

Problem 723: Pythagorean Quadrilaterals

Mathematical Foundation

Theorem 1 (Lattice Points on Circles). The number of lattice points on the circle x2+y2=dx^2 + y^2 = d is

r2(d)=4kdχ(k)r_2(d) = 4\sum_{k \mid d} \chi(k)

where χ\chi is the non-principal Dirichlet character modulo 4, defined by χ(k)=0\chi(k) = 0 if kk is even, χ(k)=(1)(k1)/2\chi(k) = (-1)^{(k-1)/2} if kk is odd.

Proof. This is a classical result in algebraic number theory. In the Gaussian integers Z[i]\mathbb{Z}[i], we have r2(d)=4(d1(d)d3(d))r_2(d) = 4(d_1(d) - d_3(d)) where dj(d)d_j(d) counts divisors of dd congruent to j(mod4)j \pmod{4}. This equals 4kdχ(k)4\sum_{k \mid d} \chi(k) by definition of χ\chi. The factor 4 accounts for the four units {±1,±i}\{\pm 1, \pm i\} in Z[i]\mathbb{Z}[i]. \square

Theorem 2 (Pythagorean Chord Condition). Let P1,P2,P3,P4P_1, P_2, P_3, P_4 be four points on a circle of radius d\sqrt{d}, with consecutive chord lengths ai=PiPi+1a_i = |P_i P_{i+1}| (indices mod 4). Write Pj=(dcosϕj,dsinϕj)P_j = (\sqrt{d}\cos\phi_j, \sqrt{d}\sin\phi_j). Then the pythagorean condition ai2=8d\sum a_i^2 = 8d is equivalent to

i=14cos(ϕi+1ϕi)=0.\sum_{i=1}^{4} \cos(\phi_{i+1} - \phi_i) = 0.

Proof. By the chord length formula, ai2=PiPi+12=2d(1cos(ϕi+1ϕi))a_i^2 = |P_i - P_{i+1}|^2 = 2d(1 - \cos(\phi_{i+1}-\phi_i)). Summing over all four sides:

ai2=2d(4i=14cos(ϕi+1ϕi)).\sum a_i^2 = 2d\left(4 - \sum_{i=1}^{4}\cos(\phi_{i+1}-\phi_i)\right).

Setting this equal to 8d8d gives 4cos(ϕi+1ϕi)=44 - \sum \cos(\phi_{i+1}-\phi_i) = 4, i.e., cos(ϕi+1ϕi)=0\sum \cos(\phi_{i+1}-\phi_i) = 0. \square

Lemma 1 (Gaussian Integer Formulation). Let the lattice points on x2+y2=dx^2+y^2=d correspond to Gaussian integers zjz_j with zj2=d|z_j|^2 = d. Write zj+1/zj=eiαjz_{j+1}/z_j = e^{i\alpha_j} (a unit-modulus complex number). The pythagorean condition becomes j=14Re(zj+1zj)/d=0\sum_{j=1}^{4} \operatorname{Re}(z_{j+1}\overline{z_j})/d = 0, i.e.,

j=14Re(zj+1zj)=0.\sum_{j=1}^{4} \operatorname{Re}(z_{j+1}\overline{z_j}) = 0.

Proof. Since cos(ϕj+1ϕj)=Re(ei(ϕj+1ϕj))=Re(zj+1zj)/zjzj+1=Re(zj+1zj)/d\cos(\phi_{j+1}-\phi_j) = \operatorname{Re}(e^{i(\phi_{j+1}-\phi_j)}) = \operatorname{Re}(z_{j+1}\overline{z_j})/|z_j||z_{j+1}| = \operatorname{Re}(z_{j+1}\overline{z_j})/d, Theorem 2 gives the result immediately. \square

Theorem 3 (Multiplicative Structure). The function g(d):=f(d)g(d) := f(\sqrt{d}) depends only on the prime factorization of dd through the function r2(d)r_2(d) and a polynomial-time counting procedure on the lattice points. Since S(n)=dng(d)S(n) = \sum_{d \mid n} g(d) is a Dirichlet convolution, and n=561331722937415361n = 5^6 \cdot 13^3 \cdot 17^2 \cdot 29 \cdot 37 \cdot 41 \cdot 53 \cdot 61 consists entirely of primes 1(mod4)\equiv 1 \pmod{4}, the function r2r_2 is multiplicative on such inputs and the computation decomposes over prime powers.

Proof. For primes p1(mod4)p \equiv 1\pmod{4}, pp splits in Z[i]\mathbb{Z}[i] as p=ππˉp = \pi\bar{\pi}. The lattice points on x2+y2=pex^2+y^2 = p^e are determined by the factorizations pe=πaπˉbup^e = \pi^a \bar{\pi}^b \cdot u with a+b=ea+b=e and uu a unit. The number of such points is r2(pe)=4(e+1)r_2(p^e) = 4(e+1). Since nn has only primes 1(mod4)\equiv 1\pmod 4, the divisor structure and lattice point counts factor over the prime powers. \square

Editorial

Count pythagorean lattice grid quadrilaterals inscribed in circles. S(n) = sum_{d|n} f(sqrt(d)) where f(r) counts distinct pythagorean lattice quadrilaterals with circumradius r. We n is given in factored form. We then iterate over each divisor d of n. Finally, enumerate all ordered 4-tuples of distinct points on the circle.

Pseudocode

n is given in factored form
for each divisor d of n
Compute f(sqrt(d)) = number of pythagorean lattice quadrilaterals
on circle x^2 + y^2 = d
Enumerate all ordered 4-tuples of distinct points on the circle
satisfying the pythagorean condition, then quotient by symmetries
Account for rotational (order 4) and reflective (order 2) symmetry
of the quadrilateral; subtract degenerate cases
Factor d and enumerate representations x^2 + y^2 = d
using Gaussian integer factorization

Complexity Analysis

  • Time: The number of divisors of nn is τ(n)=(6+1)(3+1)(2+1)(1+1)5=2688\tau(n) = (6+1)(3+1)(2+1)(1+1)^5 = 2688. For each divisor dd, computing f(d)f(\sqrt{d}) requires enumerating r2(d)r_2(d) lattice points and checking O(r2(d)4)O(r_2(d)^4) quadruples (reducible to O(r2(d)2)O(r_2(d)^2) via the two-sum technique on Re(zj+1zj)\operatorname{Re}(z_{j+1}\overline{z_j})). Since r2(d)=O(dϵ)r_2(d) = O(d^\epsilon) for any ϵ>0\epsilon > 0, and each divisor dnd \le n, the per-divisor cost is polynomial in r2(d)r_2(d). Total: O(τ(n)R2)O(\tau(n) \cdot R^2) where R=maxdr2(d)R = \max_d r_2(d).
  • Space: O(R)O(R) for storing lattice points per divisor.

Answer

1395793419248\boxed{1395793419248}

Code

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

C++ project_euler/problem_723/solution.cpp
#include <bits/stdc++.h>
using namespace std;

/*
 * Problem 723: Pythagorean Quadrilaterals
 *
 * Count pythagorean lattice grid quadrilaterals inscribed in circles.
 * A quadrilateral ABCD with vertices on x^2+y^2=d is pythagorean if
 * a^2 + b^2 + c^2 + d^2 = 8d (sides squared sum to 8r^2).
 *
 * S(n) = sum_{d|n} f(sqrt(d))
 *
 * The approach uses:
 * 1. Enumerate lattice points on circle via sum-of-two-squares
 * 2. Count valid quadrilaterals satisfying the pythagorean condition
 * 3. Multiplicative structure for the large input
 */

vector<pair<int,int>> lattice_points(int d) {
    vector<pair<int,int>> pts;
    int s = (int)sqrt((double)d) + 1;
    for (int x = -s; x <= s; x++) {
        int y2 = d - x*x;
        if (y2 < 0) continue;
        int y = (int)round(sqrt((double)y2));
        if (y*y == y2) {
            pts.push_back({x, y});
            if (y > 0) pts.push_back({x, -y});
        }
    }
    return pts;
}

int main() {
    // Verify small cases
    for (int d : {1, 2, 5}) {
        auto pts = lattice_points(d);
        int n = pts.size();
        int count = 0;
        for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++) if (j != i)
        for (int k = 0; k < n; k++) if (k != i && k != j)
        for (int l = 0; l < n; l++) if (l != i && l != j && l != k) {
            auto [x1,y1] = pts[i]; auto [x2,y2] = pts[j];
            auto [x3,y3] = pts[k]; auto [x4,y4] = pts[l];
            long long a2 = (long long)(x1-x2)*(x1-x2) + (long long)(y1-y2)*(y1-y2);
            long long b2 = (long long)(x2-x3)*(x2-x3) + (long long)(y2-y3)*(y2-y3);
            long long c2 = (long long)(x3-x4)*(x3-x4) + (long long)(y3-y4)*(y3-y4);
            long long d2 = (long long)(x4-x1)*(x4-x1) + (long long)(y4-y1)*(y4-y1);
            if (a2 + b2 + c2 + d2 == 8LL * d) count++;
        }
        printf("f(sqrt(%d)) = %d\n", d, count / 8);
    }
    return 0;
}