Project Euler Problem 41
阿新 • • 發佈:2018-11-02
Problem 41 : Pandigital prime
We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once. For example, 2143 is a 4-digit pandigital and is also prime.
What is the largest n-digit pandigital prime that exists?
#include <iostream>
#include <cmath> // sqrt()
#include <algorithm> // sort()
#include <cassert> // assert()
using namespace std;
class PE0041
{
private:
static const int m_max = 10000000; // ten million
bool *m_primeSieve;
static const int max_digits = 9; // 1,2...,9
int m_digits[max_digits];
int m_numOfDigits;
void getDigits(int number);
void createPrimeSieve();
bool checkPrime(int number);
bool checkPandigital(int number);
public:
PE0041() { m_primeSieve = new bool [m_max]; createPrimeSieve(); }
~PE0041() { delete [] m_primeSieve; }
int getNumOfDigits() const { return m_numOfDigits; }
int findLargestPandigitalPrime();
};
// create a prime Sieve of Eratosthenes below max value
void PE0041::createPrimeSieve()
{
memset(m_primeSieve, true, m_max*sizeof(bool));
m_primeSieve[0] = m_primeSieve[1] = false;
for (int i=2; i<=(int)sqrt((double)m_max); i++)
{
if (true == m_primeSieve[i])
{
for (int j=i*i; j<m_max; j+=i)
{
m_primeSieve[j] = false;
}
}
}
}
void PE0041::getDigits(int number)
{
m_numOfDigits = 0;
while (number > 0)
{
m_digits[m_numOfDigits++] = number%10;
number /= 10;
}
}
bool PE0041::checkPrime(int number)
{
return m_primeSieve[number];
}
bool PE0041::checkPandigital(int number)
{
getDigits(number);
sort(m_digits, m_digits+m_numOfDigits);
for (int i=1; i<m_numOfDigits; i++) // look like 1 2 3 4 ...
{
if (m_digits[i-1] != i)
{
return false;
}
}
return true;
}
int PE0041::findLargestPandigitalPrime()
{
// if the sum of digits of one number x is divided by 3,
// the number x is not a prime.
//
// 1+2+3+4+5+6+7+8+9 = 45 = 3 * 15, x=3k is not a prime
// 1+2+3+4+5+6+7+8 = 36 = 3 * 12, x=3k is not a prime
// 1+2+3+4+5+6 = 21 = 3 * 7, x=3k is not a prime
// 1+2+3+4+5 = 15 = 3 * 5, x=3k is not a prime
// 1+2+3 = 6 = 3 * 2, x=3k is not a prime
// 1+2 = 3 = 3 * 1, x=3k is not a prime
//
// 1+2+3+4+5+6+7 = 28 <> 3k
// 1+2+3+4 = 10 <> 3k
int number = 2143; // 4-digit pandigital prime
assert(true == checkPrime(number) && true == checkPandigital(number));
for (number=7654321; number>=1234567; number--)
{
if (true == checkPrime(number) && true == checkPandigital(number))
{
break;
}
}
return number;
}
int main()
{
PE0041 pe0041;
int number = pe0041.findLargestPandigitalPrime();
cout << number << " is the largest " << pe0041.getNumOfDigits();
cout << "-digit pandigital prime that exists." << endl;
return 0;
}