Ruby - Project Euler#23运行时间过长

时间:2014-03-23 16:57:40

标签: ruby

我对ruby很新,只是想了解它,我试图解决一些项目的euler问题。 我目前坚持的是#23问题。

链接:http://projecteuler.net/problem=23

问题是红宝石解决方案一直在运行,我累了等待。

解决方案:

def check(n)
  s=0
  for i in (1..(n/2)+1)
    if n % i == 0 then
      s+=i
    end
  end

  if s>n then
    return true

  end
end

def abundant()
  sum = 0
  for j in (1..28123)
    for k in (1..28123)
      ans = check(j)
      ans2 = check(k)
      if ans == true and ans2 == true then
        sum += (j + k)
      end    

    end
  end
  return sum
end        

a = abundant()
puts a

任何帮助将受到高度赞赏! 谢谢!

行。 所以我稍后会做一些缓存。 但我做了一些自己的尝试来减少循环。

这是现在的代码:

def check(n)
  s=0
  for i in (1..(n/2)+1)
    if n % i == 0 then
      s+=i
    end
  end

  if s>n then
    return true
  else
    return false

  end
end

def abundant()
  sum = 0
  for j in (1..28123)
    ans = check(j)
    if ans == false then
      for k in (j..28123)
        ans2 = check(k)
        if ans2 == false then
          sum += (j+k)
        end

      end  
    end
  end
end  

a = abundant()
puts a

1 个答案:

答案 0 :(得分:0)

您应该尝试缓存结果 - 如果您已经计算过13453是否为素数,则不必再次检查:

@cache = {}
def check(n)
  if @cache[n].nil?
    s=0
    for i in (1..(n/2)+1)
      if n % i == 0 then
        s+=i
      end
    end

    @cache[n] = s>n
  end
  @cache[n]
end

def abundant()
  sum = 0
  for j in (1..28123)
    for k in (1..28123)
      ans = check(j)
      ans2 = check(k)
      if ans == true and ans2 == true then
        sum += (j + k)
      end    

    end
  end
  return sum
end        

a = abundant()
puts a

这样做是在Hashtable中保存每个结果(无论数字是否为素数),在进行计算之前,它首先检查结果是否已经在Hashtable的{​​{1}}中保存的号码。这就是caching的含义。

如果你读了你的代码,你会看到你计算每个数字是否是28124(!)次(对于内循环中的每次迭代一次,加上j==k时的一次),这个很多次,并且计算量很大......你重新计算每个数字这么多次的事实使你的代码比缓存结果慢几个数量级。