Circular Primes
The number 197 is called a circular prime because all rotations of its digits are prime: 197, 971, and 719. How many circular primes are there below one million?
Problem Statement
This archive keeps the full statement, math, and original media on the page.
The number, \(197\), is called a circular prime because all rotations of the digits: \(197\), \(971\), and \(719\), are themselves prime.
There are thirteen such primes below \(100\): \(2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79\), and \(97\).
How many circular primes are there below one million?
Problem 35: Circular Primes
Mathematical Development
Definition 1 (Cyclic rotation). For a -digit positive integer with decimal representation (where ), the cyclic rotation operator is defined by
The orbit of under is .
Lemma 1 (Rotation formula). The operator maps (with , ) to . Applying exactly times returns the original number: .
Proof. The representation has digit string where represents . The map moves the last digit to the leading position: .
For the periodicity claim, observe that acts as a cyclic permutation on the digit string . Since cyclic permutations of elements have order , is the identity.
Definition 2 (Circular prime). A prime is circular if every element of is prime.
Lemma 2 (Single-digit circular primes). The single-digit circular primes are .
Proof. A single-digit number has . The single-digit primes are exactly , each trivially circular.
Theorem 1 (Digit restriction). If is a circular prime with digits, then every digit of belongs to .
Proof. We show that no digit of can be , or .
Even digits (): Suppose digit is even for some . The rotation places in the units position, yielding an even number. Since , this number is , hence an even number greater than 2, which is composite. This contradicts being prime.
Digit 5: Suppose . Then ends in 5 and is , hence divisible by 5 but not equal to 5. This is composite, a contradiction.
Digit 0: Suppose . Then has leading digit 0, making it a number with fewer than digits (or zero). But all rotations of a -digit prime should be -digit primes, since implies all rotations are , and a rotation with leading zero has value , contradicting the expectation that it equals a specific -digit rotation. More directly, , which could cause the subsequent rotation formula (which assumes digits) to malfunction. In any case, a number with leading digit 0 is not considered a -digit number in standard notation.
Therefore, all digits must be odd and not 0 or 5, leaving .
Theorem 2 (Sieve of Eratosthenes). For any positive integer , the sieve of Eratosthenes correctly identifies all primes in in time using space.
Proof. (Standard.) The sieve initializes a boolean array of size , then for each prime , marks all multiples as composite. Correctness follows from the fact that every composite has a prime factor . The time complexity is by Mertens’ second theorem.
Theorem 3 (Correctness of the rotation-check algorithm). Given a prime sieve up to , the following procedure correctly identifies all circular primes below : for each prime , compute all rotations of via Lemma 1; accept as circular if and only if every rotation satisfies and is marked prime.
Proof. If is circular, then all rotations are prime and (since and all rotations of a -digit number are also -digit numbers with the same digit set) all rotations are . Conversely, if some rotation is composite or , then is not circular. The sieve provides exact primality answers for all integers in , so the procedure is correct.
Editorial
We first sieve all primes below the bound so that primality tests for rotations are constant-time lookups. Then we scan the primes in increasing order, form every cyclic rotation of the decimal expansion of each prime, and declare the prime circular only if every rotation also lies below the bound and remains prime. The final count is the number of primes that satisfy this rotation test.
Pseudocode
Algorithm: Counting Circular Primes Below a Bound
Require: An integer N ≥ 2.
Ensure: The number of primes below N whose every decimal rotation is also prime.
1: Build a sieve and a prime lookup structure on {2, 3, ..., N - 1}.
2: Initialize count ← 0.
3: For each prime p < N, generate all cyclic rotations of the decimal expansion of p.
4: If every rotation belongs to the prime set, increment count.
5: Return count.
Complexity Analysis
Proposition. For , the algorithm runs in time and space.
Proof. The sieve dominates at . The rotation check iterates over all primes ; by the prime-counting function, there are primes below . For each prime, at most rotations are computed in each. Thus the rotation phase costs , dominated by the sieve. Space is for the boolean sieve array.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
int main() {
const int N = 1000000;
vector<bool> is_prime(N, true);
is_prime[0] = is_prime[1] = false;
for (int i = 2; i * i < N; i++)
if (is_prime[i])
for (int j = i * i; j < N; j += i)
is_prime[j] = false;
int count = 0;
for (int p = 2; p < N; p++) {
if (!is_prime[p]) continue;
int k = 0, tmp = p;
while (tmp > 0) { k++; tmp /= 10; }
int pw = 1;
for (int i = 0; i < k - 1; i++) pw *= 10;
bool circular = true;
int r = p;
for (int i = 0; i < k; i++) {
if (r < 0 || r >= N || !is_prime[r]) { circular = false; break; }
r = (r % 10) * pw + r / 10;
}
if (circular) count++;
}
cout << count << endl; // 55
return 0;
}
"""Project Euler Problem 35: Circular Primes"""
def sieve(limit):
is_prime = [True] * limit
is_prime[0] = is_prime[1] = False
for i in range(2, int(limit**0.5) + 1):
if is_prime[i]:
for j in range(i * i, limit, i):
is_prime[j] = False
return is_prime
def main():
N = 1_000_000
is_prime = sieve(N)
count = 0
for p in range(2, N):
if not is_prime[p]:
continue
s = str(p)
k = len(s)
if all(is_prime[int(s[i:] + s[:i])] for i in range(k)):
count += 1
print(count) # 55
if __name__ == "__main__":
main()