Project Euler Problem 348
Many numbers can be expressed as the sum of a square and a cube.
Solution
Answer: 1004195061
Let a number $N$ be representable as
$$N = a^2 + b^3$$
with $a>1$ and $b>1$.
We seek the five smallest palindromic numbers that admit exactly four distinct representations of this form.
Mathematical analysis
We need to combine three ideas:
- Generate palindromes efficiently.
- Test whether a palindrome can be written as a square plus a cube.
- Count representations exactly.
1. Why generate palindromes directly?
Checking every integer is wasteful because palindromes are sparse.
A palindrome is completely determined by its first half.
Examples:
- Even length:
$$123321$$
comes from mirroring $123$.
- Odd length:
$$12321$$
comes from mirroring all but the last digit of $123$.
Thus we can generate palindromes in increasing order very cheaply.
2. Counting representations
For a fixed palindrome $N$, we want all pairs
$$(a,b), \qquad a>1,; b>1$$
such that
$$a^2 + b^3 = N.$$
Rearrange:
$$a^2 = N - b^3.$$
So for every cube $b^3 < N$:
- Compute
$$r = N - b^3.$$ 2. Check whether $r$ is a perfect square.
A fast perfect-square test is:
$$a = \lfloor \sqrt{r} \rfloor,$$
then verify
$$a^2 = r.$$
Each successful check gives one representation.
3. Complexity
Suppose $N$ is around $10^9$.
Then:
$$b^3 \le N \quad\Rightarrow\quad b \le N^{1/3} \approx 1000.$$
So each palindrome requires only about $1000$ cube checks — very manageable.
Since palindromes are sparse, this brute force becomes practical.
Python implementation
from math import isqrt
def generate_palindromes(limit):
"""
Generate palindromes in increasing order up to 'limit'.
"""
length = 1
while True:
# Number of digits used to build the first half
start = 10 ** ((length - 1) // 2)
end = 10 ** ((length + 1) // 2)
for half in range(start, end):
s = str(half)
# Odd length palindrome
if length % 2 == 1:
p = int(s + s[-2::-1])
# Even length palindrome
else:
p = int(s + s[::-1])
if p > limit:
return
yield p
length += 1
def count_representations(n):
"""
Count representations of n as:
n = a^2 + b^3
with a > 1 and b > 1.
"""
count = 0
b = 2
while b ** 3 < n - 4:
cube = b ** 3
remainder = n - cube
a = isqrt(remainder)
if a > 1 and a * a == remainder:
count += 1
b += 1
return count
# Search for the first five palindromes
# having exactly four representations.
found = []
LIMIT = 2_000_000_000
for p in generate_palindromes(LIMIT):
if count_representations(p) == 4:
found.append(p)
print("Found:", p)
if len(found) == 5:
break
answer = sum(found)
print("Sum =", answer)
Code walkthrough
generate_palindromes(limit)
This function constructs palindromes directly.
Example:
If half = 123
- odd-length:
"123" + "21" -> 12321
- even-length:
"123" + "321" -> 123321
This guarantees palindromes appear in increasing order.
count_representations(n)
For every integer $b \ge 2$:
- Compute
$$b^3$$ 2. Compute
$$n - b^3$$ 3. Check whether the remainder is a perfect square.
The integer square root function isqrt() makes this exact and fast.
Verification with the example
For
$$5229225$$
the program finds exactly four representations:
$$2285^2 + 20^3$$
$$2223^2 + 66^3$$
$$1810^2 + 125^3$$
$$1197^2 + 156^3$$
matching the statement perfectly.
The five smallest qualifying palindromes
The computation finds:
$$5229225$$
$$37088073$$
$$56200265$$
$$108909801$$
$$796767697$$
Their sum is:
$$1004195061$$
The magnitude is reasonable: the fifth qualifying palindrome already lies near $8\times10^8$, so a total around $10^9$ is expected.
Answer: 1004195061