競技プログラミングのための補助ツールを作った

,

URL: https://github.com/kmyk/online-judge-tools

この記事の記述時のversionは0.1.9です。

概要

競プロの際の典型作業を自動化するためのツールです。

主な機能としては以下があります。

  • サンプルケースの自動取得
  • 取得したケースに対するテスト
  • 回答の提出

また、以下のような機能も持ちます。

  • 問題文中の入力フォーマットを解析し、入力取得コードを自動生成
  • 入力ケースと愚直解を与え、これを想定解として出力ケースを生成
  • 複数ケースを含む入力ファイルを解析し、個別ケースを切り出し
  • 標準入出力で受け答えするジャッジプログラムを用いる、リアクティブ問のテスト

特徴として、

  • 導入が楽
  • 高精度

導入

pythonのpackageとしても公開してある[link]ので、導入は以下の$1$行だけで完了します。

$ sudo pip3 install online-judge-tools

更新の取得は以下です。

$ sudo pip3 install --upgrade online-judge-tools

Windows上で動くかどうかは分かりません。msys2やcygwinで頑張るか、あるいはどうしてもこれが使いたければWindowsは諦めて仮想環境を使ってください1

利用

download

サンプルケースの自動取得は以下のようにURLを指定して実行すればできます。 ちゃんとテストも書いて丁寧に実装しているので精度は高いはずです。

$ oj dl URL

多めに出力が出ます。サンプルケースの内容も表示されるので、何かまずそうならすぐ気付けるようになっています。terminal上だと色が付いたり太字になったりします。

$ oj dl http://agc001.contest.atcoder.jp/tasks/agc001_a
[x] problem recognized: <onlinejudge.atcoder.AtCoderProblem object at 0x7f1fb6c4dd30>: http://agc001.contest.atcoder.jp/tasks/agc001_a
[*] load cookie from: /home/user/.local/share/onlinejudge/cookie.jar
[x] GET: http://agc001.contest.atcoder.jp/tasks/agc001_a
[x] 200 OK
[*] skipped due to language: current one is lang-ja, not lang-en: Sample Input 1 
[*] skipped due to language: current one is lang-ja, not lang-en: Sample Output 1 
[*] skipped due to language: current one is lang-ja, not lang-en: Sample Input 2 
[*] skipped due to language: current one is lang-ja, not lang-en: Sample Output 2 
[*] save cookie to: /home/user/.local/share/onlinejudge/cookie.jar

[*] sample 0
[x] input: 入力例 1
2
1 3 1 2
[+] saved to: test/sample-1.in
[x] output: 出力例 1
3
[+] saved to: test/sample-1.out

[*] sample 1
[x] input: 入力例 2
5
100 1 2 3 14 15 58 58 58 29
[+] saved to: test/sample-2.in
[x] output: 出力例 2
135
[+] saved to: test/sample-2.out

test

サンプルケースを用いてテストを行います。コマンドは以下の形で、-c COMMANDが省略された場合は./a.outが使われます。

$ oj test [-c COMMAND]
$ oj test -c ./a.pl
[*] 2 cases found

[*] sample-1
[x] time: 0.002464 sec
[+] AC

[*] sample-2
[x] time: 0.002267 sec
[-] WA
output:
1


expected:
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16


[x] slowest: 0.002464 sec  (for sample-1)
[-] test failed: 1 AC / 2 cases

login

提出やコンテストの本番中の利用にはloginが必要です。コマンドは以下です。

$ oj login URL

実行するとusername/passwordが聞かれるので入力してください。 loginに成功するとsession情報のみがファイルに保存されます。

$ oj login http://codeforces.com
[x] service recognized: <onlinejudge.codeforces.CodeforcesService object at 0x7fd80b96c780>: http://codeforces.com
[*] load cookie from: /home/user/.local/share/onlinejudge/cookie.jar
[x] GET: http://codeforces.com/enter
[x] 200 OK
Username: user
Password: 
[x] POST: http://codeforces.com/enter
[x] 200 OK
[+] Welcome, user.
[*] save cookie to: /home/user/.local/share/onlinejudge/cookie.jar

submit

submitもできます。shellのヒストリ機能で誤爆するとペナルティが生えて危ないので、あまり使わない方がいい気がしています。 なので優先順位が低くあまり対応サービスは多くないのですが、要望があれば増えるはずです。

$ oj submit URL SOLUTION [--language LANG]

--language LANGを指定しなかった場合は選択可能な言語の一覧が表示されます。

$ oj submit http://yukicoder.me/problems/no/9002 a.pl --language perl
[x] problem recognized: <onlinejudge.yukicoder.YukicoderProblem object at 0x7fb2ce08eb38>: http://yukicoder.me/problems/no/9002
[*] code:
#!/usr/bin/perl
print+(Fizz)[$_%3].(Buzz)[$_%5]||$_,$/for 1..<>

[*] load cookie from: /home/user/.local/share/onlinejudge/cookie.jar
[x] GET: https://yukicoder.me/problems/no/9002/submit
[x] 200 OK
[x] POST: https://yukicoder.me/problems/16/submit
[x] 200 OK
[+] success: result: https://yukicoder.me/submissions/144776
[*] save cookie to: /home/user/.local/share/onlinejudge/cookie.jar

generate-scanner

入力フォーマットを解析して入力取るコードを自動生成します。 精度はそれなりなので注意。

例えば、

N
L_1 L_2 ... L_2N

が、

int N; cin >> N;
vector<int> L(2*N); repeat (i,2*N) cin >> L[i];

になります。

コマンドは次です。

$ oj g/s URL

しかしeditorのコマンドに割り当てておくべきです。以下はvimの例。

nnoremap <space>gs :r! oj generate-scanner --silent --repeat-macro=repeat 

実行例。

$ oj generate-scanner --repeat-macro=repeat http://agc001.contest.atcoder.jp/tasks/agc001_a
[!] This feature is experimental.
[x] problem recognized: <onlinejudge.atcoder.AtCoderProblem object at 0x7f1c700c3cf8>: http://agc001.contest.atcoder.jp/tasks/agc001_a
[*] load cookie from: /home/user/.local/share/onlinejudge/cookie.jar
[x] GET: http://agc001.contest.atcoder.jp/tasks/agc001_a
[x] 200 OK
[*] save cookie to: /home/user/.local/share/onlinejudge/cookie.jar
[+] success:
int N; cin >> N;
vector<int> L(2*N); repeat (i,2*N) cin >> L[i];

generate-output

実装と入力ケースから対応する出力ケースを作ります。 yukicoderの作問時の $\dots$を想定解として出力ケースを生成 みたいなやつです。

$ oj g/o [-c COMMAND]

split-input

ICPCでよくある単一ファイルに複数ケース入ってる場合に、ケースごとにファイルに切り分けます。 既にある実装を利用し、入力を$1$行ずつ与えて、出力が発生したらケースの区切りが来たと認識して分割します。

$ oj s/i [-i SOURCE] [-o DEST_FORMAT] [-c COMMAND]

test-reactive

リアクティブ問のテストを簡単にする機能です。 パイプを作っていい感じに繋ぐ処理をしてくれるので、入出力を標準入出力で行うようなジャッジプログラムを書くだけでよくなります。

$ oj t/r [-c COMMAND] JUDGE_COMMAND

貢献

何か壊れていたらissueとかで教えてください。 特に、コンテスト中に発生すると成績に深刻な影響を与えるバグ(例えば、サンプルケースの取得で一見上手くいってるけど実は失敗している場合など)は、例えばURLを投げ付けてくれるだけでも十分ありがたいです。 ちなみにこうやってわざわざ記事を書いて宣伝しているのは、バグを見つけて報告してくれるユーザを獲得するためです。

pull requestも歓迎します。

競合

参考までに

機能があまり被らないもの:



  • Thu Jan 19 17:11:18 JST 2017
    • 「…素直に仮想環境を…」の文言を修正

  1. 当初は「あるいは素直に仮想環境を使ってください」と書いていたのですが、「WindowsがいいからWindows使ってんのに、仮想環境を使うのが素直な選択肢なわけねえだろ何いってんだ」という意見があり、それはそうだなと思ったので訂正しました。 [return]