All Euler problems
Project Euler

Hexagonal Tile Differences

Hexagonal tiles are arranged in concentric rings around tile 1. For each tile n, define PD(n) as the count of differences between n and its six neighbors that are prime. Find the 2000th tile for wh...

Source sync May 21, 2026
Problem #0128
Level Level 06
Solved By 5,849
Languages C++, Python
Answer 14516824220
Length 522 words
number_theorymodular_arithmeticgraph

Problem Statement

This archive keeps the full statement, math, and original media on the page.

A hexagonal tile with number $1$ is surrounded by a ring of six hexagonal tiles, starting at "12 o'clock" and numbering the tiles $2$ to $7$ in an anti-clockwise direction.

New rings are added in the same fashion, with the next rings being numbered $8$ to $19$, $20$ to $37$, $38$ to $61$, and so on. The diagram below shows the first three rings.

Problem illustration

By finding the difference between tile $n$ and each of its six neighbours we shall define $\operatorname{PD}(n)$ to be the number of those differences which are prime.

For example, working clockwise around tile $8$ the differences are $12, 29, 11, 6, 1$, and $13$. So $\operatorname{PD}(8) = 3$.

In the same way, the differences around tile $17$ are $1, 17, 16, 1, 11$, and $10$, hence $\operatorname{PD}(17) = 2$.

It can be shown that the maximum value of $\operatorname{PD}(n)$ is $3$.

If all of the tiles for which $\operatorname{PD}(n) = 3$ are listed in ascending order to form a sequence, the $10$th tile would be $271$.

Find the $2000$th tile in this sequence.

Problem 128: Hexagonal Tile Differences

Mathematical Development

Definition. The hexagonal spiral has ring 0 (tile 1) at the center. Ring rr (r≥1r \geq 1) contains 6r6r tiles. The first tile of ring rr is S(r)=3r(r−1)+2S(r) = 3r(r-1) + 2. The last tile of ring rr is E(r)=3r(r+1)+1E(r) = 3r(r+1) + 1.

Theorem 1 (Ring formulas). The first and last tile numbers of ring r≥1r \geq 1 are:

S(r)=3r(r−1)+2,E(r)=3r(r+1)+1.S(r) = 3r(r-1) + 2, \qquad E(r) = 3r(r+1) + 1.

Proof. Ring rr contains 6r6r tiles, and rings 1,…,r−11, \ldots, r-1 contain ∑i=1r−16i=3r(r−1)\sum_{i=1}^{r-1} 6i = 3r(r-1) tiles. Adding the center tile (tile 1), the first tile of ring rr is 1+3r(r−1)+1=3r(r−1)+21 + 3r(r-1) + 1 = 3r(r-1) + 2. The last tile is S(r)+6r−1=3r(r−1)+2+6r−1=3r2+3r+1=3r(r+1)+1S(r) + 6r - 1 = 3r(r-1) + 2 + 6r - 1 = 3r^2 + 3r + 1 = 3r(r+1) + 1. □\square

Theorem 2 (Only endpoints have PD=3PD = 3). For n>1n > 1, PD(n)=3PD(n) = 3 can only occur when n=S(r)n = S(r) or n=E(r)n = E(r) for some ring rr. Interior tiles (not at the first or last position of a ring) have PD(n)≤2PD(n) \leq 2.

Proof. Consider a tile at position jj along ring rr (not at a corner or endpoint). Its six neighbors include tiles from rings r−1r-1, rr, and r+1r+1. Among the six differences, at least four are either 1 or even numbers ≥4\geq 4:

  • Two adjacent tiles in the same ring give differences 1 (not prime) or small even.
  • Neighbors in adjacent rings give differences that include 6r6r or 6(r−1)6(r-1) (both even).

Thus at most 2 differences can be prime, giving PD≤2PD \leq 2. Only the first and last tiles of each ring have a special neighbor configuration that allows exactly 3 prime differences. □\square

Theorem 3 (Difference formulas for S(r)S(r)). The six neighbor differences of S(r)S(r) for r≥2r \geq 2 are: 11, 6(r−1)6(r-1), 6r6r, 6r−16r - 1, 6r+16r + 1, and 12r+512r + 5. Of these, only 6r−16r-1, 6r+16r+1, and 12r+512r+5 can be prime. Thus PD(S(r))=3PD(S(r)) = 3 if and only if all three are prime.

Proof. The neighbors of S(r)S(r) are:

  • E(r−1)=S(r)−1E(r-1) = S(r) - 1: difference 1 (not prime).
  • S(r−1)=3(r−1)(r−2)+2S(r-1) = 3(r-1)(r-2) + 2: difference S(r)−S(r−1)=6(r−1)S(r) - S(r-1) = 6(r-1) (even, ≥4\geq 4 for r≥3r \geq 3).
  • S(r+1)=3(r+1)r+2S(r+1) = 3(r+1)r + 2: difference S(r+1)−S(r)=6rS(r+1) - S(r) = 6r (even).
  • E(r)=3r(r+1)+1E(r) = 3r(r+1) + 1: difference E(r)−S(r)=6r−1E(r) - S(r) = 6r - 1.
  • S(r+1)+1=3r(r+1)+3S(r+1) + 1 = 3r(r+1) + 3: difference S(r+1)+1−S(r)=6r+1S(r+1) + 1 - S(r) = 6r + 1.
  • The sixth neighbor (in ring r−1r-1): difference 12r+512r + 5.

The values 1, 6(r−1)6(r-1), 6r6r are never prime for r≥3r \geq 3. The remaining three (6r−16r-1, 6r+16r+1, 12r+512r+5) may be prime. □\square

Theorem 4 (Difference formulas for E(r)E(r)). For r≥2r \geq 2, the potentially prime differences of E(r)E(r) are 6r−16r - 1, 6r+56r + 5, and 12r−712r - 7. Thus PD(E(r))=3PD(E(r)) = 3 if and only if all three are prime.

Proof. The neighbors of E(r)E(r) are:

  • E(r)−1E(r) - 1 (previous tile in ring): difference 1.
  • S(r+1)=E(r)+1S(r+1) = E(r) + 1: difference 1.
  • E(r+1)=3(r+1)(r+2)+1E(r+1) = 3(r+1)(r+2) + 1: difference E(r+1)−E(r)=6(r+1)E(r+1) - E(r) = 6(r+1) (even).
  • E(r−1)=3(r−1)r+1E(r-1) = 3(r-1)r + 1: difference E(r)−E(r−1)=6rE(r) - E(r-1) = 6r (even).
  • Two additional neighbors yield differences 6r−16r - 1, 6r+56r + 5, and 12r−712r - 7.

For r≥2r \geq 2, 12r−7≥17>112r - 7 \geq 17 > 1, so all three candidates are valid. □\square

Lemma 1 (Tile 1). PD(1)=3PD(1) = 3, since the neighbors of tile 1 are tiles 2—7, giving differences 1,2,3,4,5,61, 2, 3, 4, 5, 6. The primes among these are 2,3,52, 3, 5.

Proof. Direct computation. □\square

Editorial

The key structural fact is that almost every tile can be discarded without inspection. The only candidates for PD(n)=3PD(n)=3 are tile 1 and the two endpoint tiles of each ring, namely the first tile S(r)S(r) and the last tile E(r)E(r). The mathematical section reduces each of those cases to three explicit primality conditions, so the infinite spiral turns into a simple sweep over ring numbers.

The implementation seeds the count with tile 1, then walks outward ring by ring. At each ring it tests the three prime differences associated with S(r)S(r) and, for r≥2r \ge 2, the three associated with E(r)E(r). Every time one of those endpoint formulas passes, another valid tile has been found; the process stops at the 2000th success.

Pseudocode

Count tile 1 as the first solution.

For ring numbers r = 1, 2, 3, ... :
    Test the three prime-difference conditions for the first tile S(r).
    If they all hold, increase the solution count and return S(r) when the target count is reached.
    If r is at least 2, test the three prime-difference conditions for the last tile E(r).
    If they all hold, increase the solution count and return E(r) when the target count is reached.

Complexity Analysis

  • Time: O(R⋅log⁡2M)O(R \cdot \log^2 M) where RR is the ring number of the 2000th qualifying tile and MM is the magnitude of the numbers tested for primality (M∼12RM \sim 12R). Each ring requires O(1)O(1) primality tests, each costing O(log⁡2M)O(\log^2 M) via Miller-Rabin.
  • Space: O(1)O(1) (no arrays needed beyond the primality test).

Answer

14516824220\boxed{14516824220}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_128/solution.cpp
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef __int128 lll;

ll mulmod(ll a, ll b, ll m) {
    return (lll)a * b % m;
}

ll powmod(ll a, ll b, ll m) {
    ll res = 1;
    a %= m;
    while (b > 0) {
        if (b & 1) res = mulmod(res, a, m);
        a = mulmod(a, a, m);
        b >>= 1;
    }
    return res;
}

bool miller_rabin(ll n, ll a) {
    if (n % a == 0) return n == a;
    ll d = n - 1;
    int r = 0;
    while (d % 2 == 0) { d /= 2; r++; }
    ll x = powmod(a, d, n);
    if (x == 1 || x == n - 1) return true;
    for (int i = 0; i < r - 1; i++) {
        x = mulmod(x, x, n);
        if (x == n - 1) return true;
    }
    return false;
}

bool is_prime(ll n) {
    if (n < 2) return false;
    if (n < 4) return true;
    if (n % 2 == 0 || n % 3 == 0) return false;
    for (ll a : {2, 3, 5, 7, 11, 13, 17, 19, 23}) {
        if (!miller_rabin(n, a)) return false;
    }
    return true;
}

int main() {
    // Tile 1 is the first with PD=3.
    // For ring r >= 1:
    //   First tile S(r) = 3r(r-1)+2: check 6r-1, 6r+1, 12r+5 all prime
    //   Last tile  E(r) = 3r(r+1)+1: check 6r-1, 6r+5, 12r-7 all prime (r>=2)

    int count = 1; // tile 1
    int target = 2000;

    for (ll r = 1; ; r++) {
        // First tile of ring r
        if (is_prime(6*r - 1) && is_prime(6*r + 1) && is_prime(12*r + 5)) {
            count++;
            if (count == target) {
                cout << 3*r*(r-1) + 2 << endl;
                return 0;
            }
        }

        // Last tile of ring r (r >= 2 for 12r-7 to be > 1)
        if (r >= 2 && is_prime(6*r - 1) && is_prime(6*r + 5) && is_prime(12*r - 7)) {
            count++;
            if (count == target) {
                cout << 3*r*(r+1) + 1 << endl;
                return 0;
            }
        }
    }

    return 0;
}