Project Euler Problem 41 Solution
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.
Solution :
We can reduce problem size using the idea that a number will divisible by 3 if the summation of digits of that number is divisible by 3. And if it is true, that number will not be a prime.
Number of digits Summation Divisible by 3
9 1+2+3+4+5+6+7+8+9 = 45 Yes
8 1+2+3+4+5+6+7+8 = 36 Yes
7 1+2+3+4+5+6+7 = 28 No
6 1+2+3+4+5+6 = 21 Yes
5 1+2+3+4+5 = 15 Yes
4 1+2+3+4 = 10 No
As other than 7 digit or 4 digit pandigital number will not be a prime(divisible by 3),We will have to check 7 digit and 4 digit pandigital number only.
Here is the C++ implementation of the solution.
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; #define sz 2767 #define mx 53 bool p[sz]; int primeTable[sz],nPrime = 0; void sieve(){ int i,j; p[0] = p[1] = true; for( i = 4; i <= sz; i += 2 ) p[i] = true; primeTable[nPrime++] = 2; for( i = 3; i <= mx; i += 2 ){ if(!p[i]){ primeTable[nPrime++] = i; for( j = i * i; j <= sz; j += i ) p[j] = true; } } for( i = mx + 2; i <= sz; i += 2 ){ if(!p[i]){ primeTable[nPrime++] = i; } } } bool isPrime(int n){ for(int i = 0; i < nPrime; i++ ) if( n % primeTable[i] == 0) return false; return true; } int main(){ char num[] = "7654321"; //Largest 7 digit pandigital number sieve(); if(isPrime(atoi(num))) printf("%s\n",num); else{ while(prev_permutation( num, num + 7 )){ if(isPrime(atoi(num))){ printf("%s\n",num); break; } } } return 0; }
No comments:
Post a Comment