Project Euler Problem 44
Pentagonal numbers are generated by the formula, Pn=n(3n-1)/2.
Solution
Answer: 5482660
We seek pentagonal numbers
$$P_n=\frac{n(3n-1)}2$$
such that for some pair $(j,k)$,
- $P_j+P_k$ is pentagonal,
- $|P_k-P_j|$ is pentagonal,
and the difference
$$D=|P_k-P_j|$$
is as small as possible.
Mathematical analysis
The pentagonal numbers are generated by
$$P_n=\frac{n(3n-1)}2.$$
The first few are:
$$1,5,12,22,35,51,70,92,\dots$$
We want two pentagonal numbers $P_j,P_k$ satisfying two simultaneous conditions:
$$P_j+P_k \text{ is pentagonal}$$
and
$$|P_k-P_j| \text{ is pentagonal}.$$
A brute force search is possible, but we need an efficient way to test whether a number is pentagonal.
1. Deriving the pentagonal test
Suppose $x$ is pentagonal. Then for some integer $n$,
$$x=\frac{n(3n-1)}2.$$
Multiply by 2:
$$2x=3n^2-n.$$
Rearrange:
$$3n^2-n-2x=0.$$
This is a quadratic equation in $n$. Using the quadratic formula,
$$n=\frac{1\pm\sqrt{1+24x}}6.$$
For $n$ to be a positive integer:
- $1+24x$ must be a perfect square,
- that square root must make the numerator divisible by 6.
Thus:
$$x \text{ is pentagonal} \iff \sqrt{24x+1}\in\mathbb Z \quad\text{and}\quad (1+\sqrt{24x+1})\equiv0\pmod 6.$$
This gives a very fast membership test.
2. Search strategy
Generate pentagonal numbers in increasing order.
For each pair $j<k$:
$$P_j=\frac{j(3j-1)}2,\qquad P_k=\frac{k(3k-1)}2.$$
Compute:
$$S=P_j+P_k, \qquad D=P_k-P_j.$$
Check whether both $S$ and $D$ are pentagonal.
The first valid pair found with minimal $D$ is the required solution.
Because pentagonal numbers grow quadratically, the search converges fairly quickly.
Python implementation
import math
# Generate nth pentagonal number
def pentagonal(n):
return n * (3 * n - 1) // 2
# Test whether x is pentagonal
def is_pentagonal(x):
# Solve n = (1 + sqrt(1 + 24x)) / 6
d = 24 * x + 1
s = int(math.isqrt(d))
# Must be a perfect square
if s * s != d:
return False
# Must give integer n
return (1 + s) % 6 == 0
best_D = None
# Search over pairs of pentagonal numbers
for k in range(1, 5000):
Pk = pentagonal(k)
for j in range(1, k):
Pj = pentagonal(j)
D = Pk - Pj
S = Pk + Pj
# Check both conditions
if is_pentagonal(D) and is_pentagonal(S):
best_D = D
print("Found:", Pj, Pk, "Difference =", D)
break
if best_D is not None:
break
print("Answer =", best_D)
Code walkthrough
Function: pentagonal(n)
def pentagonal(n):
return n * (3 * n - 1) // 2
Directly implements
$$P_n=\frac{n(3n-1)}2.$$
Examples:
- $P_1=1$
- $P_2=5$
- $P_3=12$
Function: is_pentagonal(x)
d = 24 * x + 1
s = int(math.isqrt(d))
Computes the discriminant
$$24x+1.$$
If $x$ is pentagonal, this must be a perfect square.
if s * s != d:
return False
Reject immediately if not a perfect square.
return (1 + s) % 6 == 0
Checks whether
$$n=\frac{1+s}{6}$$
is an integer.
Main search loop
for k in range(1, 5000):
Generate pentagonal numbers in increasing order.
for j in range(1, k):
Check all earlier pentagonal numbers against $P_k$.
D = Pk - Pj
S = Pk + Pj
Compute the difference and sum.
if is_pentagonal(D) and is_pentagonal(S):
Verify both required conditions.
Small example verification
The problem statement gives:
$$P_4=22,\qquad P_7=70.$$
Their sum:
$$22+70=92=P_8,$$
which is pentagonal.
Their difference:
$$70-22=48.$$
Check:
$$24(48)+1=1153,$$
and $1153$ is not a perfect square, so $48$ is not pentagonal.
Our test correctly rejects it.
Final verification
Running the search finds the pair
$$P_{1020}=1560090, \qquad P_{2167}=7042750.$$
Then
$$D=7042750-1560090=5482660.$$
Both
$$7042750+1560090=8602840$$
and
$$5482660$$
are pentagonal.
This is the minimal such difference.
Answer: 5482660