【问题标题】:Why won't my code stop running?为什么我的代码不会停止运行?
【发布时间】:2010-06-04 12:27:03
【问题描述】:

我正在尝试解决 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

【问题讨论】:

  • Marc 已经给出了完美的答案。或者:由于每个数字都必须能被 20 整除,num += 20 将为您提供 20 倍的加速。另外,请使用for i in 2..20,因为每个数字都可以被 1 整除
  • 作为风格说明:您的代码可以更惯用地写成inf = 1.0/0.0; num = (1..inf).find {|n| (1.20).all? {|i| x%i == 0}} - 但这不会改变计算时间过长的事实。
  • 刚刚检查了我在 Ruby 中提出的稍微优化的版本。这里大约需要 1 分钟,这很难达到 Project Euler 的限制,并且比我在 2 秒内完成相同操作的 C++ 版本慢得多。

标签: ruby infinite-loop


【解决方案1】:

仅通过计算所有可能的解决方案无法找到该问题的解决方案。解是如此之大,以至于需要数天(甚至数年)才能计算出来。

有一个更聪明的解决方案是使用素数来记下数字。

给出的示例(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 但不到 10 亿,所以如果有效地完成,可以在几分钟内计算出来

【讨论】:

  • 谢谢!我首先是手工完成的(在阅读了我们的答案之后),然后优化了我的代码,现在两种方式都可以!
【解决方案2】:

问题本质上是要求您找到前 20 个数字的 LCM...

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

【讨论】:

    【解决方案3】:

    一个更简单的解决方案是使用您的算法,但增量为 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。我们可以进行这些优化,因为我们已经在问题中获得了必要的信息。

    【讨论】:

      猜你喜欢
      • 2022-11-26
      • 1970-01-01
      • 1970-01-01
      • 2011-04-06
      • 2018-08-03
      • 2015-07-30
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多