Hatena::Grouptopcoder

cafelier@SRM

cafelier のSRM参加記録です。コンテスト中に考えてたことを執拗に全部書き残すとどうなるだろうかという試み本番中にこういうコードが書きたかったなあ、という後で書いた反省コードを書き残す試み

スパムが来たのでしばらくコメント欄をはてなユーザ限定にしています、すみません、

 | 

2012-04-17

AOJ1004 : Pair of Primes

21:26 | はてなブックマーク -  AOJ1004 : Pair of Primes - 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の個数を数えると答えです。

トラックバック - https://topcoder-g-hatena-ne-jp.jag-icpc.org/cafelier/20120417
 | 

presented by cafelier/k.inaba under CC0