更多ruby方式做项目euler#2

时间:2010-06-12 16:49:14

标签: ruby

我正在尝试学习Ruby,并且正在解决一些Project Euler问题。我这样解决了problem number two

def fib(n)
  return n if n < 2
  vals = [0, 1]
  n.times do
    vals.push(vals[-1]+vals[-2])
  end
  return vals.last
end
i = 1
s = 0
while((v = fib(i)) < 4_000_000)
  s+=v if v%2==0
  i+=1
end
puts s

虽然这有效,但似乎不是非常红宝石 - 我无法提出任何好的纯Ruby回答,就像我可以用第一个(puts (0..999).inject{ |sum, n| n%3==0||n%5==0 ? sum : sum+n })。

9 个答案:

答案 0 :(得分:3)

为了一个很好的解决方案,为什么不创建一个Fibonacci数字生成器,如PrimeTriangular示例gave here

由此,您可以使用漂亮的Enumerable方法来处理问题。您可能想知道甚至Fibonacci数字是否存在任何模式。

编辑您的问题以发布您的解决方案......

注意:除了枚举它们之外,还有更有效的方法,但它们需要更多的数学运算,不会像这样清晰,只有在4百万更高的情况下才能发光。

正如demas'已发布解决方案,这是一个清理版本:

class Fibo
  class << self
    include Enumerable

    def each
      return to_enum unless block_given?
      a = 0; b = 1
      loop do
        a, b = b, a + b
        yield a
      end
    end
  end
end

puts Fibo.take_while { |i| i < 4000000 }.
          select(&:even?).
          inject(:+)

答案 1 :(得分:2)

我的版本基于Marc-AndréLafortune的回答:

class Some
  @a = 1
  @b = 2

  class << self
    include Enumerable

    def each
      1.upto(Float::INFINITY) do |i|
        @a, @b = @b, @a + @b
        yield @b
      end
    end
  end
end

puts Some.take_while { |i| i < 4000000 }.select { |n| n%2 ==0 }
          .inject(0) { |sum, item| sum + item } + 2

答案 2 :(得分:2)

def fib
  first, second, sum = 1,2,0
  while second < 4000000
    sum += second if second.even?
    first, second = second, first + second
  end
  puts sum
end

答案 3 :(得分:1)

您不需要return vals.last。你可以做vals.last,因为Ruby默认会返回最后一个表达式(我认为这是正确的术语)。

答案 4 :(得分:1)

fibs = [0,1]
begin
  fibs.push(fibs[-1]+fibs[-2])
end while not fibs[-1]+fibs[-2]>4000000
puts fibs.inject{ |sum, n| n%2==0 ? sum+n : sum }

答案 5 :(得分:1)

这是我得到的。我真的不认为需要在课堂上包装它。你肯定可以在更大的程序中,但在一个小脚本中,我发现只需为解释器创建附加指令。你可以选择偶数,而不是拒绝奇怪,但它几乎是相同的东西。

fib = Enumerator.new do |y|
  a = b = 1
  loop do
    y << a
    a, b = b, a + b
  end
end

puts fib.take_while{|i| i < 4000000}
        .reject{|x| x.odd?}
        .inject(:+)

答案 6 :(得分:0)

这是我的方法。我知道它可以减少代码行数,但也许你可以从中获取一些东西。

class Fib
  def first
    @p0 = 0
    @p1 = 1
    1
  end
  def next
    r = 
      if @p1 == 1
        2
      else
        @p0 + @p1
      end
    @p0 = @p1
    @p1 = r
    r
  end
end

c = Fib.new
f = c.first
r = 0
while (f=c.next) < 4_000_000
  r += f if f%2==0
end
puts r

答案 7 :(得分:0)

我是Ruby的新手,但这是我想出的答案。

 x=1
 y=2
 array = [1,2]
 dar = [] 
   begin
     z = x + y

       if z % 2 == 0
         a = z
         dar << a
       end
     x = y
     y = z
     array << z
   end while z < 4000000
     dar.inject {:+}
     puts "#{dar.sum}"

答案 8 :(得分:0)

def fib_nums(num)
    array = [1, 2]
    sum = 0
    until array[-2] > num
        array.push(array[-1] + array[-2])
    end
    array.each{|x| sum += x if x.even?}
    sum
end