Google Code Jamの集計サイト Code Jam Statistics に何種類の言語を使ったかという Contestants using multiple languages のコーナーがあり、今年はそれに挑戦することにした。
予選は27時間あるので、SmallとLargeで別の言語を使う余裕がある。
問題は基本的に簡単な順なので、慣れていない環境から順番に使う方針で。
Clojure (1.8.0)
予選問題A Counting Sheepに使った。
コマンドラインからの実行
lein-execを使う。
以下の内容で $HOME/.lein/profiles.clj を作成した。
{:user {:plugins [[lein-exec "0.3.6"]]}}
こんな感じで実行できる。
$ lein exec QR_A.clj < in.txt > out.txt
数値の一行入力
(read-string (read-line))
[N, 2N, 3N, ...]の無限の長さの配列
iterateでシーケンスを作成した。
(defn gen[n] (iterate (fn[x] (+ x n)) n))
文字列が文字列を含むかどうかの判定
提出したコードでは (split (str n) #"") で一文字ずつに分離して判定していたのだが、clojure.string/includes? でいい。Javaの関数をインポートしてもよい。
stdoutへの出力
formatだと型をあわせる必要がある。strだとansが文字列でも数値でもいける。
(println (format "Case #%d: %s" t ans)) ; ansは文字列
(println (str "Case #" t ": " ans)) ; ansは数値でもいい
その他
シーケンスをそのまま出力すると clojure.lang.LazySeq@299945fc みたいな文字列になってしまう。
apply とかで評価する必要がある。
Haskell (GHC 7.10.3)
予選問題A Counting Sheepのlargeに使った。
数値の一行入力
betaveros さんのテンプレートから拝借した。一行読み込んでIO型を返す。
readInt = (read <$> getLine) :: IO Int
T回繰り返して出力
出力のループはforM_で手続き型言語っぽく書ける。IO型はいったん普通の変数に束縛しないといけないようだ。(理解してない)
forM_ [1..t] $ \i -> do
n <- readInt
printf "Case #%d: %s\n" i $ solve n
数値Nに桁Dが含まれているか判定
show nで数値を文字列化。$を使うと何となくHaskellを使っている感
elem d $ map digitToInt $ show n
Java (1.8.0)
予選問題B Revenge of the Pancakesに使った。
数値の一行入力
Javaは何をするにもコードが長い(偏見)
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String s = reader.readLine();
Scala (2.11.8)
予選問題B Revenge of the Pancakesに使った。
数値の一行入力
慣れたらJavaより快適かもしれない。
val T = scala.io.StdIn.readLine.toInt
JavaScript (node.js 4.4.3)
予選問題C Coin Jamに使った。
入力
Windowsだと簡単にstdinから入力する方法がなさそうだったので、ファイルから入力することにした。
fs.readFile('./in_c.txt', 'utf8', function (err, text) {
N進数対応
提出コードではparseIntを使うのを忘れてしまった。
n = parseInt(digits.join(''), radix);
C# (5.0)
予選問題C Coin Jamに使った。
単純に巨大な乱数を生成して解いたため、largeはBigIntegerが使えるC#にしてみた。
Visual Studioが楽すぎて感激した。
数値の一行入力
割とJavaっぽい。
TextReader input = Console.In;
int T = int.Parse(input.ReadLine());
(staticおじさん)
Go (1.6)
予選問題D Fractilesに使った。
こちらから入力部をもらってきた。
Go 言語で標準入力から読み込む競技プログラミングのアレ --- 改訂第二版
smallは1~kを出力するだけなので特別なことは何もしていない。
パッケージの場所を作成してコンパイルするとか、未使用変数があるとコンパイルされないとか、少し縛りがきつかった。
PHP (5.6)
Round 1A A. The Last Wordに使った。
複数の数値の入力
$params = explode(" ", fgets(STDIN));
いまどきのPHPはarray_pushとか書かなくていいので楽。(この問題では未使用)
Perl (5.22.1)
Round 1A B. Rank and Fileに使った。
超久しぶりで配列やハッシュへの代入方法がわからなくてぐぐりまくり。
結果をソートして空白区切りで出力
ちょっとだけPerlを使っている感
printf "Case #$t: %s\n", join(' ', sort {$a <=> $b} @a);
C
Round 1A C. BFFsに使った。
Rubyのpermutationで書いたら制限時間内に終わらず、Cで書き直した。
蟻本 のnext_permutationを写経。
このコード何回見てもすごい。
その他
@kobae964 さんの Rustの競プロテンプレ を見てRustも使ってみた。
https://github.com/firewood/topcoder/blob/master/gcj_2016/QR_A.rs
なんというかコンパイル通るだけで喜びが味わえる言語。
Racketでもやってみたが、main関数を実行するだけで一苦労。提出している人たちはコマンドラインからの起動ではなく、IDEの中でやっているような気がする。そのうちリベンジする。
#lang racket
(provide main)
(define (main)
結果
予選はC++で解いたりRubyでテストを書いてから他の言語で書き直したりして12時間くらいかかった。
Round 1A終わった時点で10言語まできた。
意外と楽しいので来年もこの路線で行きたいと思う。