Euler Problem 35

Back to overview.

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?

First we get all primes into a look-up table. Then we iterate them and check whether they are circular.

In [1]:
def get_primes_smaller(number):
    primes = []
    prospects = [n for n in range(2, number)]
    while prospects:
        p = prospects[0]
        prospects = [x for x in prospects if x % p != 0]
        primes.append(p)
        if p * p > number:
            return primes + prospects
    return primes

ps = get_primes_smaller(1000000)
In [2]:
def get_combinations(xs):
    if not xs:
        return []
    rs = []
    for i in range(len(xs)):
        yss = get_combinations(xs[:i] + xs[i + 1:])
        if not yss:
            rs.append(xs[i])
        for ys in yss:
            rs.append(xs[i] + ys)
    return rs

assert(get_combinations("ab") == ["ab", "ba"])
In [3]:
from itertools import permutations
prime_set = set(ps)

def is_circular(p):
    cs = permutations(str(p))
    for c in cs:
        if not int("".join(c)) in prime_set:
            return False
    return True

assert(is_circular("2") == True)
assert(is_circular("11") == True)
assert(is_circular("47") == False)
In [4]:
s = len([p for p in ps if is_circular(p)])
print("False solution {}".format(s))
False solution 22

We did not read the problem properly. Cycles are obviously not the same as permutations. If we change that we should get the solution in no time.

In [5]:
def cyles(xs):
    if len(xs) <= 1:
        return xs
    return [xs[i:] + xs[:i]  for i in range(len(xs))]

prime_set = set(ps)

def is_circular(p):
    cs = cyles(str(p))
    for c in cs:
        if not int("".join(c)) in prime_set:
            return False
    return True
In [6]:
s = len([p for p in ps if is_circular(p)])
s
Out[6]:
55