All Euler problems
Project Euler

Rational Zeros of a Function of Three Variables

For any integer n, consider three functions: f_(1,n)(x,y,z) = x^(n+1) + y^(n+1) - z^(n+1) f_(2,n)(x,y,z) = (xyz)^n(x+y-z) f_(3,n)(x,y,z) = xyz^n(x^(n-1)+y^(n-1)-z^(n-1)) for n!= 1 and f(x,y,z) = f_...

Source sync May 21, 2026
Problem #0180
Level Level 11
Solved By 1,885
Languages C++, Python
Answer 285196020571078987
Length 365 words
modular_arithmeticbrute_forcelinear_algebra

Problem Statement

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

For any integer $n$, consider the three functions \begin{align*} f_{1, n}(x, y, z) &= x^{n + 1} + y^{n + 1} - z^{n + 1}\\ f_{2, n}(x, y, z) &= (xy + yz + zx) \cdot (x^{n - 1} + y^{n - 1} - z^{n - 1})\\ f_{3, n}(x, y, z) &= xyz \cdot (x^{n - 2} + y^{n - 2} - z^{n - 2}) \end{align*} and their combination $$f_n(x, y, z) = f_{1, n}(x, y, z) + f_{2, n}(x, y, z) - f_{3, n}(x, y, z)$$ We call $(x, y, z)$ a golden triple of order $k$ if $x$, $y$, and $z$ are all rational numbers of the form $a / b$ with $0 < a < b \le k$ and there is (at least) one integer $n$, so that $f_n(x, y, z) = 0$.

Let $s(x, y, z) = x + y + z$.

Let $t = u / v$ be the sum of all distinct $s(x, y, z)$ for all golden triples $(x, y, z)$ of order $35$.

All the $s(x, y, z)$ and $t$ must be in reduced form.

Find $u + v$.

Problem 180: Rational Zeros of a Function of Three Variables

Mathematical Development

Identifying the Zero Set

f=0f = 0 when any factor vanishes. Since x,y,z>0x, y, z > 0:

  • f1=0f_1 = 0: xn+1+yn+1=zn+1x^{n+1} + y^{n+1} = z^{n+1}, giving exponent m=n+1m = n+1
  • f2=0f_2 = 0: x+y=zx + y = z (since (xyz)n≠0(xyz)^n \neq 0), giving m=1m = 1
  • f3=0f_3 = 0: xn−1+yn−1=zn−1x^{n-1} + y^{n-1} = z^{n-1}, giving exponent m=n−1m = n-1

Fermat’s Last Theorem

For ∣m∣≥3|m| \geq 3, xm+ym=zmx^m + y^m = z^m has no positive rational solutions (by FLT for m>0m > 0; for m<0m < 0, clearing denominators converts to a positive-exponent FLT instance).

For m=0m = 0: 1+1=11 + 1 = 1 is false.

Remaining Cases

Only four values of mm yield solutions:

mmEquationSolution for zz
1x+y=zx + y = zz=x+yz = x + y
2x2+y2=z2x^2 + y^2 = z^2z=x2+y2z = \sqrt{x^2 + y^2}
−1-11/x+1/y=1/z1/x + 1/y = 1/zz=xy/(x+y)z = xy/(x+y)
−2-21/x2+1/y2=1/z21/x^2 + 1/y^2 = 1/z^2z=xy/x2+y2z = xy/\sqrt{x^2+y^2}

Enumeration

For k=35k = 35, generate all 383 proper fractions a/ba/b with 1≤a<b≤351 \leq a < b \leq 35. For each pair (x,y)(x, y):

  1. m=1m = 1: Check if z=x+yz = x + y is a valid proper fraction with denominator ≤35\leq 35.
  2. m=−1m = -1: Check if z=xy/(x+y)z = xy/(x+y) is valid.
  3. m=2m = 2: Check if x2+y2x^2 + y^2 is a perfect square of a rational, and if so, check zz.
  4. m=−2m = -2: If the square root exists, check if z=xy/x2+y2z = xy/\sqrt{x^2+y^2} is valid.

Collect all distinct s=x+y+zs = x + y + z values and sum them.

Editorial

The mathematical reduction is what makes the brute-force search viable. Once Fermat’s theorem removes every exponent except 11, 22, −1-1, and −2-2, each ordered pair (x,y)(x,y) produces at most four candidate values of zz. So the problem becomes a finite search over proper fractions with denominator at most 35, followed by exact rational filtering.

The implementation first builds the full set of admissible fractions once. Then, for every pair (x,y)(x,y), it checks the four surviving cases: direct addition, harmonic addition, the Pythagorean square-root case, and its reciprocal-square analogue. Whenever the resulting zz is again a valid proper fraction of order 35, the sum x+y+zx+y+z is inserted into a set. Distinct golden triples may lead to the same rational sum, so the set on these totals is essential before the final fraction sum is reduced and converted to p+qp+q.

Pseudocode

Generate every proper fraction with denominator at most 35 and store them in a sorted list.
Create an empty set of admissible sums.

For each ordered pair `(x, y)` from that list:
    Check the linear case `z = x + y`.
    Check the harmonic case `z = xy / (x + y)`.

    Compute `x^2 + y^2`.
    If this rational is a perfect square:
        let `z` be its square root and test the quadratic case.
        let `z = xy / sqrt(x^2 + y^2)` and test the inverse-quadratic case.

    Whenever a candidate `z` is a proper fraction with denominator at most 35,
    insert `x + y + z` into the set of sums.

Add all distinct sums in the set, reduce the resulting fraction to lowest terms,
and return numerator plus denominator.

Complexity Analysis

The fraction set has 383 elements, so the search examines O(R2)O(R^2) ordered pairs with R=383R=383. Each pair performs only constant-time rational arithmetic and a small amount of perfect-square checking, giving overall time O(R2)O(R^2) and negligible space beyond the set of distinct sums.

Answer

285196020571078987\boxed{285196020571078987}

Code

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

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

// Problem 180: Rational Zeros of a Function of Three Variables
// Find S(35) = sum of distinct s = x+y+z from golden triples.
// x, y, z are proper fractions a/b with 1 <= a < b <= 35.
// Equations: m=1 (x+y=z), m=-1 (z=xy/(x+y)), m=2 (z=sqrt(x^2+y^2)),
//            m=-2 (z=xy/sqrt(x^2+y^2)).

typedef long long ll;
typedef __int128 lll;

ll gcd_ll(ll a, ll b) {
    a = abs(a); b = abs(b);
    while (b) { a %= b; swap(a,b); }
    return a;
}

struct Frac {
    ll num, den; // always reduced, den > 0
    Frac(ll n = 0, ll d = 1) {
        if (d < 0) { n = -n; d = -d; }
        ll g = gcd_ll(abs(n), d);
        num = n / g; den = d / g;
    }
    bool operator<(const Frac& o) const {
        return (lll)num * o.den < (lll)o.num * den;
    }
    bool operator==(const Frac& o) const {
        return num == o.num && den == o.den;
    }
    bool operator<=(const Frac& o) const { return !(o < *this); }
    bool operator>(const Frac& o) const { return o < *this; }
    bool operator>=(const Frac& o) const { return !(*this < o); }
    Frac operator+(const Frac& o) const {
        return Frac(num * o.den + o.num * den, den * o.den);
    }
    Frac operator*(const Frac& o) const {
        return Frac(num * o.num, den * o.den);
    }
    Frac operator/(const Frac& o) const {
        return Frac(num * o.den, den * o.num);
    }
};

int main() {
    const int K = 35;

    // Generate all proper fractions a/b with 1 <= a < b <= K
    vector<Frac> rats;
    set<pair<ll,ll>> rat_set;
    for (int b = 2; b <= K; b++) {
        for (int a = 1; a < b; a++) {
            Frac f(a, b);
            if (rat_set.insert({f.num, f.den}).second) {
                rats.push_back(f);
            }
        }
    }

    auto is_valid = [&](const Frac& z) -> bool {
        if (z.num <= 0 || z.den <= 0) return false;
        if (z.num >= z.den) return false; // z >= 1
        return z.den <= K;
    };

    auto isqrt_ll = [](ll n) -> ll {
        if (n < 0) return -1;
        ll s = (ll)sqrt((double)n);
        while (s * s > n) s--;
        while ((s+1)*(s+1) <= n) s++;
        return s;
    };

    set<pair<ll,ll>> s_values;

    for (auto& x : rats) {
        for (auto& y : rats) {
            // m=1: z = x+y
            {
                Frac z = x + y;
                if (is_valid(z)) {
                    Frac s = x + y + z;
                    s_values.insert({s.num, s.den});
                }
            }

            // m=-1: z = xy/(x+y)
            {
                Frac xy = x * y;
                Frac xpy = x + y;
                Frac z = xy / xpy;
                if (is_valid(z)) {
                    Frac s = x + y + z;
                    s_values.insert({s.num, s.den});
                }
            }

            // m=2: z = sqrt(x^2+y^2)
            // x^2+y^2 = (x.num^2*y.den^2 + y.num^2*x.den^2) / (x.den^2*y.den^2)
            {
                ll num2 = x.num*x.num*y.den*y.den + y.num*y.num*x.den*x.den;
                ll den2 = x.den*x.den*y.den*y.den;
                ll g = gcd_ll(num2, den2);
                num2 /= g; den2 /= g;
                ll sn = isqrt_ll(num2);
                ll sd = isqrt_ll(den2);
                if (sn >= 0 && sd > 0 && sn*sn == num2 && sd*sd == den2) {
                    Frac z(sn, sd);
                    if (is_valid(z)) {
                        Frac s = x + y + z;
                        s_values.insert({s.num, s.den});
                    }

                    // m=-2: z = xy/sqrt(x^2+y^2)
                    Frac sqrt_sum(sn, sd);
                    Frac xy = x * y;
                    Frac z2 = xy / sqrt_sum;
                    if (is_valid(z2)) {
                        Frac s = x + y + z2;
                        s_values.insert({s.num, s.den});
                    }
                }
            }
        }
    }

    // Sum all distinct s values as a single fraction
    // Use __int128 to avoid overflow
    lll total_num = 0, total_den = 1;
    for (auto& [n, d] : s_values) {
        // total_num/total_den + n/d = (total_num*d + n*total_den) / (total_den*d)
        total_num = total_num * d + (lll)n * total_den;
        total_den = total_den * d;
        // Reduce periodically to prevent overflow
        lll g = 0;
        { lll a = total_num < 0 ? -total_num : total_num, b = total_den;
          while (b) { a %= b; swap(a,b); } g = a; }
        total_num /= g;
        total_den /= g;
    }

    if (total_den < 0) { total_num = -total_num; total_den = -total_den; }

    // Print total_num + total_den
    lll result = total_num + total_den;

    // Print __int128
    auto print128 = [](lll x) {
        if (x < 0) { putchar('-'); x = -x; }
        if (x == 0) { putchar('0'); return; }
        string s;
        while (x > 0) { s += '0' + (int)(x % 10); x /= 10; }
        reverse(s.begin(), s.end());
        printf("%s", s.c_str());
    };

    print128(result);
    putchar('\n');

    return 0;
}