素数

プッチ神父の如く素数を数えたい,そんな時.rubyistRuby素数を数えましょう.
事の発端は,友達がPython素数を求めるプログラムを書いていた事から.こんなコードでした.

for n in range(2,10):
  for x in range(2,n):
    if n % x == 0:
      print n,"equals",x,"*",n/x
      break
  else:
    print n, "is prime number"
    
=>
2 is prime number
3 is prime number
4 equals 2 * 2
5 is prime number
6 equals 2 * 3
7 is prime number
8 equals 2 * 4
9 equals 3 * 3

相変わらずスッキリしてるぜ,Python.for文にelseがくっつく辺りが,異常にカッコ良い.こんな機能はRubyには無いので,ちょっと嫉妬しちゃいます.


それでは,同じようなコードをRubyで書いてみます.

(2 ... 10).each{|n|
  f = 0
  (2 ... n).each {|x|
    if n % x == 0
      puts "#{n} equals #{x} * #{n/x}"
      f = 1
      break
    end
  }
  puts "#{n} is prime number" if f == 0
}

仕方が無いので,フラグを立てて処理を行いました.フラグはかっこわるいので,もう少し他の方法を考えます.

def counter
  count = 0
  return lambda{ return count += 1 }
end

(2 ... 10).each{|n|
  count = counter
  (2 ... n).each {|x|
    if n % x == 0
      puts "#{n} equals #{x} * #{n/x}"
      break
    end
    count.call
  }
  puts "#{n} is prime number" if ( n - 1 ) == count.call
}

何回ループしたのかをカウント.正直,気持ち悪い.どーみても,ただlambdaを入れたかっただけじゃん!


今度は,素数か否かだけを気にしたい,そんな時.

class Integer
  def prime?
    return false if self < 2
    (2 ... self).each{|x|
      return false if self % x == 0
    }
    true
  end
end

e = 1
arr = Array.new(8){ e += 1}
arr.each{|e|
  if e.prime?
    puts "#{e} is prime number"
  else
    puts "#{e} isn't prime number"
  end
}

=>
2 is prime number
3 is prime number
4 isn't prime number
5 is prime number
6 isn't prime number
7 is prime number
8 isn't prime number
9 isn't prime number

まぁ本体部はclassのメソッド定義した所だけですけど.非常に簡単な実装です.


最近,何気に配列の宣言に凝ってます.今回だと,

e = 1
arr = Array.new(8){ e += 1}

なんてして,2から9までの整数の配列を宣言したり.


今日はもう満足です.てか眠い.