euler#2项目的更多ruby方式

euler#2项目的更多ruby方式,ruby,Ruby,我正在尝试学习Ruby,并且正在经历一些项目中的问题。我这样解决: def fib(n) 如果n

我正在尝试学习Ruby,并且正在经历一些项目中的问题。我这样解决:

def fib(n)
如果n<2,则返回n
VAL=[0,1]
n、 时代确实如此
VAL.push(VAL[-1]+VAL[-2])
结束
返回VAL.last
结束
i=1
s=0
而((v=fib(i))<4_000_000)
如果v%2==0,则s+=v
i+=1
结束
放置

虽然这是可行的,但它似乎不太符合ruby-ish——我不能像第一个一样想出任何好的纯ruby答案(
put(0..999)。inject{sum,n | n%3==0 | n%5==0?sum:sum+n}

对于一个好的解决方案,为什么不创建一个斐波那契数生成器,比如
Prime
triangal
示例I

由此,您可以使用nice
Enumerable
方法来处理该问题。你可能想知道,偶数斐波那契数是否也有模式

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

注意:有比枚举它们更有效的方法,但它们需要更多的数学运算,不会像这样清晰,只有在400万更高的情况下才会发光

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(:+)
类Fibo

这是我的方法。我知道它可以是更少的代码行,但也许你可以从中得到一些东西

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
Fib类
def优先
@p0=0
@p1=1
1.
结束
def下一个
r=
如果@p1==1
2.
其他的
@p0+@p1
结束
@p0=@p1
@p1=r
R
结束
结束
c=纤维新
f=c
r=0
而(f=c.next)<4
如果f%2==0,则r+=f
结束
放r

我的版本基于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
class一些
@a=1
@b=2

class您不需要
返回vals.last
。您只需执行vals.last
,因为默认情况下Ruby将返回最后一个表达式(我认为这是正确的术语)。

def fib
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 }
第一,第二,和=1,2,0 第二次<4000000 sum+=如果是第二个,则为第二个。偶数? 第一,第二=第二,第一+第二 结束 求和 结束
我对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}"
x=1
y=2
数组=[1,2]
dar=[]
开始
z=x+y
如果z%2==0
a=z

dar这是我得到的。我真的不认为有必要在课堂上总结这一点。您当然可以在一个更大的程序中使用,但在一个小脚本中,我发现只需为解释器创建额外的指令就可以了。你可以选择偶数,而不是拒绝奇数,但这几乎是一样的

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(:+)
fib=Enumerator.new do|y|
a=b=1
环道

y如果你被困在写这样一个发电机上,看看下面:@Michael:噢,天哪!那篇文章是对光纤的糟糕使用,而且太复杂了(更不用说慢了)。如果您需要类似的东西,请编写一个好的枚举表(看看我指的三角形数字生成器),并获得一个
枚举器
,然后使用
next
,但即使这样也应该避免。我在下面发布了我的版本。请检查一下。这就是你的意思吗?@Marc AndréLafortune为什么要将
i
传递给
1中的块。upto(Float::INFINITY)do | i
?看起来你不是在用它。。。另外,您能解释一下Float::INFINITY在这里是如何工作的吗?对我来说,它写着“永远做点什么”,但显然我错了。@Mohamad这是dema下面的回答,但你是对的,这可以进一步简化。我已经相应地编辑了我的答案。不,你是对的,这是一个无限循环,但使用它作为可枚举项可以很容易地只获取少数项。如果你从
@p0=1
开始,如果
,你就可以摆脱
。。。另外,Ruby具有并行赋值,这在这里很有用。你知道吗?
2.偶数?
返回
true
?我知道。我刚刚发布了我的项目Euler任务存档中的存档代码。这是我很久以前写的。是的,这是一个很好的方法。我用一个稍微改进的版本编辑了我的答案。请注意,你的版本的一个问题是你不能多次调用它<代码>一些。首先#=>3;Some.first=>5
 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}"
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(:+)
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