Tim Varley Logo
Tim Varley Systems Engineer
Problem #37 hard

Truncatable Primes

The number 37973797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 37973797, 797797, 9797, and 77. Similarly we can work from right to left: 37973797, 379379, 3737, and 33.

Find the sum of the only eleven primes that are both truncatable from left to right and right to left.

Implementations

cpp
// Answer: 748317
// Authored by: Tim Varley πŸ’˜
// Assisted-by: Grok Code Fast via Crush πŸ’˜ <crush@charm.land>
#include <iostream>
#include <vector>
#include <string>
int truncatable_primes() {
const int MAX = 1000000;
std::vector<bool> is_prime(MAX+1, true);
is_prime[0] = is_prime[1] = false;
for(long long i=2; i*i<=MAX; i++) {
if(is_prime[i]) {
for(long long j=i*i; j<=MAX; j+=i) {
is_prime[j] = false;
}
}
}
int sum = 0;
int count = 0;
for(int n=11; n<MAX && count<11; n++) {
if(!is_prime[n]) continue;
std::string s = std::to_string(n);
bool left_ok = true;
for(size_t len=1; len<s.size(); len++) {
std::string left = s.substr(len);
int lnum = std::stoi(left);
if(!is_prime[lnum]) {left_ok=false; break;}
}
if(!left_ok) continue;
bool right_ok = true;
for(int len=s.size()-1; len>0; len--) {
std::string right = s.substr(0,len);
int rnum = std::stoi(right);
if(!is_prime[rnum]) {right_ok=false; break;}
}
if(right_ok) {
sum += n;
count++;
}
}
return sum;
}
#if ! defined UNITTEST_MODE
int main(int argc, char const *argv[]) {
std::cout << truncatable_primes() << std::endl;
}
#endif // UNITTEST_MODE

Solution Notes

Mathematical Background

A truncatable prime remains prime when digits are successively removed from either end. For example, 3797 is truncatable because 3797, 797, 97, 7 are all prime (left truncation), and 3797, 379, 37, 3 are all prime (right truncation).

Single-digit primes (2, 3, 5, 7) are excluded by definition.

Algorithm Analysis

The implementations use the Sieve of Eratosthenes combined with truncation checking:

  • Generate primes up to 1,000,000 using sieve
  • For each prime β‰₯ 11, check all left truncations (remove digits from left)
  • Check all right truncations (remove digits from right)
  • Sum the first 11 primes that satisfy both conditions

Truncation uses string slicing and primality testing.

Performance Analysis

  • Time Complexity: O(n log log n) for sieve + O(Ο€(n) Γ— d Γ— √n) for truncation checks, where Ο€(n) ~ 78,000 and d ~ 6. Total ~10^7 operations, executes in seconds.
  • Space Complexity: O(n) for the sieve array (1M booleans).
  • Execution Time: Fast (1-2 seconds), suitable for batch processing.
  • Scalability: Linear in n for sieve, but primality checks dominate for large n.

Key Insights

  • There are exactly 11 such primes, summing to 748,317
  • All truncatable primes must end with 3, 7, or 9 (can’t end with even digit or 5)
  • Must start with 2, 3, 5, or 7 (can’t start with even digit or 5)
  • The sieve enables O(1) primality lookups for efficiency

Educational Value

This problem teaches:

  • Advanced prime properties and number theory
  • String manipulation and substring operations
  • Combining multiple algorithmic techniques
  • The importance of precomputation (sieve) for performance
  • Systematic checking of multiple conditions