Project Euler Homework
|
00001 #include <iostream> 00002 using namespace std; 00003 00004 const unsigned MAX = 1000000; 00005 class prime_table 00006 { 00007 bool x[MAX]; 00008 public: 00009 prime_table(); 00010 bool has(unsigned k); 00011 unsigned next(unsigned n); 00012 unsigned count(); 00013 void filter1(); 00014 void filter2(); 00015 }; 00016 00017 prime_table::prime_table() 00018 { 00019 //assume all except 0,1 are prime 00020 x[0]=x[1]=0; 00021 for (bool* p=x+2;p-x<MAX;p++)*p=1; 00022 00023 for (unsigned n = 2; n < MAX;n = next(n)) { 00024 unsigned idx=n+n; 00025 while (idx < MAX) { 00026 x[idx]=0; 00027 idx+=n; 00028 } 00029 } 00030 } 00031 00032 unsigned prime_table::next(unsigned n) 00033 { 00034 if (n>=MAX)return MAX; 00035 bool* p = x+n; 00036 do { 00037 p++; 00038 if (*p)return (p-x); 00039 } while (p-x < MAX); 00040 return MAX; 00041 } 00042 00043 bool prime_table::has(unsigned k) 00044 { 00045 return x[k]; 00046 } 00047 00048 unsigned prime_table::count() 00049 { 00050 unsigned cnt=0; 00051 for (unsigned i=2;i<MAX;i=next(i)) 00052 cnt++; 00053 return cnt; 00054 } 00055 void prime_table::filter1() 00056 { 00057 for (unsigned i=next(9);i<MAX;i=next(i)) 00058 for (unsigned j=i/10;j>0;j/=10) 00059 if (!has(j)) { 00060 x[i]=0; 00061 break; 00062 } 00063 } 00064 00065 unsigned order_of_magnitude(unsigned k) 00066 { 00067 unsigned M; 00068 for (M=1;M<=k;M*=10); 00069 return M/10; 00070 } 00071 void prime_table::filter2() 00072 { 00073 for (unsigned i=next(9);i<MAX;i=next(i)) { 00074 00075 unsigned M = order_of_magnitude(i); 00076 for (unsigned j=i%M;j>0;M/=10,j%=M) 00077 if (!has(j)) { 00078 x[i]=0; 00079 break; 00080 } 00081 00082 } 00083 } 00084 00085 int main() 00086 { 00087 prime_table primes_right; 00088 prime_table primes_left; 00089 00090 primes_right.filter1(); 00091 primes_left.filter2(); 00092 00093 //set intersection 00094 unsigned sum=0; 00095 for(unsigned i=primes_right.next(10);i<MAX;i=primes_right.next(i)) 00096 if(primes_left.has(i)) 00097 sum+=i; 00098 00099 cout << sum << endl; 00100 return 0; 00101 }