Project Euler task 37

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 < iostream >
#include < vector >
#include < math.h >
#include < time.h >

using namespace std;

const int pow10[] = { 1, 10, 100, 1000, 10000, 10000, 1000000, 10000000, 100000000 };

bool isPrime(int _iNum) {
if (_iNum <= 1 || (_iNum > 2 && _iNum % 2 == 0) || (_iNum > 5 && _iNum % 10 == 5))
return false;

for (int i = 2; i <= (int) sqrt((double) _iNum); i++)
if (_iNum % i == 0)
return false;

return true;
}

bool isTruncatable(int _iNum) {
if (_iNum <= 10)
return false;

int iTemp = _iNum % 10;
if (iTemp == 4 || iTemp == 6 || iTemp == 8 || iTemp == 1 || iTemp == 9)
return false;

vector vNum;

// right
iTemp = _iNum;
while (iTemp) {
vNum.push_back(iTemp % 10);

if (!isPrime(iTemp))
return false;

iTemp /= 10;
}

int iMaxDec = vNum.back();
if (iMaxDec == 4 || iMaxDec == 6 || iMaxDec == 8 || iMaxDec == 1 || iMaxDec == 9)
return false;

// left !!! TODO !!!
for (size_t i = vNum.size() - 1; i >=1; i--) {
int iTarg = 0;
for (size_t j = 0; j < i; j++)
iTarg += pow10[j] * vNum[j];
if (!isPrime(iTarg))
return false;
}

return true;
}

int main() {
int i = 0;
int k = 11;
int iSum = 0;

time_t fStart = time(0);
while (i < 11) {
if (isTruncatable(k)) {
cout << k << endl;
iSum += k;
i++;
}
k++;
}
double fDiffTime = difftime(time(0), fStart);

cout << "Sum: " << iSum << endl;
cout << "Time: " << fDiffTime << endl;

return 0;
}

Comments

Popular Posts