Primeライブラリを使って実装
1~1000までの素数を列挙するとして実装すると
require 'prime'
number = *1..1000
number.map{|n| puts n if Prime.prime?(n)}
# 判定なんてしなくてもいいなら
puts Prime.each(1000).to_a
Primeライブラリを使えば簡単というか、あまりに溢れすぎていたRubyの模範解答になります・・。
これだと芸がないですし、素数判定のコードが組めるかどうかが大切な気もするので自作したコードが以下
一般的な解き方
n-1までの要素で割り切れないならそれは素数だということをそのまま書いただけのコードになります。
実際にこの結論に到るまでは数時間以上要し文系の壁の高さを今一度認識しました・・。
number = *1..100
def is_prime?(n)
return false if n ==1
(2..n-1).map{|i| return false if n%i==0}
end
number.map{|n| puts n if is_prime?(n)}
解き方の実装がうまく出来なかった頃のコード
for i in number
a = number.slice(0,i-1).map(&:to_i).drop(1)
next if i == 1
next if i == 2
# p a now it's i == 3 so a should be [1,2]
a.map{|n| puts i if i%n!=0}
end
#1で割れてしまうことを考慮したa配列の先頭排除が未実装の状態
作ってる最中では、n-1までの要素をslice
メソッドで作成して要素同士の余りを求めればいいのでは〜と考えていましたが、実際にはfor文の変数を用いて配列aを作成しているために、aをmap
で回した際にiがダブって二重ループになってしまうので却下。
素数判定処理をループ外にメソッドとして作成して処理すれば解決出来ると、この結論に至ってより、メソッドを自作して処理したことがなかったので想定外に時間が掛かりました・・。
なぜ記事を作ったのか・・。
PaizaやAOJなどの他の数多の問題ならいざ、素数判定コードは僕自身処理を複雑に考えてしまう癖があるので、就活の面談の際にどうしても二重ループ問題が解決できずにPrimeライブラリを使って実装したのですね・・。
どう考えてもこれはアウトだなーと結局ダメだったのですが、素数判定くらいの簡単なアルゴリズム?実装は出来なければまずいと思い立ち記事に残すことにしました。
素数判定の自作を含めてAOJの問題でも、頭では簡単に処理できる内容に〜・・がなかなか実装出来ずに他の方のコードを参考にすると実に簡単な処理である場合が多いので、AOJ以外にもアルゴリズムの勉強をすればサクサク書けるようになるのだろうか・・