Guest User

Untitled

a guest
Apr 21st, 2018
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.75 KB | None | 0 0
  1. // Project Euler 14
  2.  
  3. #include "stdafx.h"
  4. #include <iostream>
  5. #include <time.h>
  6. using namespace std;
  7.  
  8. #define UPPERLIMIT 1000000                           //the main number
  9. #define DRAWDOTEVERY 100000                          //this number is 10 times smaller than UPPERLIMIT,
  10. #define DICSIZE (UPPERLIMIT * 10)                    // so 10 dots are drawn
  11. #define ul unsigned long
  12.  
  13. ul startingNumber, maxValue = 0, currentResult, result, i, x;
  14. ul dic[DICSIZE] = {0};
  15. clock_t t1;
  16.  
  17. ul getChainSlow(ul n) {                              //this might actually be faster than getChainFast:
  18.     result = 0;                                      // compilers tend to optimize code
  19.     while(true) {
  20.         result++;
  21.         if (n == 1) break;
  22.         else if (n%2 == 0) n /= 2;
  23.         else n = n*3 + 1;
  24.     }
  25.     return result;
  26. }
  27.  
  28. ul getChainFast(ul n) {                              //bitwise operations are much faster than math
  29.     result = 0;
  30.     while(true) {
  31.         result++;
  32.         if (n == 1) break;
  33.         else if (n&1) n = (n<<1) + n + 1;            //n ends with 1  ->  n*2 + n + 1 = 3*n + 1
  34.         else n>>=1;                                  //n ends with 0  ->  n/2 (n = (n>>1))
  35.     }
  36.     return result;
  37. }
  38.  
  39. ul getChainUltraFast(ul n) {
  40.     result = 0;
  41.     x = n;                                           //n needs to be preserved in this function
  42.     while(true) {                                    //we could do without the while if x couldn't go up
  43.         result++;
  44.         if (x == 1) break;
  45.         else if (x&1) x = (x<<1) + x + 1;
  46.         else x>>=1;
  47.         if ((x<DICSIZE) && dic[x]) {                 //if the current x is in the dictionary,
  48.             result += dic[x];                        // use this chain number instead of iterating
  49.             break;
  50.         }
  51.     }
  52.     dic[n] = result;                                 //store the new value. as n only gets bigger,
  53.     return result;                                   // this will never owerwrite anything
  54. }
  55.  
  56. void calculate(ul (*func)(ul)) {                     //"ul (*func)(ul)" is the way to define a pointer to a function
  57.     t1 = clock();                                    // that takes one ul (unsigned long) param and returns one ul number
  58.     for(i=1; i<UPPERLIMIT; i++) {
  59.         if (i%DRAWDOTEVERY == 0) cout << ".";        //this loop actually prints 9 dots for 100000->900000
  60.         currentResult = func(i);                     // there is one dot printed before these 9 dots, so
  61.         if (currentResult > maxValue) {              // there are 10 dots after all
  62.             maxValue = currentResult;                // NOTE that outputting dots slows the execution significantly
  63.             startingNumber = i;                      // such output shouldn't be used often
  64.         }
  65.     }
  66.     cout << "\nStarting number that produces maximum chain = " << startingNumber;
  67.     cout << "\nRuntime = " << ((ul)clock()-(ul)t1) << " clock ticks\n";
  68.  
  69. }
  70.  
  71. int _tmain(int argc, _TCHAR* argv[]) {
  72.     cout << "This program searches for the number chain of maximum length,\n";
  73.     cout << "where the starting number is less than " << UPPERLIMIT << "\n";
  74.    
  75.     cout << "\nCalculating using the slow function.";
  76.     calculate(&getChainSlow);                        //we pass pointers to functions as arguments
  77.                                                      // calculate will use these functions
  78.     cout << "\nCalculating using the function that does bitwise operations.";
  79.     calculate(&getChainFast);                        // in it's loop
  80.    
  81.     cout << "\nCalculating using the function that uses an array.";
  82.     calculate(&getChainUltraFast);
  83.    
  84.     cin >> maxValue;                                 //wait for input. the only dirty hack
  85.     return 0;
  86. }
Add Comment
Please, Sign In to add comment