いまどきの Ruby なフィボナッチ数列
Enumerator.produce
を使います。
fib = Enumerator.produce([1, 1]) { |a, b| [b, a + b] }.lazy.map(&:first) #最初の10個 fib.first(10) #=>[1, 1, 2, 3, 5, 8, 13, 21, 34, 55] #数列の100以上3000未満の部分 fib.drop_while { _1 < 100 }.take_while { _1 < 3000 }.force #=>[144, 233, 377, 610, 987, 1597, 2584] #1000未満で素数であるもの require "prime" fib.select(&:prime?).take_while { _1 < 1000 }.force #=>[2, 3, 5, 13, 89, 233]
追記(12/6)
無駄に便利にしてみました。
module Fib Seq = Enumerator.produce([1, 1]) { |a, b| [b, a + b] }.lazy.map(&:first) class << self def method_missing(name, *args, &bk) Seq.__send__(name, *args, &bk) end def [](arg) case arg in Integer => i drop(i).first in Range => r a = r.begin if r.end b = r.exclude_end? ? r.end - 1 : r.end drop(a).take(b - a + 1).force else drop(a) end end end end end #最初の10個 Fib.first(10) #=>[1, 1, 2, 3, 5, 8, 13, 21, 34, 55] #最初の5個をそれぞれ2乗した数列 Fib.map { _1 ** 2 }.first(5) #=>[1, 1, 4, 9, 25] #(0番始まりで)9番目の値 Fib[9] #=>55 #(0番始まりで)3番目から9番目までの数列 Fib[3..9] #=>[3, 5, 8, 13, 21, 34, 55] #3番めから9-1番目までの数列 Fib[3...9] #=>[3, 5, 8, 13, 21, 34] #3番目からの無限数列を10個取ったもの Fib[3..].first(10) #=>[3, 5, 8, 13, 21, 34, 55, 89, 144, 233]