Project Euler Problem 4: Largest Palindrome Product
The Problem
A palindromic number reads the same both ways.
The largest palindrome made from the product of two 2-digit numbers is \[ 9009 = 91 \times 99 \]
Find the largest palindrome made from the product of two 3-digit numbers.
My Initial Approach
The plan was straightforward: multiply all pairs of 3-digit numbers, dump the results into a vector, then traverse the vector to find the largest palindrome. Nothing exotic. Here is what I actually wrote:
int a, b = 100; for (int x = 0; x < 1000; x++) { int temp; temp = a * b; results.push_back(temp); a++; b++; }
Three bugs. Let’s go through them.
Bug 1: Uninitialized Variable
int a, b = 100; // only b is initialized. a is garbage.
This is actually a basic mistake I did, I guess I haven’t paid enough attention while solving the question. The syntax int a, b = 100 does not initialize
both variables to 100, it declares a uninitialized and sets b to 100.
Reading from a before assigning it is undefined behavior: the program might
crash, produce wrong output, or appear to work correctly depending on what
happened to be in that memory location.
The fix is trivial:
int a = 100, b = 100;
Bug 2: Wrong Loop Structure
Even with a properly initialized, the loop is wrong. Incrementing both a
and b together in lockstep only tests the diagonal:
100×100, 101×101, 102×102, ..., 1099×1099
That is not “all pairs of 3-digit numbers.” You need a nested loop to cover the full Cartesian product:
for (int a = 100; a <= 999; a++) for (int b = a; b <= 999; b++) // b starts at a to avoid duplicate pairs results.push_back(a * b);
Starting b at a rather than 100 halves the work by skipping symmetric
duplicates — 100×200 and 200×100 produce the same product.
Bug 3: Unconditional Assignment
if (isPalindrome(i) == 1){ highestPalindrome = i; // overwrites regardless of whether i is larger }
This just sets highestPalindrome to whatever the last palindrome in the
vector is, not the largest. You need an additional guard:
if (isPalindrome(i) && i > highestPalindrome) highestPalindrome = i;
The Vector
I kept the vector intentionally to preserve the structure of the original approach, but it is worth noting why it is unnecessary here. The vector stores roughly 500,000 integers for a single read-once traversal. You never need more than one product in memory at a time, you can check each product against the current maximum as you compute it and discard it immediately.
The reason to keep a vector would be if you needed the full list for further processing: sorting, multiple passes, statistical queries. Here you don’t, so it is overhead with no payoff.
Final Code
#include <vector> #include <iostream> bool isPalindrome(int num) { int original = num; int reversed = 0; while (num > 0) { int digit = num % 10; reversed = reversed * 10 + digit; num /= 10; } return original == reversed; } int main() { std::vector<int> results; for (int a = 100; a <= 999; a++) for (int b = a; b <= 999; b++) results.push_back(a * b); int highestPalindrome = 0; for (auto i : results) if (isPalindrome(i) && i > highestPalindrome) highestPalindrome = i; std::cout << "Largest Palindrome Product: " << highestPalindrome << "\n"; return 0; }
The answer is 906609.
You can find the full code at my Github: https://github.com/AydoganArslantash/Project-Euler-Solutions/blob/main/large_palindrome.cpp