この記事では競技プログラミングにClojureという言語を使用して参加する方法を紹介していきます。
Clojureとは
人によってはあまり聞き馴染みのない言語かもしれませんが、れっきとしたプログラミング言語です。
綴りはClosure
ではなくClojure
です。(前者はJavaScriptなどで使われる単語の方です。)
Java仮想マシン(JVM)上で動作する関数型でLisp派生の言語です。(LispについてはWikipediaなどをご参照ください。)
競技プログラミングとは
国内で最も有名な競技プログラミングサイトであるAtCoderによると、以下のように説明されています。
決められた条件のもとで与えられた問題、課題をプログラミングを用いて解決し、その過程や結果を競うもの
たとえば以下のような問題文があったとします。
整数Aと整数Bが与えられます。
AとBの合計値を出力してください。
それに対して以下のような制約がついています。
- 入力は全て整数である。
- 0 ≦ A, B ≦ 100
そして、入力は以下の形式で標準入力から与えられます。
A B
この問題を解くプログラムを実装するスピードを競うのが競技プログラミングです。
(厳密な答えが存在しないヒューリスティックコンテストというのも開催されていますが、ここでは与えられた入力値に対して明確に答えが存在する一般的なコンテストについて説明していきます。)
上述した問題をPythonで回答してみると、以下のようになると思います。
A, B = map(int, input().split())
sum = A + B
print(sum)
input()
で標準入力を受け取り、.split()
でlist化してからmap()
関数でそれぞれの値をint
型にキャストし、AとBに代入しています。
それらを足し合わせた値をsum
に代入し、print(sum)
で標準出力しています。
これをClojureでやっていきたいと思います。
競プロ(AtCoder)の問題をClojureで解く
実際に過去に出題された問題を例にやっていきます。
AtCoder Beginner Contest(通称ABC)の128からApple Pieという問題を解いていきます。
詳細はリンク先を参照いただければと思いますが、この問題では与えられたA個のリンゴを全て砕いてそれぞれ3個の欠片にして、すべての欠片を使っていくつアップルパイを作ることができるかを求めればよいでしょう。
ではまず、標準入力を受け取ります。
read
関数を使用すると標準入力を受け取ることができます。Clojureでは半角スペースを含んだ入力値を一度で受け取ることができなさそうなので、AとPで別々に標準入力から受け取りそれぞれをAとPという変数に束縛していきます。(Clojureでは変数に値を代入することを「束縛」といいます。)
変数の定義にはdef
というマクロを使用するので、以下のようになります。
(def A (read))
(def P (read))
Clojureでは数値を入力すると自動的にlong型だと認識してくれるようなので、型キャストの必要はありません。
なので、次にAこのリンゴを全て砕いて3個の欠片にするので、Aを3倍していきます。
(def triple-a (* A 3))
そしてPと足し合わせます。
(def all-pieces (+ triple-a P))
作ることのできるアップルパイの数を求めるには、all-pieces
を2で割った商の整数部分を求めれば良いです。
Clojureではquot
という関数を使用すると小数点以下を切り捨てた値を取得することができます。
(def ans (quot all-pieces 2))
これをprintln
関数で出力すれば完了です。
(println ans)
最終的には以下のようなコードになります。
(def A (read))
(def P (read))
(def triple-a (* A 3))
(def all-pieces (+ triple-a P))
(def ans (quot all-pieces 2))
(println ans)
やろうと思えばもっと簡潔なコードにすることもできますが、どういうコードを提出したは見られず正しい値を出力することのできるコードのみが機械的に評価されるのでこのままでも全く問題ありません。
このコードを実際に提出してみた結果が以下のとおりです。
無事にすべてのテストケースでAC(Accepted)となりました。(ステータスに関してはこちらをご参照ください。)
以上がClojureで競技プログラミングに参加する基本中の基本です。
競技プログラミングは新しい言語に慣れるためには非常に効率的な手段だと思っています。
入力値をどう受け取るかということとどう出力するかということがクリアできればあとはロジックを考えて実装するだけなので、ぜひ気軽にClojureで参加してみてください。