为什么我的代码不会停止运行?

时间:2010-06-04 12:27:03

标签: ruby infinite-loop

我正在尝试解决Project Euler中的Problem #5问题。该代码适用于该示例,当我检查从1到10的数字时,我得到2520,这是正确的。但是当我检查从1到20的数字时,代码不会停止运行。

这是:

num = 0

while true

    num += 1
    check = true

    for i in 1..20

        break unless check

        check = num%i==0

    end

    break if check

end

File.open("__RESULT__.txt", "w+").write num

3 个答案:

答案 0 :(得分:11)

仅通过计算每个可能的解决方案无法找到解决该问题的方法。解决方案太大了,计算需要几天(可能是几年)。

有一个更智能的解决方案,使用素数来记下数字。

给出的示例(2520是可由1到10除数的最小数字)可以这样写下:

1 = 1 (can be skipped)  = 2^0 * 3^0 * 5^0 * 7^0
2 = 2 (prime)           = 2^1 * 3^0 * 5^0 * 7^0
3 = 3 (prime)           = 2^0 * 3^1 * 5^0 * 7^0
4 = 2^2                 = 2^2 * 3^0 * 5^0 * 7^0
5 = 5 (prime)           = 2^0 * 3^0 * 5^1 * 7^0
6 = 2 * 3               = 2^1 * 3^1 * 5^0 * 7^0
7 = 7 (prime)           = 2^0 * 3^0 * 5^0 * 7^1
8 = 2^3                 = 2^3 * 3^0 * 5^0 * 7^0
9 = 3^2                 = 2^0 * 3^2 * 5^0 * 7^0
10= 2 * 5               = 2^1 * 3^0 * 5^1 * 7^0

现在可以除以这些数字的最小数字可以通过使用每个素数上使用的最大功率来计算:

2^3 * 3^2 * 5^1 * 7^1 = 2520

对于数字1到20

,可以执行相同的操作(甚至是手动操作)

最后提示:答案大于100.000.000但不到十亿,所以如果有效地完成 可以在几分钟内计算

答案 1 :(得分:0)

问题基本上要求您找到前20个数字的最小公倍数...

lcm = 1
for i = 2 to 20
   lcm = (i * lcm) / gcd(lcm,i)

答案 2 :(得分:0)

一个更简单的解决方案是使用你的算法,但增加2520而不是1,这是我的C ++解决方案。

#include <iostream>
using namespace std;

int main()
{
    int check = 2520;
    int i = 11;
    while (i != 20)
    {
        i ++;
        if (check % i != 0)
        {
            check +=2520;
            i = 1;
        }
    }
    cout << check << endl;
    return 0;
}

正如您在上面所看到的,我也从数字2520开始,并将i设置为等于11.我们可以进行这些优化,因为我们已经在问题中获得了必要的信息。