Techioz Blog

Rubyで無限シーケンスを反復処理する

概要

プロジェクト オイラーの問題 #12 を解決しようとしています。

Rubyを使用して私が思いついた解決策は次のとおりです。

triangle_number = 1
(2..9_999_999_999_999_999).each do |i|
  triangle_number += i
  num_divisors = 2 # 1 and the number divide the number always so we don't iterate over the entire sequence
  (2..( i/2 + 1 )).each do |j|
    num_divisors += 1 if i % j == 0
  end
  if num_divisors == 500 then
    puts i
    break
  end
end

9_999_999_999_999_999 のような任意の巨大な数値を使用すべきではありません。関数型言語のような Math.INFINITY シーケンスがあればもっと良いでしょう。 Ruby で遅延無限シーケンスを生成するにはどうすればよいですか?

解決策

近い答えはいくつかありますが、実際に無限の範囲を使用している人を見たことがありません。 Ruby はそれらを適切にサポートしています。

Inf = Float::INFINITY # Ruby ≥ 1.9
Inf = 1.0/0           # Ruby < 1.9
(1..Inf).include?(2305843009213693951)
# => true
(1..Inf).step(7).take(3).inject(&:+)
# => 24.0

あなたの場合

(2..Inf).find {|i| ((2..( i/2 + 1 )).select{|j| i % j == 0}.count+2)==42 }
=> 2880

強引な方法は粗雑であり、完了するまでに非常に長い時間がかかる可能性があります。