Prime pair sets (Euler Problem 60)

Back to overview.

https://projecteuler.net/problem=60

The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property.

Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime.

In [1]:
from itertools import combinations

def concatenate_all(numbers):
    result = []
    for a, b in combinations(numbers, 2):
        result.append([a, b])
        result.append([b, a])
    return result

print(concatenate_all([3, 7, 109, 673]))
[[3, 7], [7, 3], [3, 109], [109, 3], [3, 673], [673, 3], [7, 109], [109, 7], [7, 673], [673, 7], [109, 673], [673, 109]]
In [2]:
def sieve_of_eratosthenes(limit):
    primes = []
    prospects = [n for n in range(2, limit)]
    while prospects:
        p = prospects[0]
        prospects = [x for x in prospects if x % p != 0]
        primes.append(p)
        if p * p > limit:
            break
    primes += prospects
    return primes

primes = sieve_of_eratosthenes(100000)
primes_set = set(primes)
In [3]:
def is_prime(n):
    if n % 2 == 0:
        return False
    while n % 2 == 0:
        n //= 2
    f = 3
    while f * f <= n:
        if n % f == 0:
            return False
        else:
            f += 2   
    return True

def concatentation_is_prime(a, b):
    ab = int(str(a) + str(b))
    ba = int(str(b) + str(a))
    if is_prime(ab) and is_prime(ba):
        return True
    else:
        return False
    
assert(concatentation_is_prime(673, 3))
assert(concatentation_is_prime(673, 1) == False)
In [4]:
potentials = []
new_potentials = []
done = False
for p in primes:
    if done:
        break
    potentials += new_potentials
    new_potentials = []
    for potential in potentials:
        all_concatenations_prime = True
        for prime in potential:
            if not concatentation_is_prime(p, prime):
                all_concatenations_prime = False
                break
        if all_concatenations_prime:
            new_potential = list(potential)
            new_potential.append(p)
            if len(new_potential) > 4:
                print(new_potential)
                s = sum(new_potential)
                done = True
                break
            new_potentials.append(new_potential)
    if p < 15:
        potentials.append([p])

print(s)
assert(s == 26033)
[13, 5197, 5701, 6733, 8389]
26033
In [ ]: