All Euler problems
Project Euler

Inscribed Circles of Triangles with One Angle of 60 Degrees

Let T(n) be the number of integer-sided triangles with exactly one 60^circ angle whose incircle radius is at most n. Given that T(100)=1234, T(1000)=22767, and T(10000)=359912, find T(1053779).

Source sync May 21, 2026
Problem #0195
Level Level 12
Solved By 1,714
Languages C++, Python
Answer 75085391
Length 524 words
geometrynumber_theorymodular_arithmetic

Problem Statement

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

Let’s call an integer sided triangle with exactly one angle of \(60\) degrees a \(60\)-degree triangle.

Let \(r\) be the radius of the inscribed circle of such a \(60\)-degree triangle.

There are \(1234\) \(60\)-degree triangles for which \(r \le 100\).

Let \(T(n)\) be the number of \(60\)-degree triangles for which \(r \le n\), so

\(T(100) = 1234\), \(T(1000) = 22767\), and \(T(10000) = 359912\).

Find \(T(1053779)\).

Problem 195: Inscribed Circles of Triangles with One Angle of 60 Degrees

Mathematical Development

Theorem 1. (Incircle Radius for a 60-Degree Triangle.) Consider a triangle with sides aa, bb and included angle C=60°C = 60°. The opposite side is c=a2+b2−abc = \sqrt{a^2 + b^2 - ab}, the area is Δ=34ab\Delta = \frac{\sqrt{3}}{4}ab, and the incircle radius is

r=3 ab2(a+b+c).r = \frac{\sqrt{3}\,ab}{2(a + b + c)}.

Proof. By the law of cosines, c2=a2+b2−2abcos⁡(60°)=a2+b2−abc^2 = a^2 + b^2 - 2ab\cos(60°) = a^2 + b^2 - ab. The area is Δ=12absin⁡(60°)=34ab\Delta = \frac{1}{2}ab\sin(60°) = \frac{\sqrt{3}}{4}ab. The incircle radius satisfies r=Δ/sr = \Delta / s where s=(a+b+c)/2s = (a + b + c)/2 is the semi-perimeter, giving r=3 ab2(a+b+c)r = \frac{\sqrt{3}\,ab}{2(a + b + c)}. □\square

Theorem 2. (Integer Side Condition via Eisenstein Integers.) For c=a2−ab+b2c = \sqrt{a^2 - ab + b^2} to be a positive integer, the norm form a2−ab+b2a^2 - ab + b^2 must be a perfect square. This norm is the norm of the Eisenstein integer a+bωa + b\omega where ω=e2πi/3\omega = e^{2\pi i/3}. The ring Z[ω]\mathbb{Z}[\omega] is a unique factorization domain.

Proof. The Eisenstein integers Z[ω]\mathbb{Z}[\omega] have norm N(x+yω)=x2−xy+y2N(x + y\omega) = x^2 - xy + y^2 (equivalently x2+xy+y2x^2 + xy + y^2 under a sign change of yy). This ring is a Euclidean domain (with the norm as Euclidean function), hence a UFD. The factorization of a2−ab+b2a^2 - ab + b^2 in Z[ω]\mathbb{Z}[\omega] determines when it is a perfect square. □\square

Theorem 3. (Primitive 60-Degree Triple Parameterization.) All primitive integer triples (a,b,c)(a, b, c) with c2=a2−ab+b2c^2 = a^2 - ab + b^2, gcd⁡(a,b)=1\gcd(a, b) = 1, a,b,c>0a, b, c > 0, fall into two families parameterized by coprime integers m>n>0m > n > 0:

Family 1 (m≢n(mod3)m \not\equiv n \pmod{3}):

a=2mn+n2,b=m2−n2,c=m2−mn+n2.a = 2mn + n^2, \quad b = m^2 - n^2, \quad c = m^2 - mn + n^2.

Family 2 (m≡n(mod3)m \equiv n \pmod{3}):

a=2mn+n23,b=m2−n23,c=m2−mn+n23.a = \frac{2mn + n^2}{3}, \quad b = \frac{m^2 - n^2}{3}, \quad c = \frac{m^2 - mn + n^2}{3}.

In both families, one must also check positivity (b>0b > 0 requires m>nm > n) and primitivity (gcd⁡(a,b)=1\gcd(a, b) = 1).

Proof. Factor a2−ab+b2=(a−bω)(a−bωˉ)a^2 - ab + b^2 = (a - b\omega)(a - b\bar{\omega}) in Z[ω]\mathbb{Z}[\omega]. For this to equal c2c^2, the ideal factorization must pair up. Using the UFD property, write a−bω=ϵ⋅α2a - b\omega = \epsilon \cdot \alpha^2 for some unit ϵ\epsilon and Eisenstein integer α=m+nω\alpha = m + n\omega. Expanding α2=(m+nω)2=m2+2mnω+n2ω2=(m2−n2)+(2mn−n2)ω\alpha^2 = (m + n\omega)^2 = m^2 + 2mn\omega + n^2\omega^2 = (m^2 - n^2) + (2mn - n^2)\omega (using ω2=−1−ω\omega^2 = -1 - \omega, so n2ω2=−n2−n2ωn^2\omega^2 = -n^2 - n^2\omega, giving (m2−n2)+(2mn−n2)ω(m^2 - n^2) + (2mn - n^2)\omega). Matching real and ω\omega-components and accounting for the units {1,ω,ω2,−1,−ω,−ω2}\{1, \omega, \omega^2, -1, -\omega, -\omega^2\} yields the two families. The condition m≡n(mod3)m \equiv n \pmod{3} causes all three of a,b,ca, b, c (before division) to be divisible by 3, producing Family 2 after dividing by 3. □\square

Lemma 1. (Scaling.) For each primitive triple (a0,b0,c0)(a_0, b_0, c_0) with primitive incircle radius r0r_0, the scaled triple (ka0,kb0,kc0)(ka_0, kb_0, kc_0) has incircle radius kr0kr_0. The number of valid scaled copies with r≤Rr \leq R is ⌊R/r0⌋\lfloor R / r_0 \rfloor.

Proof. r(ka0,kb0,kc0)=3⋅k2a0b02k(a0+b0+c0)=k⋅r0r(ka_0, kb_0, kc_0) = \frac{\sqrt{3} \cdot k^2 a_0 b_0}{2k(a_0 + b_0 + c_0)} = k \cdot r_0. □\square

Lemma 2. (Multiplicity.) Each unordered pair {a,b}\{a, b\} with a≠ba \neq b gives one triangle (the 60-degree angle is between sides aa and bb). If a=ba = b, the triangle is equilateral with all angles equal to 60 degrees, counted once. Additionally, (a,b)(a, b) and (b,a)(b, a) represent the same triangle, so each primitive triple with a≠ba \neq b contributes twice in the parameterization (once as (a,b)(a, b) and once as (b,a)(b, a)).

Proof. The 60-degree angle is uniquely determined by the law of cosines given c2=a2−ab+b2c^2 = a^2 - ab + b^2. The triangle is unchanged by swapping aa and bb. □\square

Editorial

The heavy algebra is already done in the parameterization step, so the algorithm only has to enumerate coprime parameter pairs. For coprime integers p > q > 0, the primitive triangle falls into one of two cases depending on whether p-q is divisible by 3. The key simplification is that the primitive inradius collapses to

r0=3 pq2orr0=3 pq6,r_0 = \frac{\sqrt{3}\,pq}{2} \quad\text{or}\quad r_0 = \frac{\sqrt{3}\,pq}{6},

so once a primitive triple is known, the number of scaled copies with radius at most R is just a floor division in terms of pq.

That turns the search into a lattice-point count over coprime pairs. For each q, there is a simple upper bound on p coming from the larger of the two radius formulas, so the double loop stays manageable. Each admissible pair contributes either floor((2R/\sqrt3)/(pq)) or floor((6R/\sqrt3)/(pq)), and the sum of those contributions is exactly T(R).

Pseudocode

Set R = 1053779.
Precompute the two radius limits 2R / sqrt(3) and 6R / sqrt(3).

For each q from 1 up to the point where pq can no longer fit the larger limit:
    let p run from q + 1 up to floor((6R / sqrt(3)) / q);
    skip the pair if gcd(p, q) is not 1.

    If p - q is divisible by 3:
        add floor((6R / sqrt(3)) / (p q)) to the answer.
    Otherwise:
        add floor((2R / sqrt(3)) / (p q)) to the answer.

Return the final count.

Complexity Analysis

  • Time: O(Rlog⁡R)O(R \log R) arithmetic operations. The outer loop over q runs to O(R)O(\sqrt{R}), and for each q the inner loop runs to O(R/q)O(R/q), giving the harmonic-series total.
  • Space: O(1)O(1) beyond the loop variables.

Answer

75085391\boxed{75085391}

Code

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

C++ project_euler/problem_195/solution.cpp
#include <cassert>
#include <cmath>
#include <iostream>
#include <numeric>

using namespace std;

long long gcd_ll(long long a, long long b) {
    while (b != 0) {
        long long t = a % b;
        a = b;
        b = t;
    }
    return a;
}

long long count_triangles(long long limit) {
    const long double sqrt3 = sqrt(static_cast<long double>(3.0));
    const long double limit_plain = 2.0L * limit / sqrt3;
    const long double limit_div3 = 6.0L * limit / sqrt3;
    const long long q_max = static_cast<long long>(sqrt(limit_div3)) + 2;
    long long total = 0;

    for (long long q = 1; q <= q_max; ++q) {
        long long p_max = static_cast<long long>(limit_div3 / q);
        for (long long p = q + 1; p <= p_max; ++p) {
            if (gcd_ll(p, q) != 1) {
                continue;
            }
            long long product = p * q;
            if ((p - q) % 3 == 0) {
                total += static_cast<long long>(limit_div3 / product);
            } else {
                total += static_cast<long long>(limit_plain / product);
            }
        }
    }

    return total;
}

int main() {
    assert(count_triangles(100) == 1234);
    assert(count_triangles(1000) == 22767);
    assert(count_triangles(10000) == 359912);

    long long answer = count_triangles(1053779);
    assert(answer == 75085391LL);
    cout << answer << '\n';
    return 0;
}