# Project Euler 35: Circular primes

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?

## Solution

With Problem 10 I introduced a prime sieve, which can be used for this question again. After that we can walk through the sieve (skipping even numbers) and if a number is prime, we check if all rotations are prime, which leads to the following implementation:

var NOT_PRIME = null; function solution(limit) { // Below 100 var num = 13; NOT_PRIME = sieve(limit); for (var i = 101; i < limit; i+= 2) { if (!NOT_PRIME[i] && allRotationsPrime(i)) num++; } return num; } solution(1000000);

The remaing question is, how can we rotate through the digits? A naive implementation would use strings like so:

function allRotationsPrime(n) { var num = String(n); for (var i = 1; i < num.length; i++) { num = num.slice(-1) + num.slice(0, num.length - 1) if (NOT_PRIME[parseInt(num, 10)]) { return false; } } return true; }

However, we can do a lot better. With Problem 25, I've proven that the length \(L(n)\) of a numer \(n\) is

\[L(n) = \lfloor 1+\log_{10}(n)\rfloor\]

Cutting off the last digit of a natural number can be done by

\[r_1(n) = \left\lfloor\frac{n}{10}\right\rfloor = \frac{n - (n \mod 10)}{10}\]

Shifting the cut-off digit to the left is as simple as:

\[r_2(n) = 10^{L(n) - 1}(n \mod 10)\]

Therefore, we can rotate a number quite easily with:

\[\begin{array}{rl}r(n) &= r_1(n) + r_2(n)\\&= \frac{n - (n \mod 10)}{10} + 10^{L(n) - 1} \cdot (n \mod 10)\\&= \frac{n - (n \mod 10)}{10} + \frac{10^{L(n)}}{10} \cdot (n \mod 10)\\&= \frac{n + (10^{L(n)} - 1) \cdot (n \mod 10))}{10}\end{array}\]

We could do another optimization. If a digit is a 2 or a 5, we know it can't be a prime, but since the lookup is \(O(1)\), it doesn't matter. All this information packed together results in the following implementation:

function allRotationsPrime(n) { var l = Math.floor(Math.log10(n)) + 1; var p = Math.pow(10, l) - 1; for (var i = 1; i < l; i++) { n = (n + n % 10 * p) / 10; if (NOT_PRIME[n]) { return false; } } return true; }