Truncatable Primes¶

Apparently another term for these sorts of numbers is a two-sided prime.

In case you're curious how we know there's only eleven of these primes (not including 2, 3, 5, or 7), this solution will outline it.

We start by generating all the right-truncatable primes - the two-sided primes are necessarily a subset of these. If we know a number $n$ is not a right-truncatable prime, we know any number with $n$ as a prefix is also not a right-truncatable prime. This means we can start by looking at one-digit primes (2, 3, 5, and 7) and for each, try appending each of 1, 3, 7, and 9 and see which, if any, are also prime (appending any other digit would clearly result in a number divisible by 2 or 5). If we find another prime, we'll want to repeat the process of appending 1, 3, 7, or 9 to see if we can find more right-truncatable primes. We use a depth-first search for this.

In [1]:
right_truncatable_primes = set()

visited = set()
stack = [2, 3, 5, 7]
while stack != []:
    n = stack.pop()
    if n in visited:
        continue
    visited.add(n)
    
    for d in (1,3,7,9):
        m = 10*n + d
        if is_prime(m):
            right_truncatable_primes.add(m)
            stack.append(m)

right_truncatable_primes
Out[1]:
{23,
 29,
 31,
 37,
 53,
 59,
 71,
 73,
 79,
 233,
 239,
 293,
 311,
 313,
 317,
 373,
 379,
 593,
 599,
 719,
 733,
 739,
 797,
 2333,
 2339,
 2393,
 2399,
 2939,
 3119,
 3137,
 3733,
 3739,
 3793,
 3797,
 5939,
 7193,
 7331,
 7333,
 7393,
 23333,
 23339,
 23399,
 23993,
 29399,
 31193,
 31379,
 37337,
 37339,
 37397,
 59393,
 59399,
 71933,
 73331,
 73939,
 233993,
 239933,
 293999,
 373379,
 373393,
 593933,
 593993,
 719333,
 739391,
 739393,
 739397,
 739399,
 2339933,
 2399333,
 2939999,
 3733799,
 5939333,
 7393913,
 7393931,
 7393933,
 23399339,
 29399999,
 37337999,
 59393339,
 73939133}

Next, we write a function for checking if a prime is left-truncatable.

In [2]:
from itertools import count

def is_left_truncatable_prime(p):
    for k in count(1):
        t = p % 10^k
        if not is_prime(t):
            return False
        if t == p:
            break
    
    return True

Now just check all our right-truncatable primes to see if they are also left-truncatable.

In [3]:
two_sided_primes = {p for p in right_truncatable_primes if is_left_truncatable_prime(p)}
two_sided_primes
Out[3]:
{23, 37, 53, 73, 313, 317, 373, 797, 3137, 3797, 739397}

Sure enough, only eleven two-sided primes.

In [4]:
sum(two_sided_primes)
Out[4]:
748317

Relevant sequences¶

  • Two-sided primes: A020994

Copyright (C) 2025 filifa¶

This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license and the BSD Zero Clause license.