/* The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3. Find the sum of the only eleven primes that are both truncatable from left to right and right to left. NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes. */ #include <Windows.h> #include <iostream> #include <vector> using namespace std; typedef unsigned long DWORD; const DWORD size = 1000000; bool prime[size] = {false}; vector<DWORD> primes; bool IsPrime(long long int n) { if (n==1) return false; if (n==2) return true; if(n%2==0) return false; long long int hd=8; long long int lg=6; long long int lh=8; long long int va=n-1; while(va>=hd) { if(!((va-hd)%lg)) return false; lh+=8; lg+=4; hd+=lh; } return true; } bool Problem37(DWORD N) { DWORD tmp = N; int i = 10; int d = 10; while (tmp!=0) { d*=10; tmp /= i; if (!prime[tmp] && tmp!=0) return false; } for (int i=10; i<=d; i*=10) if (!prime[N%i]) return false; return true; } int main() { DWORD start = GetTickCount(); for (int n=1; n<size; n++) { if (IsPrime(n)) { primes.push_back(n); prime[n] = true; } } int count = 0; int sum11 = 0; for (size_t i = 0; i<primes.size(); i++) { if (primes[i]<10) continue; if (Problem37(primes[i])) { cout << primes[i] << endl; sum11 += primes[i]; count++; if (count == 11) { cout << "result = " << sum11<< endl; DWORD end = GetTickCount(); cout << "the running time = " << end - start << " ms." << endl; return 0; } } } return 0; }