迭代数组(Project Euler#23)

时间:2013-04-02 16:25:17

标签: ruby arrays iteration

我有以下代码

#!/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:在-': nil can't be coerced into Fixnum (TypeError)
from euler23:21:in
块(2级)中         来自euler23:20:在each'
from euler23:20:in
块中         来自euler23:19:each'
from euler23:19:in
'

由于我不熟悉Ruby,我解决这个问题的各种尝试都是徒劳的。我觉得我需要包含一些库,但我的研究没有提到任何库,我不知所措。此代码用于将所有不能写入的数字相加为两个数字的总和;它是twenty third question from Project Euler

2 个答案:

答案 0 :(得分:6)

执行此操作时:

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 next,或者throw and catch - 不用于Ruby中的错误处理 - 跳转到特定的嵌套循环级别。

答案 1 :(得分:3)

以下代码有问题:

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>'