Tim Varley Logo
Tim Varley Systems Engineer
Problem #28 hard

Number Spiral Diagonals

Starting with the number 11 and moving to the right in a clockwise direction a 55 by 55 spiral is formed as follows:

| 21 | 22 | 23 | 24 | 25 | |----|----|----|----|----| | 20 | 7 | 8 | 9 | 10 | | 19 | 6 | 1 | 2 | 11 | | 18 | 5 | 4 | 3 | 12 | | 17 | 16 | 15 | 14 | 13 |

It can be verified that the sum of the numbers on the diagonals is 101101.

What is the sum of the numbers on the diagonals in a 10011001 by 10011001 spiral formed in the same way?

Implementations

cpp
// https://projecteuler.net/problem=28
// Starting with the number 1 and moving to the right in a clockwise direction a 5 by 5 spiral is formed as follows:
//
// 21 22 23 24 25
// 20 7 8 9 10
// 19 6 1 2 11
// 18 5 4 3 12
// 17 16 15 14 13
//
// It can be verified that the sum of the numbers on the diagonals is 101.
//
// What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral formed in the same way?
//
// Answer: 669171001
// Authored by: Tim Varley 💘
// Assisted-by: Grok Code Fast via Crush 💘 <crush@charm.land>
#include <iostream>
long long spiral_diagonal_sum(int size) {
if (size == 1) return 1;
long long sum = 1; // center
for (int n = 3; n <= size; n += 2) {
// corners: n², n²-n+1, n²-2n+2, n²-3n+3
long long corner1 = (long long)n * n;
long long corner2 = corner1 - (n - 1);
long long corner3 = corner2 - (n - 1);
long long corner4 = corner3 - (n - 1);
sum += corner1 + corner2 + corner3 + corner4;
}
return sum;
}
#if ! defined UNITTEST_MODE
int main(int argc, char const *argv[]) {
std::cout << spiral_diagonal_sum(1001) << std::endl;
}
#endif // UNITTEST_MODE

Solution Notes

Mathematical Background

This problem involves summing the diagonal elements of a square spiral formed by placing numbers in a clockwise pattern starting from the center. The spiral grows by adding layers, with each layer nn having side length 2n12n-1. The corners of each layer follow a predictable pattern: for layer nn, the corner values are n2n^2, n2(n1)n^2 - (n-1), n22(n1)n^2 - 2(n-1), and n23(n1)n^2 - 3(n-1).

Algorithm Analysis

The solution iterates through each layer of the spiral, calculating the four corner values and adding them to a running sum. Starting with the center value of 1, it processes layers from size 3 to the target size (1001) in steps of 2. Each layer computation is O(1)O(1), resulting in O(n)O(n) time complexity where nn is the spiral size. Space complexity is O(1)O(1) as only a few variables are used.

Key Insights

The diagonal sum can be computed without constructing the entire spiral grid. Each layer contributes exactly four diagonal elements (except the center layer), and their values follow the pattern derived from the spiral’s growth. For a 1001×10011001 \times 1001 spiral, there are 500 layers beyond the center, giving a total of 2001 diagonal elements summing to 669,171,001.

Educational Value

This problem demonstrates pattern recognition in mathematical sequences and the power of mathematical insight over brute-force computation. It teaches how to identify regularities in seemingly complex structures and derive closed-form formulas for efficient calculation, avoiding the need to generate large data structures.