Saturday, September 19, 2009

3n+1 problem

The Problem

Consider the following algorithm:
1. input n 2. print n
3. if n = 1 then STOP
4. if n is odd then  n = 3*n+1
5. else    n = n/2
6. GOTO 2

Given the input 22, the following sequence of numbers will be printed 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1

It is conjectured that the algorithm above will terminate (when a 1 is printed) for any integral input value. Despite the simplicity of the algorithm, it is unknown whether this conjecture is true. It has been verified, however, for all integers n such that 0 < n < 1,000,000 (and, in fact, for many more numbers than this.)
Given an input n, it is possible to determine the number of numbers printed (including the 1). For a given n this is called the cycle-length of n. In the example above, the cycle length of 22 is 16.

For any two numbers i and j you are to determine the maximum cycle length over all numbers between i and j
Normal non recursive method
#include
using namespace std;

int main()
{

    unsigned int i, j;

    int count, cmax;  

    int process(int x);

    cout<<"Enter range:\nFrom:";
    cin>>i;

    cout<<"\nTo: ";
    cin>>j;
    cout<<<" "<


    for(;i<=j;i++)    {            

                  count=process(i); 

                  if(count>cmax)
                  cmax=count;          
    }

    cout<<" "<  
    return 0;
}

int process(int x)
{
     int count;
 

     for(count=1;x!=1;++count)
     {                  
                            if(x%2==0)
                                 x/=2;
                            else
                               x=3*x+1;

   }
     return count;

}


Recursive Solution
#include <stdio.h>
#define SIZE 1000001

static unsigned short table[SIZE];

unsigned short calcCycleLength(register unsigned long n )
{
if(n < SIZE && table[n])
return table[n];
if(n & 1){ /* if n is odd */
if( n < SIZE) {
table[n] = 2 + calcCycleLength( (3*n+1) >> 1 ); /* calc two steps at one */
return table[n];
}
else
return 2 + calcCycleLength( (3*n+1) >> 1 );

}
else {
if( n < SIZE) {
table[n] = 1 + calcCycleLength( n >> 1 ); /* n/2 */
return table[n];
}
else
return 1 + calcCycleLength( n >> 1 );
}
}

int main()
{
unsigned long i, fstIn, sndIn;
short out = 0, temp;

table[1] = 1;

while ( scanf("%lu %lu", &fstIn, &sndIn ) != EOF )
{
if( fstIn > sndIn) {
for( i = sndIn; i <= fstIn; ++i )
{
temp = calcCycleLength( i );
if( temp > out)
out = temp;
}
}
else {
for( i = fstIn; i <= sndIn; ++i )
{
temp = calcCycleLength( i );
if( temp > out)
out = temp;
}
}
printf("%lu %lu %hdn", fstIn, sndIn, out);
out = 0;
}
return 0;
}

No comments:

Post a Comment