找到带有>的第一个三角形数字的算法500个因素正在放缓

时间:2014-03-23 02:14:27

标签: ruby algorithm

这是我的算法,找到带有>的第一个三角形数字。 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

3 个答案:

答案 0 :(得分:3)

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

我试图改进你的代码,但遗憾的是你的解决方案本身速度慢且效率低,如果不改变方法就不能从根本上改进。请查看此solution以及此SO thread

答案 1 :(得分:2)

我不知道this是否是最新的,但是重新为数组重新分配空间似乎存在问题。在127,你的代码只需要大约6秒钟就可以运行,然后在128处跳到30秒。它会再次关闭一段时间。

如果你使用类似triangle_numbers = Array.new(x)的预先分配数组,你将失去简洁的.last语法,并且必须跟踪数组索引,但是代码在大约两倍的时间内运行板。这意味着每次增加它的速度仍会不成比例地变慢,但是你可以做的并不多,你不应该碰到任何奇怪的不连续性。

答案 2 :(得分: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上