慢Ruby计算?项目欧拉#5

时间:2013-05-29 04:32:42

标签: ruby optimization

此问题引用了Project Euler Problem 5,所以要小心剧透! 问题5:

  

2520是可以除以1至10中的每个数字而没有任何余数的最小数字。可以被1到20的所有数字整除的最小正数是多少?

我在Ruby中编写了以下代码作为问题5的解决方案。

num = 2520
until (1..20).all?{|x| num % x == 0}
  num += 1
end
puts "#{num}"        

但是,每当我运行脚本时,它就会挂起。请注意,我在基础案例2520上测试了相同的方法,范围为1到10,并且它工作得很好。

为什么它适用于更简单的情况但不适用于更高级的情况?我该怎么做才能解决我的问题?

5 个答案:

答案 0 :(得分:3)

这很慢,因为答案超过了2亿,并且你正在以1的步数计算它。这需要一段时间。你需要一个更好的算法。

答案 1 :(得分:2)

你将无法像对待别人一样强行解决这个问题。您将需要为它找到更有效的解决方案。

这是一种更有效的方法(如果这不像Ruby那样道歉):

def find_multiple
  lcm = 1

  (2..20).each do |i|
    lcm *= i / gcd(lcm, i)
  end

  lcm
end

def gcd(a, b)
  while b > 0
    a %= b
    return b if a == 0
    b %= a
  end

  a
end

puts find_multiple

如果您正在寻找更类似Ruby的解决方法,可以使用以下内容(如评论中的steenslag所示):

(1..20).inject(:lcm)

答案 2 :(得分:1)

游戏有点晚,但这是我的意见。如果你喜欢你的代码 - 它简洁而且非常清晰 - 你可以进行一些小的调整以使其运行得更快。这对我有用,没有超时:

num = 20

  until (11..20).all?{ |i| num % i == 0 }
    num +=20
  end

puts num

基本上你只需增加20秒,因为你知道它需要被20整除,你可以跳过迭代通过集合的下半部分中的任何东西。

答案 3 :(得分:1)

ruby​​语言中最简洁的解决方案。

(1..20).inject(:lcm) # output will be 232792560

答案 4 :(得分:0)

试试这个。 代码:

i=2520
max_product = (4..19).inject(1){|j,k| j*k}
puts max_product
while i < max_product
    if( [3, 7].inject(true) do |memo, p|
        memo && i%p==0
    end)
      if( 
          (4..20).inject(true) do |memo, p|
          memo && i%p==0
          end 
      )   
      puts i
      end 
    end 
    i+=10
end