Tim Varley Logo
Tim Varley Systems Engineer
Problem #44 hard

Pentagon Numbers

Pentagonal numbers are generated by the formula, Pn=n(3n1)/2P_n=n(3n-1)/2. The first ten pentagonal numbers are: 1,5,12,22,35,51,70,92,117,145,1, 5, 12, 22, 35, 51, 70, 92, 117, 145, \dots

It can be seen that P4+P7=22+70=92=P8P_4 + P_7 = 22 + 70 = 92 = P_8. However, their difference, 7022=4870 - 22 = 48, is not pentagonal.

Find the pair of pentagonal numbers, PjP_j and PkP_k, for which their sum and difference are pentagonal and D=PkPjD = |P_k - P_j| is minimised; what is the value of DD?

Implementations

cpp
// https://projecteuler.net/problem=44
// Pentagonal numbers are generated by the formula, Pn=n(3n-1)/2. The first ten pentagonal numbers are:
// 1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ...
// It can be seen that P4 + P7 = 22 + 70 = 92 = P8. However, their difference, 70 - 22 = 48, is not pentagonal.
// Find the pair of pentagonal numbers, Pj and Pk, for which their sum and difference are pentagonal and D = |Pk - Pj| is minimised; what is the value of D?
// Answer: 5482660
// Authored by: Tim Varley 💘
#include <iostream>
#include <vector>
#include <set>
#include <cmath>
#include <climits>
static bool is_pentagonal(long long n) {
double k = (1 + sqrt(1 + 24.0 * n)) / 6;
return k == floor(k);
}
long long pentagon_numbers() {
std::vector<long long> pent;
for (long long n = 1; n < 3000; n++) {
long long p = n * (3 * n - 1) / 2;
pent.push_back(p);
}
long long min_diff = LLONG_MAX;
for (size_t i = 0; i < pent.size(); i++) {
for (size_t j = i + 1; j < pent.size(); j++) {
long long sum_p = pent[i] + pent[j];
long long diff_p = pent[j] - pent[i];
if (is_pentagonal(sum_p) && is_pentagonal(diff_p)) {
if (diff_p < min_diff) min_diff = diff_p;
}
}
}
return min_diff;
}
#if ! defined UNITTEST_MODE
int main(int argc, char const *argv[]) {
std::cout << pentagon_numbers() << std::endl;
}
#endif // UNITTEST_MODE

Solution Notes

Mathematical Background

Pentagonal numbers are generated by the formula Pn=n(3n1)/2P_n = n(3n-1)/2. The first ten are 1, 5, 12, 22, 35, 51, 70, 92, 117, 145.

The problem requires finding pairs of pentagonal numbers where both their sum and difference are also pentagonal, and finding the pair with the minimal difference D.

Algorithm Analysis

The solution generates pentagonal numbers sequentially and checks all pairs (j,k) with j < k. For each pair, it computes sum S = Pj + Pk and difference D = Pk - Pj, then checks if both S and D are pentagonal.

Pentagonal checking uses the inverse formula: for a number x, solve n(3n1)/2=xn(3n-1)/2 = x for integer n. This gives the quadratic 3n2n2x=03n^2 - n - 2x = 0, solved as n=(1+1+24x)/6n = (1 + \sqrt{1 + 24x})/6. If n is integer, x is pentagonal.

Performance Analysis

  • Time Complexity: O(n^2) where n ≈ 2500 (number of pentagonals up to reasonable limit), resulting in ~6 million operations
  • Space Complexity: O(n) for storing the list of pentagonals
  • Execution Time: <1 second on modern hardware
  • Scalability: Quadratic growth, but small n makes it practical

Key Insights

  • The minimal difference is 5482660 (between P_{2167} and P_{1020})

  • Generating pentagonals on-the-fly or precomputing doesn’t significantly affect performance

  • Using a set for O(1) lookup can optimize checks in some implementations

  • The pair is found relatively early in the sequence

Educational Value

This problem demonstrates:

  • Figurate number sequences and their properties

  • Inverse formula derivation for number checking

  • Quadratic equation solutions in programming

  • Brute force search with early termination

  • Mathematical optimization in computational problems