简体   繁体   中英

Project Euler Solution #14

I have the following problem (from ProjectEuler.net - Problem 14 )

The following iterative sequence is defined for the set of positive integers:

n -> n/2 (n is even)
n -> 3n + 1 (n is odd)

Using the rule above and starting with 13, we generate the following sequence:

13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1

It can be seen that this sequence (starting at 13 and finishing at 1 ) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1 .

Which starting number, under one million, produces the longest chain?

NOTE: Once the chain starts the terms are allowed to go above one million.

I used:

   static int road (int n)
   {
       int road = 0;
       while (n != 1)
       {
           if (n % 2 == 0)
               n = n / 2;
           else
               n = 3 * n + 1;
           road++;
       }
       return road;
   }
   static void Main(string[] args)
   {
       int max = 0, num = 0;
       for (int i = 1; i < 1000000; i++)
       {
           if (road(i) > max)
           {
               max = road(i);
               num = i;
           }
       }
       Console.WriteLine(num);
   }

But no output is printed.

(I'm not going to give you a complete solution since Project Euler is intended to make you think, not us who already solved the problems.)

Try figuring out how large the values in your chain are going to be and keep in mind the limits for integral types .

function problem14(){

    function r(p,n){
        return cl(p)>cl(n)?p:n;
    }

    function c(n){
        return n%2===0?n/2:3*n+1;
    }

    function cl(n){
        var _a = 1;
        var _n = n;
        while(_n !== 1){
            _a++;
            _n = c(_n);
        }
        return _a;
    }

    var b = [];
    var m = 20;
    var i = 500000;
    while(i < 1000000){
        var _n = cl(i);
        if(_n>m){
            b.push(i);
            m = _n;
        }
        i++;
    }

    return b.reduce(r);

}

Here is my js code.

It is not that "nothing is output", it is just running very long. If you change the upper bound of the for-loop to 100000, you will see that pretty quickly you get output. The reason it runs very long is that you use unchecked integers and you don't get an overflowexception where you should want one. Break after a few seconds an you'll see a negative n .

Try the following , ie with the checked keyword, it will illustrate what I mean:

// will now throw OverflowException with large n
checked
{
    int road = 0;
    while (n != 1)
    {
        if (n%2 == 0)
            n = n/2;
        else
            n = 3*n + 1;
        road++;
    }
    return road;
}

First, note that you are calling the road() function twice per iteration, which is a waste of processing time (and for a 'function with side effects', could have unwanted consequences).

Secondly, due to integer overflow, you can't get an answer - the value 113383, for example, ends up cycling around the same 20 or so numbers

-122, -61, -182, -91, -272, -136, -68, -34, -17, -50, -25, -74, -37, -110, -55, ,-164, -82, -41, -122

Oops!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM