All Euler problems
Project Euler

Investigating the Torricelli Point of a Triangle

Let ABC be a triangle with all interior angles less than 120 degrees. Let T be the Torricelli (Fermat) point of the triangle, and let p = |AT|, q = |BT|, r = |CT|. It can be shown that p, q, r sati...

Source sync May 21, 2026
Problem #0143
Level Level 08
Solved By 3,265
Languages C++, Python
Answer 30758397
Length 481 words
geometrynumber_theorygraph

Problem Statement

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

Let \(ABC\) be a triangle with all interior angles being less than \(120\) degrees. Let \(X\) be any point inside the triangle and let \(XA = p\), \(XC = q\), and \(XB = r\). co

Fermat challenged Torricelli to find the position of \(X\) such that \(p + q + r\) was minimised.

Torricelli was able to prove that if equilateral triangles \(AOB\), \(BNC\) and \(AMC\) are constructed on each side of triangle \(ABC\), the circumscribed circles of \(AOB\), \(BNC\), and \(AMC\) will intersect at a single point, \(T\), inside the triangle. Moreover he proved that \(T\), called the Torricelli/Fermat point, minimises \(p + q + r\). Even more remarkable, it can be shown that when the sum is minimised, \(AN = BM = CO = p + q + r\) and that \(AN\), \(BM\) and \(CO\) also intersect at \(T\).

PIC

If the sum is minimised and \(a, b, c, p, q\) and \(r\) are all positive integers we shall call triangle \(ABC\) a Torricelli triangle. For example, \(a = 399\), \(b = 455\), \(c = 511\) is an example of a Torricelli triangle, with \(p + q + r = 784\).

Find the sum of all distinct values of \(p + q + r \le 120000\) for Torricelli triangles.

Problem 143: Investigating the Torricelli Point of a Triangle

Mathematical Development

Theorem 1. At the Torricelli point T of a triangle with all angles less than 120°120°, each pair of vertices subtends an angle of exactly 120°120° at T. In particular, for side c=∣AB∣c = |AB|:

c2=p2+pq+q2c^2 = p^2 + pq + q^2

Proof. The Torricelli point minimizes ∣AT∣+∣BT∣+∣CT∣|AT| + |BT| + |CT| and, when all angles are less than 120°120°, lies in the interior with ∠ATB=∠BTC=∠ATC=120°\angle ATB = \angle BTC = \angle ATC = 120°. Applying the law of cosines to triangle ATB:

c2=p2+q2−2pqcos⁡(120°)=p2+q2−2pq⋅(−12)=p2+pq+q2c^2 = p^2 + q^2 - 2pq\cos(120°) = p^2 + q^2 - 2pq \cdot (-\tfrac{1}{2}) = p^2 + pq + q^2

The other two equations follow by cyclic symmetry. □\square

Definition. A pair (u,v)(u, v) with u≥v≥1u \geq v \geq 1 is called 120-compatible if u2+uv+v2u^2 + uv + v^2 is a perfect square.

Theorem 2. All primitive 120-compatible pairs (with gcd⁡(u,v)=1\gcd(u,v) = 1) are parametrized by:

u=m2−n2,v=2mn+n2u = m^2 - n^2, \quad v = 2mn + n^2

where m>n≥1m > n \geq 1, gcd⁡(m,n)=1\gcd(m, n) = 1, and m≢n(mod3)m \not\equiv n \pmod{3}. The corresponding square root is s=m2+mn+n2s = m^2 + mn + n^2.

Proof. We verify: u2+uv+v2=(m2−n2)2+(m2−n2)(2mn+n2)+(2mn+n2)2u^2 + uv + v^2 = (m^2 - n^2)^2 + (m^2 - n^2)(2mn + n^2) + (2mn + n^2)^2.

Expanding each term:

  • (m2−n2)2=m4−2m2n2+n4(m^2 - n^2)^2 = m^4 - 2m^2 n^2 + n^4
  • (m2−n2)(2mn+n2)=2m3n+m2n2−2mn3−n4(m^2 - n^2)(2mn + n^2) = 2m^3 n + m^2 n^2 - 2mn^3 - n^4
  • (2mn+n2)2=4m2n2+4mn3+n4(2mn + n^2)^2 = 4m^2 n^2 + 4mn^3 + n^4

Summing: m4+2m3n+3m2n2+2mn3+n4=(m2+mn+n2)2m^4 + 2m^3 n + 3m^2 n^2 + 2mn^3 + n^4 = (m^2 + mn + n^2)^2.

For primitivity: if 3∣(m−n)3 \mid (m - n), then m≡n(mod3)m \equiv n \pmod{3}, which implies u=m2−n2≡0(mod3)u = m^2 - n^2 \equiv 0 \pmod{3} and v=2mn+n2≡2n2+n2=3n2≡0(mod3)v = 2mn + n^2 \equiv 2n^2 + n^2 = 3n^2 \equiv 0 \pmod{3}, so gcd⁡(u,v)≥3\gcd(u,v) \geq 3, violating primitivity. The converse (that gcd⁡(m,n)=1\gcd(m,n) = 1 and m≢n(mod3)m \not\equiv n \pmod{3} imply gcd⁡(u,v)=1\gcd(u,v) = 1) can be verified by checking that any common prime factor of uu and vv must divide m2+mn+n2=sm^2 + mn + n^2 = s, and showing this leads to a contradiction using the Eisenstein integer norm. □\square

Lemma 1. All 120-compatible pairs are of the form (ku,kv)(ku, kv) where (u,v)(u,v) is a primitive pair and k≥1k \geq 1.

Proof. If (U,V)(U, V) is 120-compatible with g=gcd⁡(U,V)g = \gcd(U, V), then U2+UV+V2=g2(u2+uv+v2)U^2 + UV + V^2 = g^2(u^2 + uv + v^2) where u=U/gu = U/g, v=V/gv = V/g, gcd⁡(u,v)=1\gcd(u,v) = 1. Since u2+uv+v2u^2 + uv + v^2 is a perfect square (being g−2g^{-2} times a perfect square), (u,v)(u,v) is a primitive 120-compatible pair. □\square

Lemma 2. A valid Torricelli triple (p,q,r)(p, q, r) corresponds to a 3-clique in the graph GG whose vertices are positive integers and whose edges connect all 120-compatible pairs.

Proof. The three Torricelli equations require (p,q)(p,q), (p,r)(p,r), and (q,r)(q,r) to each be 120-compatible. This is exactly the condition that {p,q,r}\{p, q, r\} forms a clique of size 3 in GG. □\square

Editorial

The hard part is not checking a single triple, but generating only the pairs that could possibly belong to one. The parametrization of primitive 120-compatible pairs gives exactly that: every edge in the compatibility graph comes from a primitive pair generated by (m,n)(m,n), together with all of its positive multiples that still fit under the perimeter bound.

The implementation stores this graph in a directed way. For every compatible pair, the larger endpoint keeps the smaller endpoint in an adjacency set. Once that graph is built, a Torricelli triple (p,q,r)(p,q,r) is simply a 3-clique: pp must be compatible with qq and rr, and qq must also be compatible with rr. Iterating over the adjacency lists therefore becomes a direct clique search, and every valid perimeter sum p+q+r≤120000p+q+r \le 120000 is inserted into a set so that repeated constructions are counted only once.

Pseudocode

Set the perimeter limit to 120000 and create an adjacency structure `smaller`.

Generate primitive 120-compatible pairs from parameters $m>n$:
    Skip pairs that are not coprime or have $m \equiv n \pmod 3$.
    Form the primitive pair $(u,v)$.
    For each positive multiple that still satisfies $u+v \le 120000$:
        Store the smaller endpoint in the adjacency set of the larger endpoint.

Create an empty set of valid perimeter sums.

For each largest value $p$ in the graph:
    For each compatible $q<p$ attached to $p$:
        Discard this branch if $p+q$ already leaves no room for a positive $r$.
        Look through all $r<q$ that are attached to $q$.
        Whenever $r$ is also attached to $p$, the three values form a clique.
        Record $p+q+r$ if it does not exceed the limit.

Return the sum of the distinct recorded perimeter sums.

Complexity Analysis

  • Time: Pair generation is O(L⋅M)O(L \cdot M) where MM is the number of primitive pairs with parameters up to L\sqrt{L}, which is O(L/log⁡L)O(L / \log L) by density estimates for Eisenstein primes. Clique enumeration depends on graph density; in practice, the neighbor sets are small enough that intersection is fast. Overall: O(L3/2)O(L^{3/2}) in the worst case.
  • Space: O(L+E)O(L + E) where EE is the number of 120-compatible pairs, for storing the adjacency lists.

Answer

30758397\boxed{30758397}

Code

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

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

int main() {
    // Problem 143: Torricelli point distances
    // Find sum of all distinct p+q+r <= 120000
    // where all three pair-wise expressions u^2+uv+v^2 are perfect squares.
    //
    // Primitive 120-compatible pairs: u = m^2-n^2, v = 2mn+n^2
    // with m > n >= 1, gcd(m,n) = 1, (m-n) % 3 != 0.
    // Then u^2+uv+v^2 = (m^2+mn+n^2)^2.
    // All solutions are k*(u,v) for k >= 1.

    const int LIMIT = 120000;

    // smaller[u] = sorted vector of v < u compatible with u
    vector<vector<int>> smaller(LIMIT + 1);

    auto addPrimitive = [&](int a, int b) {
        if (a <= 0 || b <= 0) return;
        int u = max(a, b), v = min(a, b);
        for (int k = 1; (long long)k * (u + v) <= LIMIT; k++) {
            smaller[k * u].push_back(k * v);
        }
    };

    for (int m = 2; (long long)m * m < LIMIT; m++) {
        for (int n = 1; n < m; n++) {
            if (__gcd(m, n) != 1) continue;
            if ((m - n) % 3 == 0) continue;
            int a = m * m - n * n;
            int b = 2 * m * n + n * n;
            addPrimitive(a, b);
        }
    }

    // Sort and deduplicate each adjacency list
    for (int i = 0; i <= LIMIT; i++) {
        sort(smaller[i].begin(), smaller[i].end());
        smaller[i].erase(unique(smaller[i].begin(), smaller[i].end()), smaller[i].end());
    }

    // Find triangles
    set<int> valid_sums;

    for (int p = 1; p <= LIMIT; p++) {
        if (smaller[p].empty()) continue;
        // For quick lookup, use a set for smaller[p]
        unordered_set<int> sp_set(smaller[p].begin(), smaller[p].end());

        for (int q : smaller[p]) {
            int max_r = LIMIT - p - q;
            if (max_r <= 0) continue;

            for (int r : smaller[q]) {
                if (r >= q) continue;
                if (r > max_r) continue;
                if (sp_set.count(r)) {
                    valid_sums.insert(p + q + r);
                }
            }
        }
    }

    long long ans = 0;
    for (int s : valid_sums) ans += s;
    cout << ans << endl;

    return 0;
}