外部イテレータで素数生成(Ruby)

標準添付ライブラリに Prime がありますが、自分でやってみました。めっちゃ素朴な実装です(数が大きくなると急速に遅くなります)。

gen_primes = Enumerator.new do |y, i = 2|
  loop do
    catch do |jp|
      2.upto(i - 1) {|j| throw(jp) if (i % j).zero?}
      y << i
    end
    i += 1
  end
end

e = gen_primes.each(100)
p e.take(10)    #=>[101, 103, 107, 109, 113, 127, 131, 137, 139, 149]

Enumerator に引数を渡すのには each を使います。


同様にフィボナッチ数列もできますね。

gen_fibonatti = Enumerator.new do |y|
  a = 0; b = 1
  loop do
    y << b
    a, b = b, a + b
  end
end

p gen_fibonatti.take_while {|i| i < 1000}.to_a
#=>[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987]



※参考
Ruby で外部イテレータを使う - Camera Obscura