【问题标题】:Project Euler #3 Ruby Solution - What is wrong with my code?Project Euler #3 Ruby 解决方案 - 我的代码有什么问题?
【发布时间】:2015-01-16 00:26:19
【问题描述】:

这是我的代码:

def is_prime(i)
    j = 2
    while j < i do 
        if i % j == 0
            return false
        end
        j += 1
    end
true
end

i = (600851475143 / 2)
while i >= 0 do 
    if (600851475143 % i == 0) && (is_prime(i) == true) 
        largest_prime = i
        break 
    end
    i -= 1
end



puts largest_prime

为什么没有返回任何东西?通过所有数字进行的计算是否太大?有没有不使用 Ruby prime 库的简单方法(达不到目的)?

我在网上找到的所有解决方案对我来说都太高级了,有没有初学者能够理解的解决方案?

【问题讨论】:

  • 因为它循环了很多数字。它需要时间来完成。 Project Euler 的目的是提出高效的算法。
  • 查找 Eratosthenes 筛,或任何其他素筛
  • 另一个问题是 Ruby 对Prime 的实现很慢。除此之外,是的,重点是学习算法,而不是通过蛮力解决。
  • 或者只是……Write In C

标签: ruby-on-rails ruby primes factorization


【解决方案1】:

“过早的优化是(万恶之源)”。 :)

在这里,您可以立即找到 (1) 最大的 (2) 素数因子。如何找出所有因数,无论是否是素数,然后然后取最后一个(最大的)素数。当我们解决了那个,我们就可以开始优化它了。

一个数字n 的因子a 使得存在一些b(我们假设a &lt;= b 以避免重复)a * b = n。但这意味着对于a &lt;= b,它也将是a*a &lt;= a*b == n

因此,对于每个b = n/2, n/2-1, ...,潜在的对应因子自动称为a = n / b,根本不需要测试a 的可分性......也许你可以找出as 中的哪一个' 也不必进行 primality 测试。

最后,如果pn的最小质因数,那么n的质因数就是pn / p的所有质因数。对吧?

现在你可以完成任务了。

更新:您可以找到更多讨论和here 之类的伪代码。另外,搜索"600851475143" here on Stack Overflow

【讨论】:

    【解决方案2】:

    我不会给出太多的答案,而是如何寻求答案。

    最优雅的故障排除方法是使用调试器来深入了解实际发生的情况:How do I debug Ruby scripts?

    也就是说,我很少使用调试器——我只是到处插入 put 以查看发生了什么。

    首先添加puts "testing #{i}" 作为循环内的第一行。虽然屏幕 I/O 将比静默计算慢一百万倍,但它至少会让您确信它正在做您认为它正在做的事情,并且可能对整个问题需要多长时间有所了解。或者它可能会显示一个错误,例如计数器没有改变、以错误的方向递增、超出条件中断等。基本的健全性检查内容。

    如果这还没有触发灯泡,请更深入并在 if 语句中使用puts。还没有爆料?接下来放入 is_prime(),然后放入 is_prime() 的循环。你明白了。

    此外,在开发过程中,世界上没有理由以 600851475143 开头! 17、51、100 和 1024 也可以。 (并且不要忘记像 0、1、2、-1 之类的边缘情况,只是为了好玩。)这些都将在您的手指离开回车键之前完成——或者证明您的算法真的永远不会返回并发送给您回到绘图板。

    使用这两种方法,我相信您会在一两分钟内找到答案。祝你好运!

    【讨论】:

    • 600851475143 是问题中的实际数字。这不是关于一般的因式分解,而是针对这个特定的数字。我相信,所使用的算法适用于 1024 年。
    • 我建议您在证明和改进您的算法时,继续测试较小的数字,例如 1024。如果你需要解决的问题需要一个小时或一天或一个月的时间来解决,那么解决一个小答案将需要一秒钟。如果您可以通过多次测试迭代和优化将其降低到 0.5,然后是 0.1,然后是 0.001 秒,那么您真正需要解决的问题可能只需要一秒钟、一分钟或一个小时。使用分析器(ruby-prof、GC:Profiler 等),这样您就可以真正看到 CPU 在哪里,以及您的更改会产生什么影响。
    • 对于运行时预测,我通常使用en.wikipedia.org/wiki/… 方法。
    【解决方案3】:

    你知道你可以用 Ruby 中的一行代码解决这个问题吗?

    Prime.prime_division(600851475143).flatten.max
    
    => 6857
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-30
      • 2016-04-30
      • 1970-01-01
      • 2022-11-29
      • 2013-07-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多