【问题标题】:Algorithm that finds first triangle number with > 500 factors is running to slow找到具有 > 500 个因子的第一个三角形数的算法运行缓慢
【发布时间】:2014-03-24 03:52:31
【问题描述】:

这是我的算法,它找到具有 > x 因子的第一个三角形数。我可以将它运行到大约 x = 150,然后它需要永远。我可以进行哪些更改来加快速度?谢谢!

def triangle_numbers_max_divisors(x)
    triangle_numbers = []
    divisors = 0
    a = 1; b = 2

    until divisors > x
        divisors = 0
        triangle_numbers.push(a)
        a = a + b; b += 1

        for i in 1..triangle_numbers.last
            if triangle_numbers.last % i == 0
                divisors += 1
            end
        end
    end
    triangle_numbers.last
end

【问题讨论】:

  • 你想达到什么目的?你能提供一些预期的输入输出案例吗?

标签: ruby algorithm


【解决方案1】:

看起来您正在尝试解决名为高度可除三角数Problem number 12 of the Project Euler

我已经尝试改进您的代码,但不幸的是,您的解决方案本身很慢且效率低下,如果不改变方法就无法从根本上改进。看看这个solution 和这个SO thread

【讨论】:

    【解决方案2】:

    您的代码运行缓慢的原因已在其他答案中给出。这是一种类似 Ruby 的算法编码方式。大约需要 10 秒才能解决。*

    代码

    def triangle_numbers_max_divisors(min_nbr_factors)
      (1..Float::INFINITY).reduce(0) do |tnbr, n|
        tnbr += n
        return tnbr if nbr_factors(tnbr) >= min_nbr_factors
        tnbr
      end
    end
    
    def nbr_factors(n)
      m = Math.sqrt(n)
      2 * 1.upto(m).count { |i| (n % i).zero? } - ((n == m * m) ? 1 : 0)
    end   
    
    p triangle_numbers_max_divisors(500) #=> 76_576_500
    

    说明

    • 您只需要一个值,因此无需保留除数。数一数。
    • 如果 n 是一个完全平方,则术语 - ((n == m * m) ? 1 : 0 会导致 n 的平方根只计算一次。
    • 有时你会看到(1..Float::INFINITY)写成(1..1.0/0)

    。 * 在最近的老式 Macbook Pro 上

    【讨论】:

      【解决方案3】:

      我不知道this 是否是最新的,但重新分配数组空间时似乎存在问题。在 127 处,您的代码只需要大约 6 秒即可运行,然后在 128 处跳转到 30 秒。它再次稳定了一段时间。

      如果您使用triangle_numbers = Array.new(x) 之类的东西预先分配数组,您将失去简洁的.last 语法,并且必须跟踪数组索引,但代码在大致二次时间内运行。这意味着每次增加它仍然会变得不成比例地变慢,但是您对此无能为力,而且您不应该遇到任何奇怪的不连续性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-10
        • 2013-03-22
        • 2018-03-17
        • 1970-01-01
        相关资源
        最近更新 更多