1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <ctime>
unsigned int cycle_length( unsigned int n ) // n > 0
{
// look up table of cycle lengths
static std::unordered_map< unsigned int, unsigned int > cycle_length_map ;
if( n == 1 ) return 1 ;
// if found it in look up table, return the value
if( cycle_length_map[n] != 0 ) return cycle_length_map[n] ;
// otherwise, compute the cycle length, and return it after memoizing it
else return cycle_length_map[n] = 1 + cycle_length( (n%2) ? (3*n + 1) : (n/2) ) ;
}
unsigned int max_cycle_length( unsigned int low, unsigned int high )
{
unsigned int max_length = 0 ;
for( auto n = low ; n <= high ; ++n )
max_length = std::max( max_length, cycle_length(n) ) ;
return max_length ;
}
int main()
{
const auto start = std::clock() ;
struct input { unsigned int i ; unsigned int j ; } ;
for( input inp : { input{ 1, 10 }, input{ 100, 200 }, input{ 201, 210 }, input{ 900, 1000 }, input { 1, 9'999 } } )
std::cout << inp.i << ' ' << inp.j << ' ' << max_cycle_length( inp.i, inp.j ) << '\n' ;
const auto end = std::clock() ;
std::cout << '\n' << (end-start) * 1000.0 / CLOCKS_PER_SEC << " milliseconds\n" ;
}
| |