euler#2项目的更多ruby方式
我正在尝试学习Ruby,并且正在经历一些项目中的问题。我这样解决:euler#2项目的更多ruby方式,ruby,Ruby,我正在尝试学习Ruby,并且正在经历一些项目中的问题。我这样解决: def fib(n) 如果n
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
由此,您可以使用niceEnumerable
方法来处理该问题。你可能想知道,偶数斐波那契数是否也有模式
编辑您的问题以发布解决方案
注意:有比枚举它们更有效的方法,但它们需要更多的数学运算,不会像这样清晰,只有在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