Project Euler Problem 44

Pentagonal numbers are generated by the formula, Pn=n(3n-1)/2.

Project Euler Problem 44

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. $1+24x$ must be a perfect square,
  2. 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