# 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 [ ]: