简体   繁体   English

项目欧拉解决方案#14

[英]Project Euler Solution #14

I have the following problem (from ProjectEuler.net - Problem 14 ) 我有以下问题(来自ProjectEuler.net - 问题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开始,我们生成以下序列:

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. 可以看出,该序列(从13开始并在1 )包含10个项。 Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1 . 虽然尚未证实(Collat​​z问题),但据认为所有起始数字都是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. 这是我的js代码。

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. 如果将for循环的上限更改为100000,您将很快看到输出。 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 . 几秒后打破,你会看到负面的n

Try the following , ie with the checked keyword, it will illustrate what I mean: 尝试以下方法,即使用checked关键字,它将说明我的意思:

// 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). 首先,请注意您每次迭代都会调用road()函数两次,这会浪费处理时间(对于“带有副作用的函数”,可能会产生不必要的后果)。

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 其次,由于整数溢出,你无法得到答案 - 例如,值113383最终在相同的20左右数字周围循环

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

Oops! 哎呀!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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