eratosthenesのふるいをRubyで書く
エラトステネスのふるいを利用して素数を集めるプログラムを書きました。
条件
- 素数リストnums 探索リスト内の素数を記録
- 探索リストprime 入力された上限値以下の整数を並べたリスト
- インデックスと探索リストの要素が一致するようにする
- for式を利用してiを2〜入力値でループ
- iまたはその倍数がnums[i]と等しければnilに設定する。
1 def delete_multiple(array, current, max) 2 for n in (2..max) 3 for i in (0..max) 4 if current * n == array[i] 5 array[i] = nil 6 end 7 end 8 end 9 end 10 11 def last_number(array) 12 i = -1 13 while array[i] == nil 14 i -= 1 15 end 16 return array[i] 17 end 21 puts("上限値を入力してください") 22 s = gets() 23 max = Integer(s) 24 nums = [] 25 for i in (0..max) 26 nums << i 27 end 28 primes = [] #素数リスト 30 for i in (2..max) 31 if nums[i] != nil 32 primes << i 33 delete_multiple(nums, i, max) 34 last_num = last_number(nums) 35 if last_num < (i*i) 36 break 37 end 38 end 39 end 40 for i in (2..max) 41 if nums[i] != nil 42 primes << nums[i] 43 end 44 end 45 puts ("#{max}までの素数は#{primes}です")
こんなコードを書きました。実行結果は
上限値を入力してください 10 10までの素数は[2, 3, 2, 3, 5, 7]です
こんなんだった。おかしい・・・
line 2 の範囲が間違っているのが判明。
” 2 for n in (2..max)”→” 2 for n in (0..max)”
へ直して実行すると・・・
上限値を入力してください 10 10までの素数は[2, 3, 5, 7]です
今度は成功〜♪
さて、line2 〜 line8はもっと別に良い書き方があるはず・・・。
参考にしていた本を見てみると、
mul = current while mul <= max array[mul] = nil mul += current end
forをwhileに変えたこと、”mul += current”で倍数を表現することでこんなスッキリかけた。はぁ〜、すごいなぁ。”mul += current”なんて思いつきませんでした。頭いいなぁ〜。