Project Euler Homework

021.cpp

Go to the documentation of this file.
00001 
00009 #include <iostream>
00010 using namespace std;
00011 
00012 /* Find smallest prime factor*/
00013 unsigned
00014 factor (unsigned *N, unsigned k0 = 3)   
00015 {
00016   if (!(*N & 1))                //multiple of 2
00017     {
00018       *N >>= 1;                 //faster than *N/=2
00019       return 2;
00020     }
00021 
00022   for (unsigned k = k0; k <= *N; k++)
00023     if (*N % k == 0)
00024       {
00025         *N /= k;
00026         return k;
00027       }
00028   return 1;
00029 }
00030 
00031 /*calculate p^0+p^1+...+p^k*/
00032 unsigned
00033 term (unsigned p, unsigned k)
00034 {
00035   unsigned t = 1;
00036   for (unsigned i = 1; i <= k; i++)
00037     {
00038       t = t * p + 1;
00039     }
00040   return t;
00041 }
00042 
00043 /* sum of all divisors of n except n */
00044 unsigned
00045 d (unsigned N)
00046 {
00047   unsigned answer = 1;
00048 
00049   unsigned previous_prime = 2;  //modified from 012.cpp
00050   unsigned power = 0;
00051 
00052   unsigned r = N;
00053   unsigned div = 2;
00054   do
00055     {
00056       div = factor (&r, div);
00057       if (div == previous_prime)
00058         power++;
00059       else                      //determined the power of the previous prime factor
00060         {
00061           answer *= term (previous_prime, power);
00062 
00063           previous_prime = div;
00064           power = 1;
00065         }
00066       //cout << div<<','<<answer<<' ';
00067     }
00068   while (div > 1);
00069 
00070   answer -= N;                  //exclude N itself from the sum
00071   return answer;
00072 }
00073 
00074 /*memorize impossible integers*/
00075 class lookup_table
00076 {
00077   bool x[10000];
00078 public:
00079     lookup_table ()
00080   {
00081     bool *p = x;
00082     for (unsigned i = 0; i < 10000; i++, p++)
00083        *p = 0;
00084   }
00085   bool exception (unsigned k)
00086   {
00087     return x[k];
00088   }
00089   void push (unsigned k)
00090   {
00091     x[k] = 1;
00092   }
00093 };
00094 
00095 int
00096 main ()
00097 {
00098 
00099   unsigned Sum = 0;
00100   lookup_table table;
00101 
00102   for (unsigned a = 3; a < 10000; a++)
00103     {
00104       if (table.exception (a))
00105         continue;
00106       unsigned b = d (a);
00107       if (b == a || b >= 10000)
00108         continue;
00109       if (d (b) == a)
00110         {
00111           Sum += a + b;
00112           table.push (b);       //so b will never appear again
00113           //cout << a << ' '<<b << ' ';
00114         }
00115       else if (b > a && b < 10000)      //add an exception to reduce computation time
00116         table.push (b);
00117     }
00118 
00119   cout << Sum << endl;
00120   return 0;
00121 }
00122 
 All Classes Files Functions Variables