【问题标题】:Iterating through an array (Project Euler #23)遍历数组(Project Euler #23)
【发布时间】:2013-03-24 01:14:19
【问题描述】:

我有以下代码

#!/usr/bin/ruby -w
c = 1
d = Array.new(6965)  #6965 is the amount of abundant numbers below 28123 of which all numbers greater than that can be written as the sum of two abundant numbers
f = 0
while c < 28124      # no need to go beyond 28123 for this problem
  a = 0
  b = 1
  i = true           # this will be set to false if a number can be written as the sum of two abundant numbers
  while b <= c/2 + 1 # checks will go until they reach just over half of a number
    if c % b == 0    # checks for integer divisors
      a += b         # sums integer divisors
    end
    b += 1           # iterates to check for new divisor
  end
  if a > c           # checks to see if sum of divisors is greater than the original number
    d << c           # if true it is read into an array
  end
  d.each{|j|         # iterates through array
    d.each{|k|       # iterates through iterations to check all possible sums for number
                     # false is declared if a match is found. does ruby have and exit statement i could use here?
      i = false if c - j - k == 0
    }
  }
  c+=1               # number that we are checking is increased by one
                     # if a number cannot be found as the sum of two abundant number it is summed into f
  f += c if i == true
end
puts f

对于以下代码,每当我尝试对我的d 数组进行双重迭代时,都会出现以下错误:

euler23:21:in -': nil can't be coerced into Fixnum (TypeError)
from euler23:21:in
block (2 层) in '
来自 euler23:20:in each'
from euler23:20:in
block in '
来自 euler23:19:in each'
from euler23:19:in
'

由于我对 Ruby 不熟悉,因此我为解决此问题所做的各种尝试都是徒劳的。我感觉有些库我需要包含,但我的研究没有提到任何库,我很茫然。这段代码旨在将所有不能写成两个丰富数字之和的数字相加;它是twenty third question from Project Euler

【问题讨论】:

  • 你能说一下算法,它将执行什么任务。请在您的帖子中提及这一点。以便我们为您提供更好的解决方案。
  • 我很想复制我对这个问题的答案...:/
  • 该算法是找到28123以下的所有丰富的数字并将它们放入一个数组中,因为它访问该数组并检查是否可以从任何两个之和中得出一个数字到目前为止我发现的大量数字中,如果不能,它们会被加总
  • 除了清理格式和语法之外,我还添加了一个指向 Project Euler 问题 #23 的链接。
  • 一旦你得到了完成这项工作的答案,你可以访问codereview.stackexchange.com,这不是你应该写代码的方式,至少不是在 Ruby 中。

标签: ruby arrays iteration


【解决方案1】:

当你这样做时:

d = Array.new(6965)

您创建了一个包含 6965 个 nil 值的数组。

如果在第 21 行之前添加此测试代码:

p [c,j,k]

然后你得到结果:

[1, nil, nil]

这表明jk 都是nil 值。您正在遍历数组中的空项。

如果您将 d 的创建更改为:

d = [] # an empty array, which in Ruby can change size whenever you want

...然后您的代码运行。 (我没有让它运行足够长的时间来查看它是否运行正确,但它至少运行了相当长一段时间没有错误。)


最后,一些随机风格的建议:

这段代码:

while b <= c/2 + 1
  if c % b == 0
    a += b
  end
  b += 1
end

可以更简洁和更 Ruby-esque 重写为:

b.upto(c/2+1){ a+=b if c%b==0 }

同样,这个循环:

c=1
while c < 28124
  # ...
  c += 1
end

可以改写为:

1.upto(28123) do |c|
  # ...
end

当您询问中断循环时,您可以酌情使用break or nextthrow and catch(在 Ruby 中不用于错误处理)来跳转到特定的嵌套循环级别。

【讨论】:

  • 谢谢,我已经修复了错误,我现在正在运行它以获得结果,但到目前为止没有错误
  • 请注意,(您可能知道)许多欧拉计划问题的设计方式使得对答案的最简单的蛮力计算可能无法及时完成。 (天知道我已经让许多 Euler 程序在一夜之间运行,希望简单的解决方案能够工作。)我不确定您的代码是否属于蛮力类型,但如果在 Ruby 中需要超过几分钟,可能有更优雅的方法来解决问题。
  • 是的,我的总的想法是让代码工作,然后一旦我开始工作,我会改进并提高效率
  • 所以我已经用你的编辑运行了我的代码六次,我不知道为什么,但它确实很好,直到 c = 2240 和 f = 669038 然后它冻结了
【解决方案2】:

下面的代码有问题:

d.each{|j|                     
d.each{ |k|             
p c,j,k  #1,nil,nil
i = false if c - j - k == 0 }}

因为:

1 - nil - nil
#TypeError: nil can't be coerced into Fixnum
#      from (irb):2:in `-'
#      from (irb):2
#     from C:/Ruby193/bin/irb:12:in `<main>'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-14
    • 1970-01-01
    • 2013-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多