Online Judge Template Generator を Windows 10 + Python で使う:AtCoder コンテストにおける提出コードの作成,テストから提出まで
Online Judge Template Generator (OJTG) *1は,提出コードのひな型作成や,ランダムテストケースの作成といった機能を備え,競技プログラミングの問題やコンテストへの取り組みを強力に支援するツール群です.本記事では,Windows 10 環境に OJTG を導入し,AtCoder のコンテスト(過去問を含む)に Python で取り組む*2際に,これを活用する方法について述べます.
はじめに
競技プログラミングでは,ただ問題に答えるコードを書くだけではなく,それをテストにより検証したり,オンラインジャッジに提出したりする必要があります.この操作は,時として煩雑となり,その過程で思わぬ誤りが生じ,苦しむこともあります.そこで,近年さまざまな支援ツールが開発されました.その例として,以前紹介した online-judge-tools や atcoder-cli が挙げられます.このようなツールのおかげで,作業を省力化し,解法やその実装法を考える時間を増やすことができるようになりました.
今回紹介する OJTG は,上記の online-judge-tools とも連携し,競技プログラミングにつきものの作業に対し,さらなる強力な支援を行うツールです*3.このツール群には,たとえば以下のような機能が含まれています.
- 問題を解析し,適切な入出力処理を含む,解答コードのひな型を作成する
- 問題の制約に合うランダムケースを出力するコード(ジェネレータ)を作成する
- 上記のコードおよび問題に記された入出力例を,取り組むコンテストの構成に合わせて適切にプロジェクトに配置する
本記事では,Windows 10 環境において,AtCoder のコンテストに Python で取り組むことを想定して,上記の支援機能を用いる方法を説明します.OJTG はほかのオンラインジャッジや言語にも既定で対応しているか,適切な設定により対応させることができますが,ここでは一つの例として,このケースについて述べます.
主な前提条件
ツールの導入と初期設定
Python 3 環境が適切に導入されていれば,以下の操作で OJTG と関連ツールを導入できます.
pip3 install online-judge-template-generator
AtCoder のコンテストに取り組む
以下では,AtCoder Beginner Contest 177 - AtCoder の A - Don't be late を Python で解くことを想定し,一連の操作を行います.なお,以下ではこの問題に対するネタバレがあるので,注意してください.
コンテストのプロジェクトを作成する
解答コードのひな型,入出力例,ジェネレータを,一括して得るには,以下を実行します.コンテストの問題数や通信環境によっては,処理に時間がかかることがあります.
oj-prepare https://atcoder.jp/contests/abc177
しばらく待つと,問題ごとに,abc177_a
から abc177_f
までのディレクトリが現れます.ここでは,abc177_a
に入ります.
cd abc177_a
解答コードを作成する
解答のコードは main.py
に記述します.初期状態では,たとえば以下のようになっています.
#!/usr/bin/env python3 # from typing import * YES = 'Yes' NO = 'No' # def solve(D: int, T: int, S: int) -> str: def solve(D, T, S): pass # TODO: edit here # generated by online-judge-template-generator v4.4.0 (https://github.com/kmyk/online-judge-template-generator) def main(): D, T, S = map(int, input().split()) a = solve(D, T, S) print(a) if __name__ == '__main__': main()
以下のように修正すれば,問題に答えるコードになるはずです.
#!/usr/bin/env python3 # from typing import * YES = 'Yes' NO = 'No' # def solve(D: int, T: int, S: int) -> str: def solve(D, T, S): return YES if S * T >= D else NO # generated by online-judge-template-generator v4.4.0 (https://github.com/kmyk/online-judge-template-generator) def main(): D, T, S = map(int, input().split()) a = solve(D, T, S) print(a) if __name__ == '__main__': main()
ランダムテストケースを作成する
解答コードを検査するには,与えられた入出力例だけではなく,愚直解を利用してランダムテストケースも作成して準備しておくと,なおよいでしょう.そのための方法を記述します.ごく簡単な問題では,この手順は必ずしも必要でないかもしれませんが,込み入った問題になると,この準備が威力を発揮します.
ランダムな入力例
ランダムな入力例を作るためのコードは,generator.py
に記載されています.まずはこれを修正します.初期状態では,たとえば次のようなコードになっています.
#!/usr/bin/env python3 # usage: $ oj generate-input 'python3 generate.py' import random # generated by online-judge-template-generator v4.4.0 (https://github.com/kmyk/online-judge-template-generator) def main(): D = random.randint(1, 10 ** 9) # TODO: edit here T = random.randint(1, 10 ** 9) # TODO: edit here S = random.randint(1, 10 ** 9) # TODO: edit here print(D, T, S) if __name__ == "__main__": main()
たいていのデバッグでは,小さな入力例を用意し,これに対し計算時間がかかるものの確実な解答コード(愚直解)を用いて,対応する出力例を作ることになります.そこで,以下のように設定します.
#!/usr/bin/env python3 # usage: $ oj generate-input 'python3 generate.py' import random # generated by online-judge-template-generator v4.4.0 (https://github.com/kmyk/online-judge-template-generator) def main(): D = random.randint(1, 100) T = random.randint(1, 100) S = random.randint(1, 100) print(D, T, S) if __name__ == "__main__": main()
これにより,小さな入力例のみが得られます*6.その後,以下を実行します.なお,generate-input
は g/i
とすることもできます.
oj generate-input "python generate.py"
すると,test/random-*.in
という形で,入力例が作成されます.
ランダムな出力例
続いて,愚直解を用いて,入力例に対する出力例を作ります.愚直解は,main.py
を複製し,適宜編集して作るとよいでしょう.ここでは,straightforward.py
という愚直解を作ったと仮定します.すると,出力例は次のように作れます.なお,generate-output
は g/o
とすることもできます.
oj generate-output -c "python straightforward.py"
すると,test/random-*.out
という形で,出力例が作成されます.
解答コードのテスト
問題文に書かれた入出力例と,上記のランダムな入出力例を用いて,解答コードをテストするには,以下を実行します.なお,test
は t
とすることもできます.
oj test -c "python main.py"
すべてのケースに対して,AC が得られていることを確認しましょう.さもなければ,コードを修正しましょう.
解答コードの提出
コードの提出は,以下で行えます.なお,submit
は s
とすることもできます.
oj submit main.py
自動的にブラウザが開き,提出結果が表示されます.
おわりに
OJTG および関連ツールの基本的な使い方をまとめました.今までは複数のツールを行ったり来たりしていましたが,このように,共通の操作感をもつツール群を用いることで,より効率的になりました.今後,実戦等でも活用していきたいと思います.
参考
OJTG および online-judge-tools については,本記事では扱わなかった機能,設定および仕様を含め,以下のドキュメントにわかりやすく記載されています.
*1:OJTG およびそれに関連するツールは,サードパーティ(有志の方々)が手がけられているものです.今後,もし AtCoder の仕様または規約,ポリシー等に変更があった場合,本記事の記述のようには利用できなくなるおそれがあります.
*2:後述のように,OJTG はさまざまなオンラインジャッジと言語に対応しますが,本記事は一つの例として,この場合について述べます.
*3:上述の記事を記した後,開発者の方から OJTG の存在を教えていただきました.
*4:Cython ではありません.
*5:今回は使いません.
*6:ただ,ここでは仮に値の上限を 100 としているものの,それが適切かは状況によります.