Problem 142: Perfect Square Collection

View on Project Euler

Project Euler Problem 142 Solution

EulerSolve provides an optimized solution for Project Euler Problem 142, Perfect Square Collection, with C++, Python, Java, and a step-by-step mathematical explanation.

Problem Summary We seek the smallest value of \(x+y+z\) with \(x \gt y \gt z \gt 0\) such that all six pairwise sums and differences $$x+y,\quad x-y,\quad x+z,\quad x-z,\quad y+z,\quad y-z$$ are perfect squares. A direct search over triples \((x,y,z)\) is far too loose, because each candidate would still need six square tests and there is no obvious numerical range for the three variables separately. The implementations therefore search in a more structured space: instead of guessing \(x\), \(y\), and \(z\) directly, they guess a small set of square quantities from which every other required square is forced. That is the key mathematical simplification. Mathematical Approach The six square conditions are strongly linked. Once the relations between them are written down explicitly, the problem collapses to a search over three squares rather than three unrestricted integers. Naming the Six Square Quantities Let $$A=x+y,\qquad B=x-y,\qquad C=x+z,\qquad D=x-z,\qquad E=y+z,\qquad F=y-z.$$ Every one of \(A,B,C,D,E,F\) must be a perfect square. Because \(x \gt y \gt z \gt 0\), they satisfy the order relations $$A \gt C \gt D \gt 0,\qquad E \gt F \gt 0,\qquad B \gt 0.$$ These six quantities are not independent....

Detailed mathematical approach

Problem Summary

We look for integers \(x\gt y\gt z\gt0\) for which all six numbers \(x+y\), \(x-y\), \(x+z\), \(x-z\), \(y+z\) and \(y-z\) are perfect squares, and we must find the smallest possible value of \(x+y+z\). The statement gives no example and no checkpoint value. [1]

The whole solution in one sentence: we write \(x+y=i^2\), \(x+z=j^2\) and \(x-z=k^2\), so that the other three numbers become \(i^2-j^2\), \(i^2-k^2\) and \(j^2+k^2-i^2\), search through \(i=4,5,6,\dots\) and the pairs \(j\gt k\) of equal parity until these three are positive squares too, and use \(i^2\lt x+y+z\lt\frac32 i^2\) to check that no later \(i\) gives a smaller sum.

Mathematical Approach

Six numbers built from three unknowns cannot be independent. We use this to reduce the problem to three squares, test the reduction on a complete example, and then ask in which order a search meets the solutions.

1. Small cases: one pair at a time

For two numbers \(p\gt q\gt0\), both \(p+q=s^2\) and \(p-q=t^2\) are squares exactly when

$$p=\frac{s^2+t^2}{2},\qquad q=\frac{s^2-t^2}{2}$$

with \(s\gt t\ge1\), both odd or both even, so that the halves are integers. Such square pairs are common: with \(p\lt30\) they are \((5,4)\), \((10,6)\), \((13,12)\), \((17,8)\), \((20,16)\), \((25,24)\), \((26,10)\) and \((29,20)\). Our problem asks for three numbers such that all three pairs \((x,y)\), \((x,z)\) and \((y,z)\) are square pairs. Two of the three pairs are still easy to arrange. The smallest \(x\) that forms square pairs with two smaller numbers is \(x=65\): from \(130=11^2+3^2=9^2+7^2\) it gets the partners \(56\) and \(16\), so \(x\pm y\) are \(121\) and \(9\), and \(x\pm z\) are \(81\) and \(49\). But \(y+z=72\) and \(y-z=40\) are not squares. The real difficulty is that the third pair must work at the same time.

2. Six numbers, three unknowns

We name the six numbers

$$\begin{aligned}A&=x+y, & B&=x-y,\\ C&=x+z, & D&=x-z,\\ E&=y+z, & F&=y-z.\end{aligned}$$

Adding and subtracting the definitions gives \(A+B=C+D=2x\), \(E+F=2y\) and \(C-D=E-F=2z\), and from these

$$\begin{aligned}F&=A-C,\\ E&=A-D,\\ B&=C+D-A.\end{aligned}$$

So \(A\), \(C\) and \(D\) determine the other three numbers, and \(x\gt y\gt z\gt0\) gives \(A\gt C\gt D\gt0\). For the triple \((65,56,16)\) of Section 1 we have \(A=121\), \(C=81\) and \(D=49\), and indeed \(F=40\), \(E=72\) and \(B=9\): the two numbers that fail are the differences \(A-C\) and \(A-D\).

3. Three squares decide everything

Put \(A=i^2\), \(C=j^2\) and \(D=k^2\). The key claim is that the solutions of the problem correspond one to one to the triples of integers \(i\gt j\gt k\ge1\) with \(j\equiv k\pmod 2\) for which the three numbers

$$\begin{aligned}F&=i^2-j^2,\\ E&=i^2-k^2,\\ B&=j^2+k^2-i^2\end{aligned}$$

are positive squares, the solution belonging to such a triple being

$$\begin{aligned}x&=\frac{j^2+k^2}{2},\\ y&=i^2-x,\\ z&=\frac{j^2-k^2}{2}.\end{aligned}$$

Proof. Given a solution, put \(i=\sqrt{x+y}\), \(j=\sqrt{x+z}\) and \(k=\sqrt{x-z}\). Then \(i\gt j\gt k\ge1\) because \(A\gt C\gt D\gt0\); the three numbers above equal \(y-z\), \(y+z\) and \(x-y\) by Section 2, so they are positive squares; and \(j^2+k^2=2x\) is even. A square is even exactly when its root is even, [2] so \(j\) and \(k\) have the same parity. Conversely, take such \(i\), \(j\), \(k\). The parity condition makes \(j^2+k^2\) and \(j^2-k^2\) even, so \(x\), \(y\) and \(z\) are integers, and substituting them gives

$$\begin{aligned}x+y&=i^2, & x-y&=B,\\ x+z&=j^2, & x-z&=k^2,\\ y+z&=E, & y-z&=F.\end{aligned}$$

All six numbers are squares, and \(x-y=B\gt0\), \(y-z=F\gt0\) and \(z\gt0\), which holds because \(j\gt k\), give \(x\gt y\gt z\gt0\). The two constructions undo each other, so the correspondence is one to one. \(\square\)

4. Two right triangles with one hypotenuse

The first two conditions have a geometric meaning. \(F\) is a square \(w^2\) exactly when \(i^2=j^2+w^2\), that is, when \(j\) and \(w\) are the legs of a right triangle with integer sides and hypotenuse \(i\), a Pythagorean triple. In the same way \(E=v^2\) means \(i^2=k^2+v^2\). So \(i\) must be the hypotenuse of two such triangles, one with the leg \(j\) and one with the leg \(k\), and the last condition asks that \(B\) be a positive square \(u^2\). Since \(B=k^2-w^2\), positivity says that \(k\) is longer than the other leg \(w\) of the triangle of \(j\). A triple is primitive if its sides have no common factor greater than \(1\); up to the order of the legs, Euclid's formula \((m^2-n^2,\,2mn,\,m^2+n^2)\) gives all of them, with coprime \(m\gt n\ge1\) of which exactly one is even (\(m=2\), \(n=1\) give \((3,4,5)\)). Every triple is a multiple of a primitive one, and one hypotenuse may belong to several triples. [3]

5. A worked example: \(i=697\) and \(i=1394\)

The number \(697=17\cdot41\) is the hypotenuse of four right triangles with integer sides, with the legs \(153\) and \(680\), \(185\) and \(672\), \(328\) and \(615\), and \(455\) and \(528\). So exactly eight values of \(j\) make \(697^2-j^2\) a square, and among all pairs \(j\gt k\) of them only \((j,k)=(680,185)\) makes \(B\) a positive square:

$$\begin{aligned}F&=697^2-680^2=153^2,\\ E&=697^2-185^2=672^2,\\ B&=680^2+185^2-697^2=104^2,\end{aligned}$$

that is, \(F=23409\), \(E=451584\) and \(B=10816\). So all six numbers \(A,\dots,F\) are squares, but \(680\) is even and \(185\) is odd. Then \(2x=680^2+185^2=496625\) is odd, and Section 3 gives the halves \(x=496625/2\), \(y=474993/2\) and \(z=428175/2\) instead of integers. The search never even forms this pair, because it pairs \(j\) only with values \(k\) of the same parity. Doubling repairs the parity. The legs of \(1394=2\cdot697\) are the doubled legs of \(697\), and the pair \((j,k)=(1360,370)\) has \(F=306^2\), \(E=1344^2\) and \(B=208^2\), now with \(j\) and \(k\) both even. Section 3 gives

$$\begin{aligned}x&=\frac{1360^2+370^2}{2}=993250,\\ z&=\frac{1360^2-370^2}{2}=856350,\end{aligned}$$

and \(y=1394^2-x=949986\), four times the halves above. All six numbers are squares:

$$\begin{aligned}x+y&=1943236=1394^2,\\ x-y&=43264=208^2,\\ x+z&=1849600=1360^2,\\ x-z&=136900=370^2,\\ y+z&=1806336=1344^2,\\ y-z&=93636=306^2.\end{aligned}$$

So \((993250,949986,856350)\) is a solution, with \(x+y+z=2799586\). It is not the smallest one, but it shows every step of the method, and Section 7 uses it as a bound.

6. The box behind a solution

Write \(B=u^2\), \(E=v^2\) and \(F=w^2\). Since \(B+E=C\), \(B+F=D\) and \(B+E+F=A\) by Section 2,

$$\begin{aligned}u^2+v^2&=j^2,\\ u^2+w^2&=k^2,\\ u^2+v^2+w^2&=i^2.\end{aligned}$$

A solution is therefore a box with integer edges \(u\), \(v\), \(w\) whose space diagonal \(i\) and whose diagonals \(j\) and \(k\) of the two faces at the edge \(u\) are integers. The third face has the diagonal \(\sqrt{v^2+w^2}=\sqrt{2y}\); if it were an integer too, the box would be a perfect cuboid, and no perfect cuboid is known. A box in which all edges and diagonals except one face diagonal are integers is called a face cuboid. The box of Section 5, with edges \(104\), \(153\) and \(672\), face diagonals \(185\) and \(680\) and space diagonal \(697\), is the example that Euler gave, and it is the smallest face cuboid: none has a shorter space diagonal or a shorter longest edge. [4]

The parity condition \(j\equiv k\) is the same as \(v\equiv w\pmod 2\), because \(j^2-k^2=v^2-w^2\), and remainders after division by \(4\) show how it depends on the common edge \(u\). An even square is divisible by \(4\) and an odd square leaves the remainder \(1\), [2] so a sum of two odd squares leaves the remainder \(2\) and is never a square.

  • If \(u\) is odd, then \(v\) is even, because \(u^2+v^2\) is a square, and in the same way \(w\) is even. The parity condition holds.
  • If \(u\) is even, then \(v\) and \(w\) cannot both be odd, because \(u^2+v^2+w^2\) would leave the remainder \(2\). The parity condition holds only when \(v\) and \(w\) are both even, and then all three edges are even.

So a box whose edges have no common factor gives a solution directly when its common edge is odd, and only after doubling when it is even; doubling multiplies \(x\), \(y\) and \(z\) by \(4\). Euler's box has the even common edge \(104\), which is why Section 5 had to double it.

7. In which order the search meets the solutions

By Section 3 the quantity to minimise is

$$x+y+z=i^2+z=i^2+\frac{j^2-k^2}{2}.$$

Since \(z\lt y\lt x\), we have \(2z\lt x+y=i^2\), so every solution satisfies

$$i^2\lt x+y+z\lt\tfrac32\,i^2.$$

The value of \(i\) therefore fixes the sum only up to a factor below \(3/2\); for the solution of Section 5 the factor is \(2799586/1394^2\approx1.44\). A search through \(i=4,5,6,\dots\) meets the solutions roughly, but not exactly, in the order of their sums. If the first solution appears at \(i_0\) with the sum \(S_0\), a solution with a smaller sum must have \(i^2\lt S_0\lt\frac32 i_0^2\), that is \(i\lt1.225\,i_0\). A search that proves minimality must therefore continue up to \(i=\lfloor\sqrt{S_0-1}\rfloor\) and keep the smallest sum, and for one value of \(i\) it must compare all solutions, because the order of the pairs \((j,k)\) is not the order of \(z\).

Section 5 also bounds the search. Its solution has \(i=1394\), so the first solution has \(i_0\le1394\); and the smallest sum is at most \(2799586\), so the optimal solution has \(i\le\lfloor\sqrt{2799585}\rfloor=1673\). The search limit \(5000\) of the programs is more than enough.

How the Code Works

The C++ program [8] begins in main, which calls parse_arguments. It accepts --skip-checkpoints and --search-limit= followed by the largest \(i\) to try; the limit defaults to \(5000\) and must be at least \(4\). All search values have the type i64, the program's name for long long. is_square rejects negative numbers, takes the square root in long double, truncates it to an integer \(r\) and accepts the number if it equals \(r^2\) or \((r+1)^2\). Because std::sqrt is correctly rounded, the root of a perfect square below \(2^{53}\) comes out exactly; [5] the second comparison guards against a root that comes out one too small.

solve is the search of Sections 3 and 4. Its variables a, c, d, e, f and b hold the squares \(A\), \(C\), \(D\), \(E\), \(F\) and \(B\), and its loop variables are the \(i\), \(j\), \(k\) of Section 3. The outer loop sets \(A=i^2\) for \(i=4,5,\dots\) up to the limit. The middle loop tries \(j=3,\dots,i-1\) and rejects \(j\) at once unless \(F=A-C\) is a square; this Pythagorean test of Section 4 fails for almost every \(j\). Only after a success does the inner loop run, over the \(k\lt j\) of the same parity as \(j\): it starts at \(1\) or \(2\) and steps by \(2\). It forms \(E=A-D\) and \(B=C-E\), skips \(k\) when \(B\le0\), and otherwise tests \(B\) and \(E\). The starting values \(i=4\) and \(j=3\) lose nothing, because \(j=1\) and \(j=2\) have no smaller \(k\) of the same parity, and \(i\gt j\). When all tests pass, the program computes \(x=(D+C)/2\), \(y=(E+F)/2\) and \(z=(C-D)/2\), checks \(x\gt y\gt z\gt0\) and all six squares once more, and returns \(x+y+z\). By Section 3 these last checks cannot fail; they are a safety net. If no triple is found up to the limit, solve returns \(0\).

The return happens at the first triple met, in the order of increasing \(i\) and, for one \(i\), of increasing \(j\) and \(k\). By Section 7 this is not the order of the sums, so the program by itself does not prove that its result is the smallest; the verification below does. run_checkpoints calls solve(5000) and compares the result with a stored value, the expected output of the program. This protects against accidental changes of the code, but it is not an independent check. Unless --skip-checkpoints is given, main runs this check first, then runs the search with the requested limit and prints the result.

The Python version has the same is_square and solve, and its main handles the same two arguments and the same stored check. It uses math.isqrt, which returns the exact integer square root, so its second comparison is never needed, and its integers have unlimited precision. [6] The Java version consists of isSquare and main only: the limit \(5000\) is fixed, command-line arguments are ignored and there is no stored check. Its loop variables \(i\), \(j\), \(k\) are int, while the squares and the root inside isSquare are long, and Math.sqrt is correctly rounded like std::sqrt. It prints the first sum it finds and stops, and it prints nothing if there is none. With the limit \(5000\), every number in the three versions stays below \(\frac32\cdot5000^2\) in absolute value, far inside the 64-bit range.

Complexity and Verification

A full scan up to \(i=L\) makes \((L-3)(L-2)/2\) tests in the middle loop, since each \(i\) has \(i-3\) values of \(j\): \(12487503\) for \(L=5000\). A pair \((i,j)\) passes when \(j\) is a leg of a triple with hypotenuse \(i\), and then the inner loop makes \(\lfloor(j-1)/2\rfloor\lt L/2\) steps. The \(n\)-th hypotenuse of a primitive triple, counted with multiplicity, is asymptotically \(2\pi n\), [7] so about \(X/(2\pi)\) primitive triples have a hypotenuse up to \(X\); adding the \(\lfloor L/c\rfloor\) multiples of each primitive hypotenuse \(c\) gives a sum like a harmonic sum, so \(O(L\log L)\) triples have a hypotenuse up to \(L\). A full scan therefore takes \(O(L^2\log L)\) time and constant memory. For \(L=5000\) the \(5681\) triples give \(11362\) passing pairs and \(9893553\) inner steps, of which \(3500014\) have \(B\gt0\) and need square tests.

The programs stop at the first solution, at some \(i_0\le1394\) by Section 7, so they make at most \(968136\) middle-loop tests and \(646539\) inner steps, the counts of a full scan to \(1394\). All three versions finish in a fraction of a second; by default the C++ and Python programs run the search twice, once for the stored check and once for the result.

All three programs print the same number, and the stored check of the C++ and Python versions passes. The following checks were run separately for this article; they are not part of the published solutions.

  • A full scan of all \(i\le5000\) with the loops of solve, but without the early return, finds \(22\) solutions. Their smallest sum is the one the programs print, the solution with this sum is the only one with its value of \(i\), and no solution lies in the range \(i_0\lt i\lt\sqrt{S_0}\) of Section 7, so the early return gives the right result. Because \(i^2\lt x+y+z\), this scan contains every solution with \(x+y+z\le5000^2\).
  • An independent search with another parametrisation takes \(x+y=s^2\) and \(x-y=t^2\) with \(s\gt t\ge1\) of equal parity, writes \(2y=v^2+w^2\) in all possible ways with \(v\gt w\ge1\), which gives \(z=(v^2-w^2)/2\), and tests \(x+z\) and \(x-z\). Since \(s^2\lt x+y+z\), running \(s\) up to \(\sqrt{5\cdot10^6}\) covers every solution with \(x+y+z\le5\cdot10^6\); it finds the same five solutions as the scan.
  • An enumeration of all boxes of Section 6 with space diagonal at most \(3000\), built from Euclid's formula, finds \(15\) boxes, the smallest being Euler's. All of them obey the parity rule of Section 6, and the \(11\) boxes with \(v\equiv w\pmod 2\) give exactly the \(11\) solutions of the scan with \(i\le3000\).

Footnotes and References

The references below supply the background facts used above. The reduction to three squares, the parity rule for the boxes and the analysis of the search order are derived explicitly in this article.

  1. Project Euler 142 — Perfect Square Collection. The official statement asks for the smallest x + y + z with integers x > y > z > 0 such that x + y, x − y, x + z, x − z, y + z and y − z are all perfect squares. It gives no example values.
  2. Wikipedia — Square number. Squares of even numbers are even and divisible by 4, and squares of odd numbers are odd and leave the remainder 1 after division by 8, hence also after division by 4. Section 3 uses the parity, and Section 6 the remainders after division by 4.
  3. Wikipedia — Pythagorean triple. A primitive triple has no common divisor larger than 1. Euclid's formula a = m² − n², b = 2mn, c = m² + n² gives a primitive triple exactly when m and n are coprime and exactly one of them is even, and every primitive triple arises in this way, up to exchanging a and b. In a primitive triple exactly one leg is even and the hypotenuse is odd, and for every k some hypotenuse is shared by at least k triples.
  4. Wikipedia — Euler brick. An almost-perfect cuboid has six of its seven lengths rational, and in a face cuboid one face diagonal is irrational. Euler gave the face cuboid with edges 104, 153 and 672, which the article lists as the smallest, with face diagonals 185 and 680, the third face diagonal √474993 and space diagonal 697. No perfect cuboid has been found.
  5. cppreference — std::sqrt. The IEEE standard requires std::sqrt to be correctly rounded, so the exact result is produced whenever it can be represented in the floating-point type.
  6. Python — math.isqrt returns the floor of the exact square root of a nonnegative integer, and Python — numeric types states that integers have unlimited precision. Java — Math.sqrt returns the correctly rounded square root, the double closest to the true value.
  7. OEIS A020882 — Ordered hypotenuses (with multiplicity) of primitive Pythagorean triangles. The sequence starts 5, 13, 17, 25, 29, 37, 41, 53, 61, 65, 65, … and the entry gives a(n) ~ 2πn, so about X/(2π) primitive triangles have a hypotenuse up to X.
  8. C++ — Euler142.cpp. The linked immutable C++ revision contains parse_arguments, is_square, solve and run_checkpoints. It is the implementation record for this article.

Problem 142 source code

C++

#include <cmath>
#include <cstdint>
#include <iostream>
#include <string>

namespace {

using i64 = long long;

struct Options {
    int search_limit = 5000;
    bool run_checkpoints = true;
};

bool parse_int_after_prefix(const std::string& arg, const std::string& prefix, int& value) {
    if (arg.rfind(prefix, 0U) != 0U) {
        return false;
    }
    const std::string tail = arg.substr(prefix.size());
    if (tail.empty()) {
        return false;
    }

    int parsed = 0;
    for (char c : tail) {
        if (c < '0' || c > '9') {
            return false;
        }
        parsed = parsed * 10 + static_cast<int>(c - '0');
    }
    value = parsed;
    return true;
}

bool parse_arguments(int argc, char** argv, Options& options) {
    for (int i = 1; i < argc; ++i) {
        const std::string arg(argv[i]);
        if (arg == "--skip-checkpoints") {
            options.run_checkpoints = false;
            continue;
        }
        if (parse_int_after_prefix(arg, "--search-limit=", options.search_limit)) {
            continue;
        }

        std::cerr << "Unknown argument: " << arg << '\n';
        return false;
    }

    return options.search_limit >= 4;
}

bool is_square(const i64 x) {
    if (x < 0) {
        return false;
    }
    const i64 root = static_cast<i64>(std::sqrt(static_cast<long double>(x)));
    return root * root == x || (root + 1) * (root + 1) == x;
}

i64 solve(const int search_limit) {
    for (i64 i = 4; i <= search_limit; ++i) {
        const i64 a = i * i;
        for (i64 j = 3; j < i; ++j) {
            const i64 c = j * j;
            const i64 f = a - c;
            if (f <= 0 || !is_square(f)) {
                continue;
            }

            const i64 kstart = (j & 1LL) ? 1 : 2;
            for (i64 k = kstart; k < j; k += 2) {
                const i64 d = k * k;
                const i64 e = a - d;
                const i64 b = c - e;

                if (b <= 0 || e <= 0 || !is_square(b) || !is_square(e)) {
                    continue;
                }

                const i64 x = (d + c) / 2;
                const i64 y = (e + f) / 2;
                const i64 z = (c - d) / 2;
                if (!(x > y && y > z && z > 0)) {
                    continue;
                }

                if (is_square(x + y) && is_square(x - y) &&
                    is_square(x + z) && is_square(x - z) &&
                    is_square(y + z) && is_square(y - z)) {
                    return x + y + z;
                }
            }
        }
    }

    return 0;
}

bool run_checkpoints() {
    if (solve(5000) != 1006193) {
        std::cerr << "Checkpoint failed for search limit 5000" << '\n';
        return false;
    }
    return true;
}

}  // namespace

int main(int argc, char** argv) {
    Options options;
    if (!parse_arguments(argc, argv, options)) {
        return 1;
    }
    if (options.run_checkpoints && !run_checkpoints()) {
        return 2;
    }

    std::cout << solve(options.search_limit) << '\n';
    return 0;
}

Python

import math
import sys

def is_square(x: int) -> bool:
    if x < 0:
        return False
    root = int(math.isqrt(x))
    return root * root == x or (root + 1) * (root + 1) == x

def solve(search_limit: int) -> int:
    for i in range(4, search_limit + 1):
        a = i * i
        for j in range(3, i):
            c = j * j
            f = a - c
            if f <= 0 or not is_square(f):
                continue
            
            kstart = 1 if (j & 1) else 2
            for k in range(kstart, j, 2):
                d = k * k
                e = a - d
                b = c - e
                
                if b <= 0 or e <= 0 or not is_square(b) or not is_square(e):
                    continue
                
                x = (d + c) // 2
                y = (e + f) // 2
                z = (c - d) // 2
                
                if not (x > y and y > z and z > 0):
                    continue
                
                if (is_square(x + y) and is_square(x - y) and
                    is_square(x + z) and is_square(x - z) and
                    is_square(y + z) and is_square(y - z)):
                    return x + y + z
    
    return 0

def main():
    args = sys.argv[1:]
    
    search_limit = 5000
    run_checkpoints = True
    
    for arg in args:
        if arg == "--skip-checkpoints":
            run_checkpoints = False
        elif arg.startswith("--search-limit="):
            try:
                search_limit = int(arg[len("--search-limit="):])
            except ValueError:
                sys.stderr.write(f"Unknown argument: {arg}\n")
                sys.exit(1)
        else:
            sys.stderr.write(f"Unknown argument: {arg}\n")
            sys.exit(1)
    
    if search_limit < 4:
        sys.stderr.write("Search limit must be at least 4\n")
        sys.exit(1)
    
    if run_checkpoints:
        if solve(5000) != 1006193:
            sys.stderr.write("Checkpoint failed for search limit 5000\n")
            sys.exit(2)
    
    result = solve(search_limit)
    print(result)

if __name__ == "__main__":
    main()

Java

public class Euler142 {
    static boolean isSquare(long x) {
        if (x < 0)
            return false;
        long r = (long) Math.sqrt(x);
        if (r * r == x)
            return true;
        r++;
        return r * r == x;
    }

    public static void main(String[] args) {
        int limit = 5000;
        for (int i = 4; i <= limit; i++) {
            long a = (long) i * i;
            for (int j = 3; j < i; j++) {
                long c = (long) j * j;
                long f = a - c;
                if (f <= 0 || !isSquare(f))
                    continue;
                int kstart = (j % 2 == 0) ? 2 : 1;
                for (int k = kstart; k < j; k += 2) {
                    long d = (long) k * k;
                    long e = a - d;
                    long b = c - e;
                    if (b <= 0 || e <= 0 || !isSquare(b) || !isSquare(e))
                        continue;
                    long x = (d + c) / 2, y = (e + f) / 2, z = (c - d) / 2;
                    if (x > y && y > z && z > 0 &&
                            isSquare(x + y) && isSquare(x - y) &&
                            isSquare(x + z) && isSquare(x - z) &&
                            isSquare(y + z) && isSquare(y - z)) {
                        System.out.println(x + y + z);
                        return;
                    }
                }
            }
        }
    }
}