Tim Varley Logo
Tim Varley Principal AI Engineer and Tech Leader
Problem #61 hard

Cyclical Figurate Numbers

Triangle, square, pentagonal, hexagonal, heptagonal, and octagonal numbers are all figurate (polygonal) numbers and are generated by the following formulae:

| Triangle | | P3,n=n(n+1)/2P_{3,n}=n(n+1)/2 | | 1,3,6,10,15,1, 3, 6, 10, 15, \dots | | Square | | P4,n=n2P_{4,n}=n^2 | | 1,4,9,16,25,1, 4, 9, 16, 25, \dots | | Pentagonal | | P5,n=n(3n1)/2P_{5,n}=n(3n-1)/2 | | 1,5,12,22,35,1, 5, 12, 22, 35, \dots | | Hexagonal | | P6,n=n(2n1)P_{6,n}=n(2n-1) | | 1,6,15,28,45,1, 6, 15, 28, 45, \dots | | Heptagonal | | P7,n=n(5n3)/2P_{7,n}=n(5n-3)/2 | | 1,7,18,34,55,1, 7, 18, 34, 55, \dots | | Octagonal | | P8,n=n(3n2)P_{8,n}=n(3n-2) | | 1,8,21,40,65,1, 8, 21, 40, 65, \dots |

The ordered set of three 44-digit numbers: 81288128, 28822882, 82818281, has three interesting properties.

  1. The set is cyclic, in that the last two digits of each number is the first two digits of the next number (including the last number with the first).

  2. Each polygonal type: triangle (P3,127=8128P_{3,127}=8128), square (P4,91=8281P_{4,91}=8281), and pentagonal (P5,44=2882P_{5,44}=2882), is represented by a different number in the set.

  3. This is the only set of 44-digit numbers with this property.

Find the sum of the only ordered set of six cyclic 44-digit numbers for which each polygonal type: triangle, square, pentagonal, hexagonal, heptagonal, and octagonal, is represented by a different number in the set.

View on Project Euler

Implementations

cpp
#include <iostream>
#include <vector>
#include <set>
#include <functional>
int cyclical_figurate_numbers() {
std::vector<std::vector<int>> polys(9);
auto gen_poly = [&](int type, auto formula) {
for (int n = 1; ; ++n) {
int num = formula(n);
if (num >= 10000) break;
if (num >= 1000) polys[type].push_back(num);
}
};
gen_poly(3, [](int n){ return n*(n+1)/2; });
gen_poly(4, [](int n){ return n*n; });
gen_poly(5, [](int n){ return n*(3*n-1)/2; });
gen_poly(6, [](int n){ return n*(2*n-1); });
gen_poly(7, [](int n){ return n*(5*n-3)/2; });
gen_poly(8, [](int n){ return n*(3*n-2); });
std::vector<std::vector<std::vector<int>>> by_prefix(9);
for (int t = 3; t <= 8; ++t) {
by_prefix[t].resize(100);
for (int num : polys[t]) {
int prefix = num / 100;
by_prefix[t][prefix].push_back(num);
}
}
std::function<bool(std::vector<int>&, std::set<int>&, int)> find_cycle = [&](std::vector<int>& current, std::set<int>& used_types, int start_suffix) -> bool {
if (current.size() == 6) {
int last = current.back() % 100;
int first = current[0] / 100;
return last == first;
}
int next_prefix = current.back() % 100;
for (int t = 3; t <= 8; ++t) {
if (used_types.count(t)) continue;
for (int num : by_prefix[t][next_prefix]) {
current.push_back(num);
used_types.insert(t);
if (find_cycle(current, used_types, start_suffix)) return true;
used_types.erase(t);
current.pop_back();
}
}
return false;
};
std::vector<int> current;
std::set<int> used_types;
for (int t = 3; t <= 8; ++t) {
for (int num : polys[t]) {
current = {num};
used_types = {t};
if (find_cycle(current, used_types, num / 100)) {
int sum = 0;
for (int n : current) sum += n;
return sum;
}
}
}
return -1;
}
#if ! defined UNITTEST_MODE
int main(int argc, char const *argv[]) {
std::cout << cyclical_figurate_numbers() << std::endl;
}
#endif
View on GitHub
O(1) time complexity

Solution Notes

Mathematical Background

This problem involves finding cyclic sets of figurate numbers where each type is represented exactly once, and the numbers form a cycle based on their last two and first two digits.

Algorithm Analysis

Generate all 4-digit polygonal numbers for each type, then use backtracking to find a cycle of six numbers, each of different types, where the last two digits of one match the first two of the next.

Performance Analysis

  • Time Complexity: O(1) - fixed small search space
  • Space Complexity: O(1) - small data structures
  • Execution Time: Fast, backtracking finds solution quickly
  • Scalability: Not applicable, fixed problem size

Key Insights

  • Prefix maps enable efficient lookup of numbers with matching prefixes
  • Backtracking with early termination finds the unique solution
  • The solution sum is 28684

Educational Value

This problem teaches:

  • Combinatorial search and backtracking
  • Data structure optimization for prefix matching
  • Working with polygonal number sequences
  • Cycle detection in permutations