フィボナッチ数列
id:pyletさんのフィボナッチ数列(fib2)をRubyにて。
Pythonのrange(n)の意味は(0...n)でよいのかしらん。
def fib(n) a, b = 1, 1 for i in (0...n) a, b = b, a + b end a end for i in (0...20) print fib(i), " " end #=> 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
Danさんの問題への解答は以下でよいのでしょうかね。
def fib(n) fib_iterator(n, 0, 1) end def fib_iterator(n, a, b) if n == 0 b else fib_iterator(n - 1, b, a + b) end end (0...20).each do |n| print fib(n), " " end #=> 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
よくわからないけれど、ぐにゅぐにゅ。
def fib(n) ff = lambda {|f, n, a, b| if n == 0 b else f.call(f, n - 1, b, a + b) end } ff.call(ff, n, 0, 1) end (0...20).each do |n| print fib(n), " " end #=> 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
代入がまずいって?二回繰り返しちゃえ。
def fib(n) lambda {|f, n, a, b| if n == 0 b else f.call(f, n - 1, b, a + b) end }.call( lambda {|f, n, a, b| if n == 0 b else f.call(f, n - 1, b, a + b) end }, n, 0, 1 ) end (0...20).each do |n| print fib(n), " " end #=> 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
二回繰り返す部分を高階関数にすればいいのね。
def ff(f, *args) f.call(f, *args) end def fib(n) ff(lambda {|f, n, a, b| if n == 0 b else f.call(f, n - 1, b, a + b) end }, n, 0, 1) end (0...20).each do |n| print fib(n), " " end #=> 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
もう少しコンパクトなほうがわかりやすい。
def ff(f, n, a, b) f.call(f, n, a, b) end def fib(n) ff(lambda {|f, n, a, b| n == 0 ? b : f.call(f, n - 1, b, a + b)}, n, 0, 1) end (0...20).each do |n| print fib(n), " " end #=> 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
- 参照:フィボナッチ数列、もっと