All Euler problems
Project Euler

Diophantine Reciprocals I

Find the least value of n such that the number of distinct solutions of (1)/(x) + (1)/(y) = (1)/(n) exceeds 1000.

Source sync May 21, 2026
Problem #0108
Level Level 04
Solved By 14,456
Languages C++, Python
Answer 180180
Length 429 words
searchnumber_theoryoptimization

Problem Statement

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

In the following equation \(x\), \(y\), and \(n\) are positive integers. \[\dfrac {1}{x} + \dfrac {1}{y} = \dfrac {1}{n}\] For \(n = 4\) there are exactly three distinct solutions: \begin {align} \dfrac {1}{5} + \dfrac {1}{20} &= \dfrac {1}{4}\\ \dfrac {1}{6} + \dfrac {1}{12} &= \dfrac {1}{4}\\ \dfrac {1}{8} + \dfrac {1}{8} &= \dfrac {1}{4} \end {align}

What is the least value of \(n\) for which the number of distinct solutions exceeds one-thousand?

Note: This problem is an easier version of
hrefhttps://projecteuler.net/problem=110Problem 110; it is strongly advised that you solve this one first.

Problem 108: Diophantine Reciprocals I

Mathematical Foundation

Theorem 1. (Algebraic Transformation) The equation 1x+1y=1n\frac{1}{x} + \frac{1}{y} = \frac{1}{n} with positive integers x,y≥n+1x, y \geq n+1 is equivalent to (x−n)(y−n)=n2(x - n)(y - n) = n^2.

Proof. Starting from 1x+1y=1n\frac{1}{x} + \frac{1}{y} = \frac{1}{n}, multiply both sides by nxynxy:

ny+nx=xyny + nx = xy

Rearrange: xy−nx−ny=0xy - nx - ny = 0. Add n2n^2 to both sides:

xy−nx−ny+n2=n2xy - nx - ny + n^2 = n^2

Factor the left side: (x−n)(y−n)=n2(x - n)(y - n) = n^2.

For the constraint x,y≥n+1x, y \geq n+1: since 1x,1y>0\frac{1}{x}, \frac{1}{y} > 0 and 1x+1y=1n\frac{1}{x} + \frac{1}{y} = \frac{1}{n}, each fraction must be strictly less than 1n\frac{1}{n}, so x>nx > n and y>ny > n, giving x≥n+1x \geq n+1 and y≥n+1y \geq n+1. □\square

Theorem 2. (Solution Count) The number of distinct solutions (x,y)(x, y) with x≤yx \leq y equals ⌈d(n2)2⌉\left\lceil \frac{d(n^2)}{2} \right\rceil, where d(m)d(m) denotes the number of positive divisors of mm.

Proof. Let a=x−n,b=y−na = x - n, b = y - n, so ab=n2ab = n^2 with a,b≥1a, b \geq 1. The solutions (x,y)(x, y) with x≤yx \leq y correspond to divisor pairs (a,b)(a, b) of n2n^2 with a≤ba \leq b (since x≤y  ⟺  a≤bx \leq y \iff a \leq b). The number of such pairs is ⌈d(n2)/2⌉\lceil d(n^2) / 2 \rceil: if n2n^2 is a perfect square (which it always is), then d(n2)d(n^2) is odd, and the number of pairs with a≤ba \leq b is (d(n2)+1)/2=⌈d(n2)/2⌉(d(n^2) + 1)/2 = \lceil d(n^2)/2 \rceil. □\square

Theorem 3. (Divisor Function of a Square) If n=p1a1p2a2⋯pkakn = p_1^{a_1} p_2^{a_2} \cdots p_k^{a_k}, then:

d(n2)=∏i=1k(2ai+1)d(n^2) = \prod_{i=1}^{k} (2a_i + 1)

Proof. Since n2=p12a1p22a2⋯pk2akn^2 = p_1^{2a_1} p_2^{2a_2} \cdots p_k^{2a_k}, by the multiplicative property of the divisor function:

d(n2)=∏i=1k(2ai+1)d(n^2) = \prod_{i=1}^{k} (2a_i + 1)

Each factor 2ai+12a_i + 1 counts the number of choices for the exponent of pip_i in a divisor of n2n^2 (from 00 to 2ai2a_i). □\square

Lemma 1. (Optimization Principle) To minimize nn subject to d(n2)≥Md(n^2) \geq M, the exponents (a1,a2,…,ak)(a_1, a_2, \ldots, a_k) assigned to primes (p1<p2<⋯<pk)(p_1 < p_2 < \cdots < p_k) must satisfy a1≥a2≥⋯≥ak≥1a_1 \geq a_2 \geq \cdots \geq a_k \geq 1.

Proof. Suppose ai<aja_i < a_j for some i<ji < j (so pi<pjp_i < p_j). Swapping exponents ai↔aja_i \leftrightarrow a_j does not change d(n2)=∏(2am+1)d(n^2) = \prod(2a_m + 1) but strictly decreases nn:

nnewnold=piajpjaipiaipjaj=(pipj)aj−ai<1\frac{n_{\text{new}}}{n_{\text{old}}} = \frac{p_i^{a_j} p_j^{a_i}}{p_i^{a_i} p_j^{a_j}} = \left(\frac{p_i}{p_j}\right)^{a_j - a_i} < 1

since pi<pjp_i < p_j and aj−ai>0a_j - a_i > 0. Thus assigning larger exponents to smaller primes is always optimal. □\square

Theorem 4. (Solution) We need ⌈d(n2)/2⌉>1000\lceil d(n^2)/2 \rceil > 1000. Since d(n2)d(n^2) is odd, this means d(n2)≥2001d(n^2) \geq 2001, i.e., ∏(2ai+1)≥2001\prod(2a_i + 1) \geq 2001.

The minimum nn with this property is:

n=180180=22⋅32⋅5⋅7⋅11⋅13n = 180180 = 2^2 \cdot 3^2 \cdot 5 \cdot 7 \cdot 11 \cdot 13

with d(n2)=5⋅5⋅3⋅3⋅3⋅3=2025d(n^2) = 5 \cdot 5 \cdot 3 \cdot 3 \cdot 3 \cdot 3 = 2025 and ⌈2025/2⌉=1013>1000\lceil 2025/2 \rceil = 1013 > 1000.

Proof. We verify 180180180180 is minimal by exhaustive search over non-increasing exponent sequences. The exponent sequence is (2,2,1,1,1,1)(2, 2, 1, 1, 1, 1), giving the divisor product 5×5×3×3×3×3=2025≥20015 \times 5 \times 3 \times 3 \times 3 \times 3 = 2025 \geq 2001. Any alternative sequence with product ≥2001\geq 2001 assigned to the same or different primes yields n≥180180n \geq 180180. This is verified by checking all feasible exponent profiles (bounded by log⁡3(2001)≈7\log_3(2001) \approx 7 primes and maximum exponent ≤10\leq 10). □\square

Editorial

After rewriting the equation as (x−n)(y−n)=n2(x-n)(y-n) = n^2, the search is no longer over pairs (x,y)(x,y) at all; it is over factorizations of nn. If n=∏piain = \prod p_i^{a_i}, then the number of solutions depends only on the divisor product ∏(2ai+1)\prod(2a_i+1), so the task is to find the smallest nn whose exponent pattern makes that product reach 20012001.

The key optimization is that a minimal solution must place larger exponents on smaller primes, which means the exponents form a non-increasing sequence. The implementation recursively builds exactly those sequences, updates both the current value of nn and the current divisor product, and prunes any branch that is already no better than the best solution found so far.

Pseudocode

Keep a global best value of n, initially infinite.
Explore exponent sequences recursively, one prime at a time.

During the search:
    If the current divisor product has already reached 2001, compare the current n with the best value and keep the smaller one.
    Otherwise choose an exponent for the next prime, not exceeding the previous exponent.
    Update n by multiplying by the corresponding prime power, and update the divisor product by the factor 2a + 1.
    Skip any branch whose partial n is already at least as large as the best solution found.

When all feasible branches have been explored or pruned, return the best n.

Complexity Analysis

  • Time: The search explores exponent sequences (a1≥a2≥⋯≥1)(a_1 \geq a_2 \geq \cdots \geq 1) with ∏(2ai+1)≥2001\prod(2a_i+1) \geq 2001. The number of such sequences is bounded by the number of partitions of integers into parts of the form 2a+1≥32a+1 \geq 3, which is very small (hundreds at most). With pruning (n<best_nn < \text{best\_n}), the search terminates almost instantly.
  • Space: O(k)O(k) for the recursion stack, where k≤9k \leq 9 (the number of primes considered).

Answer

180180\boxed{180180}

Code

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

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

/*
 * Problem 108: Diophantine Reciprocals I
 *
 * 1/x + 1/y = 1/n => (x-n)(y-n) = n^2
 * Number of solutions = ceil(d(n^2) / 2) where d is the divisor function.
 * d(n^2) = product of (2*a_i + 1) for each prime factor p_i^a_i of n.
 * We need ceil(d(n^2)/2) > 1000, i.e., d(n^2) >= 2001.
 *
 * Strategy: search over non-increasing exponent sequences assigned to
 * primes 2, 3, 5, 7, 11, 13, ... to minimize n.
 */

int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47};
const int NPRIMES = 15;
long long best_n;

// Recursive search: assign exponents to primes in order
// idx: current prime index, max_exp: maximum exponent allowed (non-increasing)
// current_n: product so far, current_div: d(n^2) so far
void dfs(int idx, int max_exp, long long current_n, long long current_div) {
    if (current_div >= 2001) {
        best_n = min(best_n, current_n);
        return;
    }
    if (idx >= NPRIMES) return;
    if (current_n > best_n) return;

    // Try exponents from max_exp down to 1
    long long pw = 1;
    for (int e = 1; e <= max_exp; e++) {
        pw *= primes[idx];
        if (current_n > best_n / pw) break; // overflow guard
        dfs(idx + 1, e, current_n * pw, current_div * (2 * e + 1));
    }
}

int main() {
    best_n = LLONG_MAX;
    dfs(0, 30, 1, 1);
    cout << best_n << endl;
    return 0;
}