Largest Palindrome Product
Find the largest palindrome made from the product of two 3-digit numbers. That is, determine M = maxbigl{xy: 100 <= x,y <= 999, xy is a palindrome in base 10bigr}.
Problem Statement
This archive keeps the full statement, math, and original media on the page.
A palindromic number reads the same both ways. The largest palindrome made from the product of two \(2\)-digit numbers is \(9009 = 91 \time 99\)
Find the largest palindrome made from the product of two \(3\)-digit numbers.
Problem 4: Largest Palindrome Product
Mathematical Development
Definitions
Definition 1. A non-negative integer is a palindrome in base 10 if its decimal representation satisfies for all .
Definition 2. A 6-digit palindrome is an integer with that is a palindrome. Its decimal form is where and .
Theorem 1 (Structure of 6-digit palindromes). Every 6-digit palindrome admits the representation
In particular, .
Proof. By positional notation,
Collecting terms:
We verify each coefficient is divisible by 11:
- , since .
- , since .
- .
Therefore , and .
Lemma 1 (Factor constraint). If where is a 6-digit palindrome and are positive integers, then or .
Proof. By Theorem 1, . Since is prime, Euclid’s lemma (if is prime and , then or ) yields or .
Theorem 2 (Product range). If , then . Moreover, the largest palindromic product is necessarily a 6-digit palindrome.
Proof. The bounds follow from and . The largest 5-digit palindrome is . We claim that a 6-digit palindromic product exists in the given range. Indeed, , which is a 6-digit palindrome and satisfies . Since , the maximum palindromic product must be a 6-digit palindrome.
Theorem 3 (Optimality). The largest palindrome that is a product of two 3-digit numbers is
Proof. By Theorem 2, any maximal palindromic product of two 3-digit numbers must be a 6-digit palindrome. Therefore Lemma 1 applies: if , then at least one of the two factors is divisible by 11.
By commutativity of multiplication, every candidate product can thus be written in the form with
Hence it suffices to search the finite set
The algorithm below enumerates in descending order of and, for each fixed , in descending order of . Its pruning rule is sound because for fixed the products strictly decrease as decreases. Consequently:
- once , no smaller value of can improve the answer;
- the first palindromic product found for a fixed is the largest palindromic product with that value of .
A complete execution over returns
We verify that is a palindrome and that , so the candidate indeed lies in the restricted search space. Since the search is exhaustive over all relevant pairs, no larger palindromic product exists.
Editorial
We search the factor pairs in descending order while exploiting the divisibility-by-11 constraint for six-digit palindromes. The outer loop enumerates 3-digit multiples of 11 from largest to smallest, the inner loop scans the matching partner in descending order, and each product is tested by reversing its decimal digits. Two early exits avoid useless work: once a product is no larger than the current best, later partners for the same outer factor cannot improve it, and once a palindrome is found for a fixed outer factor, smaller partners only decrease the product.
Theorem 4 (Algorithm correctness). LargestPalindromeProduct() returns the largest palindrome of the form with .
Proof. By Theorem 2 and Lemma 1, every optimal pair may be reordered so that it belongs to
The outer loop enumerates every admissible value of in exactly once, and for each such the inner loop enumerates admissible values from down to . Thus every pair in is considered unless a justified early exit occurs.
There are two early exits:
- If
P <= best, then for every later inner-loop value we have , so no skipped pair can improve the answer. - If
Pis palindromic, the algorithm storesbest <- Pand breaks. This is valid because any later inner-loop value satisfies , hence , so no later pair with the same outer-loop value can produce a larger palindrome.
Therefore the algorithm never discards a pair that could beat the final answer, and it eventually records the maximum palindromic product.
Pseudocode
Algorithm: Largest Palindromic Product of Two Three-digit Numbers
Require: The set of three-digit integers.
Ensure: The largest palindromic product of two three-digit factors.
1: Initialize best ← 0.
2: For each three-digit multiple of 11, taken in descending order, denote it by a.
3: For each three-digit integer b in descending order with b ≥ a and a · b > best, compute P ← a · b.
4: If P is a palindrome, set best ← P and stop the inner scan for this a.
5: Return best.
Complexity Analysis
Theorem 5 (Time complexity). The algorithm runs in time in the worst case, where is the count of 3-digit numbers.
Proof. The outer loop visits the 3-digit multiples of 11
which form an arithmetic progression with
terms. For each outer-loop value, the inner loop performs at most iterations in the worst case. Each iteration carries out work: one multiplication, one comparison, and at most one palindrome test on a decimal string of length at most . Hence the total work is bounded by
where is the number of 3-digit integers. Early termination can only decrease this bound.
Space complexity. . Only a constant number of integer variables and a string of length are used.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
bool is_palindrome(int n) {
string s = to_string(n);
int lo = 0, hi = (int)s.size() - 1;
while (lo < hi) {
if (s[lo++] != s[hi--]) return false;
}
return true;
}
int main() {
int best = 0;
// By Theorem 1 + Euclid's lemma: one factor must be divisible by 11
for (int x = 990; x >= 110; x -= 11) {
for (int y = 999; y >= x; y--) {
int P = x * y;
if (P <= best) break;
if (is_palindrome(P)) {
best = P;
break;
}
}
}
cout << best << endl;
return 0;
}
"""Project Euler Problem 4: Largest Palindrome Product"""
def is_palindrome(n: int) -> bool:
s = str(n)
return s == s[::-1]
def solve() -> int:
best = 0
# One factor must be divisible by 11 (Theorem 1 + Euclid's lemma)
for a in range(990, 99, -11):
for b in range(999, a - 1, -1):
prod = a * b
if prod <= best:
break
if is_palindrome(prod):
best = prod
break
return best
answer = solve()
assert answer == 906609
print(answer)