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 Apr 19, 2026
Problem #0180
Level Level 11
Solved By 1,885
Languages C++, Python
Answer 285196020571078987
Length 212 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 Analysis

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)n0(xyz)^n \neq 0), giving m=1m = 1
  • f3=0f_3 = 0: xn1+yn1=zn1x^{n-1} + y^{n-1} = z^{n-1}, giving exponent m=n1m = n-1

Fermat’s Last Theorem

For m3|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 1a<b351 \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.

Answer

285196020571078987\boxed{285196020571078987}

Complexity

The enumeration iterates over O(R2)O(R^2) pairs where R=383R = 383 rationals, with O(1)O(1) work per pair per case. Total: O(R2)1.5×105O(R^2) \approx 1.5 \times 10^5 operations. Negligible runtime.

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;
}