LoginSignup
0
0

More than 5 years have passed since last update.

Rubyで素数を見つけてみた.(エラトステネスのふるい)

Last updated at Posted at 2018-11-10

素数の定義

以下,Weblio辞書:素数より引用.

1 と自分自身以外には約数をもたない正の整数。 1 は素数の中に含ませない。

エラトステネスのふるい

  1. 2から数字を見ていって素数を見つける,
  2. 素数の倍数は素数ではないので素数が現れるたびに,その倍数は素数ではないと確定していく.
  3. 見つけた素数から見ていって,見つけた素数より大きい素数を見つける.
  4. 2.と3.の動作を繰り返す.

以上の工程で素数を見つけることをエラトステネスのふるいと言います.
表が載っているサイトがわかりやすいので以下を紹介しておきます.
こちらです.(エラトステネスのふるい)

実装

eratosthenes_sieve.rb
def eratosthenes_sieve(num)
  # nums = Array.new(num, true)
  nums = [*0...num]
  primes = []
  k = 2 # 0, 1 aren't  prime-nums
  while k*k<=num
    for i in k..num/k
      nums[k*i] = nil
    end
    k += 1
    while !nums[k]
      k += 1
    end
  end
=begin
  primes = nums.each_with_index.select {|num, index| index if num}
  primes.clone.each_with_index do |prime, index|
    primes[index] = prime[1]
  end
  primes
=end
  nums.compact[2...nums.size]
end

num = rand(100)
prime_nums = eratosthenes_sieve(num)
p "num: #{num}" # "num: 53"
p "prime_nums: #{prime_nums}" # "prime_nums: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]" 

おまけ(Rubyのnilチェック?)

コーディング中に「ん???」と思うことがありました.
問題の部分を以下に記します.

primes << i if nums[i] = true

この一文は,たまたまif nums[i] == trueと書きたかったのを間違えちゃった一文です.でもこれでも通っちゃいました.ナゼだろう...と不思議に思って色々試して見ました.

a = 'test'
p a # "test"
p a if a = 'change' # "change"

あ,ifの条件式に配置したa = 'change'が影響して"change"が出力されてる!:open_mouth:

もしかして,swiftif letと同様のnilチェックの様な機能を果たしているのではないか!と考えました.

a = nil
p a # nil
p 'hogehoge' if b = a # nil
a = 'test'
p 'hogehoge' if b = a # "hogehoge"

おーやっぱりそうなのか!:stuck_out_tongue_closed_eyes:
しかし...

a = 'test'
p b if b = a

こうすると,bなんて変数知りませんよと言われちゃいました.

a = 'test'
if b = a
  p b # "test"
end

これだと大丈夫.Rubyのifのワンライナーで書く方法のうち,内容を前に持って来る場合はこのnilチェックは使えない様ですね.

nilチェックという言葉が正しいのかどうかは定かではありません.どなたかご存知でしたらこの様な動作の名称を教えていただけると発狂します:smiling_imp:

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0