Ruby - Select()

时间:2015-05-25 09:42:49

标签: ruby math functional-programming

我正在做www.eulerproject.net,这是第一个问题:

  

如果我们列出10以下的所有自然数,则为3的倍数   或者5,我们得到3,5,6和9.这些倍数的总和是23.找到   所有3或5的倍数的总和低于1000。

以下是我到目前为止的代码。

(3..999).to_a.select do |x|
   x % 3.0 == 0 || x % 5.0 == 0
end

将数字附加到数组中会很容易,但是如何通过将方法链接到数组来完成此操作呢?像

这样的东西
p start loop
  do stuff
end.sum

4 个答案:

答案 0 :(得分:2)

要回答这个问题 - 是的,你可以像你所展示的那样链接方法。

(3..999).to_a.select do |x|
   x % 3 == 0 || x % 5 == 0 # you don't have to use floats here, integers would work
end.inject(:+)
#=> 233168

样式指南的规则是不要将方法链接到多行do end块,但它是一个有效的代码。

与写作相同

 (3..999).to_a.select { |x| x % 3 == 0 || x % 5 == 0 }.inject(:+)
 #=>233168

Array#sum是一个ActiveSupport方法,而不是Ruby的方法,但我认为你应该在eulerproject任务中使用Ruby的方法。

答案 1 :(得分:2)

您正在对算术系列求和,因此无需迭代:

<input type="checkbox" name="tsk" value="212654" onclick="ToggleCheck(this);">

考虑:

def sum(n,m)
  p = n/m
  m*p*(1+p)/2
end

n = 999
sum(n,3) + sum(n,5) - sum(n,15)
  #=> 233168

我们需要减去n = 100 m = 3 p = 100/3 #=> 33 sum(100,3) = 3 + 6 + 9 +...+ 99 = 3 * (1 + 2 +...+ p) = 3 * p(1+p)/2 因为sum(100,15)重复计算:

sum(100,3) + sum(100,5)

答案 2 :(得分:1)

如果你想得到数组的总和,你可以这样做:

(3..999).inject(0) { |sum, e| e % 3 == 0 || e % 5 == 0 ? sum += e : sum }
=> 233168

它只需要一次循环。

答案 3 :(得分:1)

你可以省略to_a,因为调用'select'到(3..999)仍然会返回一个数组。 安德烈的答案是最紧凑的答案:

(3..999).select{ |x| x % 3 == 0 || x % 5 == 0 }.inject(:+)