Project Euler Homework

037.cpp

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 }
 All Classes Files Functions Variables