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...
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.

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 Foundation
Definition. The hexagonal spiral has ring 0 (tile 1) at the center. Ring () contains tiles. The first tile of ring is . The last tile of ring is .
Theorem 1 (Ring formulas). The first and last tile numbers of ring are:
Proof. Ring contains tiles, and rings contain tiles. Adding the center tile (tile 1), the first tile of ring is . The last tile is .
Theorem 2 (Only endpoints have ). For , can only occur when or for some ring . Interior tiles (not at the first or last position of a ring) have .
Proof. Consider a tile at position along ring (not at a corner or endpoint). Its six neighbors include tiles from rings , , and . Among the six differences, at least four are either 1 or even numbers :
- Two adjacent tiles in the same ring give differences 1 (not prime) or small even.
- Neighbors in adjacent rings give differences that include or (both even).
Thus at most 2 differences can be prime, giving . Only the first and last tiles of each ring have a special neighbor configuration that allows exactly 3 prime differences.
Theorem 3 (Difference formulas for ). The six neighbor differences of for are: , , , , , and . Of these, only , , and can be prime. Thus if and only if all three are prime.
Proof. The neighbors of are:
- : difference 1 (not prime).
- : difference (even, for ).
- : difference (even).
- : difference .
- : difference .
- The sixth neighbor (in ring ): difference .
The values 1, , are never prime for . The remaining three (, , ) may be prime.
Theorem 4 (Difference formulas for ). For , the potentially prime differences of are , , and . Thus if and only if all three are prime.
Proof. The neighbors of are:
- (previous tile in ring): difference 1.
- : difference 1.
- : difference (even).
- : difference (even).
- Two additional neighbors yield differences , , and .
For , , so all three candidates are valid.
Lemma 1 (Tile 1). , since the neighbors of tile 1 are tiles 2—7, giving differences . The primes among these are .
Proof. Direct computation.
Editorial
Key insight: Only the first and last tile of each ring can have PD=3. We check S(r). We then check E(r) for r >= 2. Finally, unreachable.
Pseudocode
Check S(r)
Check E(r) for r >= 2
unreachable
Complexity Analysis
- Time: where is the ring number of the 2000th qualifying tile and is the magnitude of the numbers tested for primality (). Each ring requires primality tests, each costing via Miller-Rabin.
- Space: (no arrays needed beyond the primality test).
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#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;
}
"""
Problem 128: Hexagonal Tile Differences
Find the 2000th tile for which exactly 3 of the differences
with its 6 neighbors are prime.
Key insight: Only the first and last tile of each ring can have PD=3.
- First tile S(r) = 3r(r-1)+2: needs 6r-1, 6r+1, 12r+5 all prime
- Last tile E(r) = 3r(r+1)+1: needs 6r-1, 6r+5, 12r-7 all prime (r>=2)
"""
from sympy import isprime
def solve(target=2000):
count = 1 # tile 1 is the first with PD=3
r = 1
while True:
# First tile of ring r
if isprime(6*r - 1) and isprime(6*r + 1) and isprime(12*r + 5):
count += 1
if count == target:
return 3*r*(r-1) + 2
# Last tile of ring r (r >= 2 for 12r-7 > 1)
if r >= 2 and isprime(6*r - 1) and isprime(6*r + 5) and isprime(12*r - 7):
count += 1
if count == target:
return 3*r*(r+1) + 1
r += 1
if __name__ == '__main__':
answer = solve()
print(answer)