All Euler problems
Project Euler

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

Source sync Apr 19, 2026
Problem #0004
Level Level 00
Solved By 523,556
Languages C++, Python
Answer 906609
Length 709 words
searchnumber_theorybrute_force

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 nn is a palindrome in base 10 if its decimal representation dkdk1d1d0d_k d_{k-1} \cdots d_1 d_0 satisfies di=dkid_i = d_{k-i} for all 0ik0 \le i \le k.

Definition 2. A 6-digit palindrome is an integer PP with 100,000P999,999100{,}000 \le P \le 999{,}999 that is a palindrome. Its decimal form is abccba\overline{abccba} where a{1,,9}a \in \{1,\dots,9\} and b,c{0,,9}b,c \in \{0,\dots,9\}.

Theorem 1 (Structure of 6-digit palindromes). Every 6-digit palindrome P=abccbaP = \overline{abccba} admits the representation

P=11(9091a+910b+100c).P = 11(9091a + 910b + 100c).

In particular, 11P11 \mid P.

Proof. By positional notation,

P=105a+104b+103c+102c+10b+a.P = 10^5 a + 10^4 b + 10^3 c + 10^2 c + 10 b + a.

Collecting terms:

P=(105+1)a+(104+10)b+(103+102)c=100001a+10010b+1100c.P = (10^5 + 1)a + (10^4 + 10)b + (10^3 + 10^2)c = 100001a + 10010b + 1100c.

We verify each coefficient is divisible by 11:

  • 100001=11×9091100001 = 11 \times 9091, since 11×9091=11×9000+11×91=99000+1001=10000111 \times 9091 = 11 \times 9000 + 11 \times 91 = 99000 + 1001 = 100001.
  • 10010=11×91010010 = 11 \times 910, since 11×910=1001011 \times 910 = 10010.
  • 1100=11×1001100 = 11 \times 100.

Therefore P=11(9091a+910b+100c)P = 11(9091a + 910b + 100c), and 11P11 \mid P. \square

Lemma 1 (Factor constraint). If P=xyP = xy where PP is a 6-digit palindrome and x,yx, y are positive integers, then 11x11 \mid x or 11y11 \mid y.

Proof. By Theorem 1, 11P11 \mid P. Since 1111 is prime, Euclid’s lemma (if pp is prime and pabp \mid ab, then pap \mid a or pbp \mid b) yields 11x11 \mid x or 11y11 \mid y. \square

Theorem 2 (Product range). If 100x,y999100 \le x, y \le 999, then 10,000xy998,00110{,}000 \le xy \le 998{,}001. Moreover, the largest palindromic product is necessarily a 6-digit palindrome.

Proof. The bounds follow from 100×100=10,000100 \times 100 = 10{,}000 and 999×999=998,001999 \times 999 = 998{,}001. The largest 5-digit palindrome is 99,99999{,}999. We claim that a 6-digit palindromic product exists in the given range. Indeed, 143×707=101,101=101101143 \times 707 = 101{,}101 = \overline{101101}, which is a 6-digit palindrome and satisfies 100143,707999100 \le 143, 707 \le 999. Since 101,101>99,999101{,}101 > 99{,}999, the maximum palindromic product must be a 6-digit palindrome. \square

Theorem 3 (Optimality). The largest palindrome that is a product of two 3-digit numbers is

M=906,609=913×993.M = 906{,}609 = 913 \times 993.

Proof. By Theorem 2, any maximal palindromic product of two 3-digit numbers must be a 6-digit palindrome. Therefore Lemma 1 applies: if P=xyP = xy, 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 xyxy with

110xy999,11x.110 \le x \le y \le 999, \qquad 11 \mid x.

Hence it suffices to search the finite set

C={(x,y)Z2:110xy999, 11x}.\mathcal{C} = \{(x,y) \in \mathbb{Z}^2 : 110 \le x \le y \le 999,\ 11 \mid x\}.

The algorithm below enumerates C\mathcal{C} in descending order of xx and, for each fixed xx, in descending order of yy. Its pruning rule is sound because for fixed xx the products xyxy strictly decrease as yy decreases. Consequently:

  • once xybestxy \le \text{best}, no smaller value of yy can improve the answer;
  • the first palindromic product found for a fixed xx is the largest palindromic product with that value of xx.

A complete execution over C\mathcal{C} returns

best=906,609=913×993.\text{best} = 906{,}609 = 913 \times 993.

We verify that 906,609906{,}609 is a palindrome and that 913=11×83913 = 11 \times 83, so the candidate indeed lies in the restricted search space. Since the search is exhaustive over all relevant pairs, no larger palindromic product exists. \square

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 xyxy with 100x,y999100 \le x, y \le 999.

Proof. By Theorem 2 and Lemma 1, every optimal pair may be reordered so that it belongs to

C={(x,y):110xy999, 11x}.\mathcal{C} = \{(x,y) : 110 \le x \le y \le 999,\ 11 \mid x\}.

The outer loop enumerates every admissible value of xx in C\mathcal{C} exactly once, and for each such xx the inner loop enumerates admissible yy values from 999999 down to xx. Thus every pair in C\mathcal{C} is considered unless a justified early exit occurs.

There are two early exits:

  1. If P <= best, then for every later inner-loop value y<yy' < y we have xy<xybestxy' < xy \le \text{best}, so no skipped pair can improve the answer.
  2. If P is palindromic, the algorithm stores best <- P and breaks. This is valid because any later inner-loop value satisfies y<yy' < y, hence xy<xy=Pxy' < xy = P, so no later pair with the same outer-loop value xx 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. \square

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 O(N2/11)O(N^2/11) time in the worst case, where N=900N = 900 is the count of 3-digit numbers.

Proof. The outer loop visits the 3-digit multiples of 11

110,121,132,,990,110, 121, 132, \ldots, 990,

which form an arithmetic progression with

99011011+1=81\frac{990 - 110}{11} + 1 = 81

terms. For each outer-loop value, the inner loop performs at most 900900 iterations in the worst case. Each iteration carries out O(1)O(1) work: one multiplication, one comparison, and at most one palindrome test on a decimal string of length at most 66. Hence the total work is bounded by

81×900=72,900=O(N2/11),81 \times 900 = 72{,}900 = O(N^2/11),

where N=900N = 900 is the number of 3-digit integers. Early termination can only decrease this bound. \square

Space complexity. O(1)O(1). Only a constant number of integer variables and a string of length 6\le 6 are used.

Answer

906609\boxed{906609}

Code

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

C++ project_euler/problem_004/solution.cpp
#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;
}