cafelier のSRM参加記録です。コンテスト中に考えてたことを執拗に全部書き残すとどうなるだろうかという試み本番中にこういうコードが書きたかったなあ、という後で書いた反省コードを書き残す試み
スパムが来たのでしばらくコメント欄をはてなユーザ限定にしています、すみません、
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1004
さっき実は、10003 は面白くないから 10004 をやろう、と思ったら間違えて 1004 を解いてしまったのでその話をします。
import std.algorithm; import std.conv; import std.range; import std.stdio; import std.string; bool is_prime(int n) { if( n == 1 ) return false; for(int p=2; p*p<=n; ++p) if( n%p == 0 ) return false; return true; } void main() { string line; while( !(line=readln()).empty ) { int N = line.chomp().to!int(); auto ns = iota(1, N+1).map!(is_prime); zip(ns, retro(ns)).map!("a[0] && a[1]").count(true).writeln(); } }
素数判定は特に工夫せず O(√n) で書いています。入力がEOF終端という仕様なので、readln() の結果が空文字列かどうかを判定するようにしています。.length == 0 と書いてもいいし、std.array の empty() 関数を使ってもいいです。
問題を解いている肝心の部分は最後の方の2行で、頑張って range を使いまくりました。iota(x,y) は [x から y) までの値が順に並んだ range です。is_prime を map して bool が並んだ range に変換します。retro は range を逆順にする関数で、zip は複数の range を1個の Tuple の range にまとめます。これに論理&&をmapして、trueの個数を数えると答えです。
presented by cafelier/k.inaba under