はじめに
最近、約3年ぶりに AtCoder を再開しました。
私は、AtCoder が用意してくれている「コードテスト」はほとんど使っておらず、ローカル環境でコードを書いて試すスタイルをとっています。
その際には、サンプルケースをコピペして試しているのですが、これは意外と手間です。
提出の際にも、cat main.rb | pbcopy をしてブラウザを開いて貼り付けているので、これも手間です。
「これらの手間を解決してくれるいい感じのツールはないかな」と思っていたところ
の2つが便利そうだったので、導入してみました。
似たような導入記事はあったのですが、うまく入れられなかったり、現在は使えない機能もあったりしてので、その点も含めてまとめます。
oj
インストール
$ pipx install https://github.com/online-judge-tools/oj/archive/refs/tags/v12.0.0.zip
ここでは PyPI ではなく、GitHub の特定バージョン(v12.0.0)を明示的に指定して、インストールしています。
現在の oj の最新バージョンは、v12.0.0 で、その1つ前は v11.5.1 です。
v11.5.1 を使った場合、以下のようなエラーが出力されることがあります。
$ oj
Traceback (most recent call last):
File "/Users/tsuzuki-takaaki/.local/bin/oj", line 3, in <module>
from onlinejudge_command.main import main
File "/Users/tsuzuki-takaaki/.local/pipx/venvs/online-judge-tools/lib/python3.14/site-packages/onlinejudge_command/main.py", line 19, in <module>
import onlinejudge_command.update_checking as update_checking
File "/Users/tsuzuki-takaaki/.local/pipx/venvs/online-judge-tools/lib/python3.14/site-packages/onlinejudge_command/update_checking.py", line 1, in <module>
import distutils.version
ModuleNotFoundError: No module named 'distutils'
これは Python3.12 から distutils が削除されたのですが、oj の v11.5.1 では disutils を使っているので、エラーになっています。
なので、Python3.12 よりも下のバージョンを使っているのであれば、oj の v11.5.1 を使っていても、上記のエラーが起きることはないです。
に加えて、v12.0.0 は PyPi に上がっていないので、GitHub を参照する必要があります。
ログイン
ログインも README の通りにやると、下記のようにエラーになります。
$ oj login https://atcoder.jp/
[INFO] online-judge-tools 12.0.0 (+ online-judge-api-client 10.10.1)
[INFO] load cookie from: /Users/tsuzuki-takaaki/Library/Application Support/online-judge-tools/cookie.jar
[NETWORK] GET: https://atcoder.jp/contests/agc001/submit
[NETWORK] 302 Found
[FAILURE] You are not signed in.
[ERROR] Selenium is not installed. Please run $ pip3 install selenium
[WARNING] Switch to use CUI-based login instead of Selenium
[NETWORK] GET: https://atcoder.jp/contests/agc001/submit
[NETWORK] 302 Found
[NETWORK] GET: https://atcoder.jp/login
[NETWORK] 200 OK
[WARNING] AtCoder says: × Please sign in first.
Username: tsuzuki_takaaki
Password:
[NETWORK] POST: https://atcoder.jp/login
[NETWORK] 200 OK
[WARNING] AtCoder says: × Error.
[ERROR] Username or Password is incorrect.
[INFO] save cookie to: /Users/tsuzuki-takaaki/Library/Application Support/online-judge-tools/cookie.jar
ボット対策で CloudFlareのTurnstile が入っているので、それが原因でエラーになってしまうようです。
上記の issue のコメントにも書かれている通り、
ブラウザを使ってログインした際に Cookie に保存される REVEL_SESSION を使うようにするとこの問題を回避することができます。
[INFO] load cookie from: /Users/tsuzuki-takaaki/Library/Application Support/online-judge-tools/cookie.jar
のように、Cookie を管理しているファイル出力されているので、
AtCoder にログインした状態で、Cookie の REVEL_SESSION の値を確認し、対象のファイルを書き換えます。
ただ書き換えればいいだけではありますが、aclogin を使うと便利です。
テストケースのダウンロード
$ oj donwload <問題のURL>
# e.g.
$ oj download https://atcoder.jp/contests/abc434/tasks/abc434_a
カレントディレクトリに test ディレクトリが作成され、その配下にサンプルケースをテストするための input, output 用のファイルがダウンロードされます。
テストの実行
上記でダウンロードしたサンプルケースを使って、テストを実行することができます。
以下の例だと、見た目の通りですが、ruby /tmp/sample.rb を実行し、test 配下のすべてのサンプルケースを入力としてテストします。
$ oj test --command "ruby /tmp/sample.rb" --directory test
[INFO] online-judge-tools 12.0.0 (+ online-judge-api-client 10.10.1)
[INFO] 3 cases found
[INFO] sample-1
[INFO] time: 0.106215 sec
[SUCCESS] AC
[INFO] sample-2
[INFO] time: 0.075114 sec
[SUCCESS] AC
[INFO] sample-3
[INFO] time: 0.074849 sec
[SUCCESS] AC
[INFO] slowest: 0.106215 sec (for sample-1)
[INFO] max memory: 16.864000 MB (for sample-2)
[SUCCESS] test success: 3 cases
提出
提出の機能は、Cloudflare Turnstile の影響で、現在は使えなさそうでした。
$ oj submit https://atcoder.jp/contests/abc434/tasks/abc434_a /tmp/sample.rb --language 6087
[INFO] online-judge-tools 12.0.0 (+ online-judge-api-client 10.10.1)
[WARNING] cannot guess URL since the given file is not in the current directory
[INFO] code (55 byte):
w,_b_=_gets.split.map(&:to_i)
puts_(w_*_1000_+_b)_/_b
[INFO] load cookie from: /Users/tsuzuki-takaaki/Library/Application Support/online-judge-tools/cookie.jar
[NETWORK] GET: https://atcoder.jp/contests/agc001/submit
[NETWORK] 200 OK
[INFO] You are logged in.
[NETWORK] GET: https://atcoder.jp/contests/abc434/tasks/abc434_a
[NETWORK] 200 OK
[INFO] chosen language: 6087 (Ruby 3.4 (ruby 3.4.5))
[WARNING] the problem "https://atcoder.jp/contests/abc434/tasks/abc434_a" is specified to submit, but no samples were downloaded in this directory. this may be mis-operation
Are you sure? Please type "abca" abca
[NETWORK] GET: https://atcoder.jp/contests/abc434/tasks/abc434_a
[NETWORK] 200 OK
[NETWORK] GET: https://atcoder.jp/contests/abc434/submit
[NETWORK] 200 OK
[NETWORK] POST: https://atcoder.jp/contests/abc434/submit
[NETWORK] 200 OK
[WARNING] AtCoder says: × Error.
[FAILURE] submission failed
[INFO] save cookie to: /Users/tsuzuki-takaaki/Library/Application Support/online-judge-tools/cookie.jar
以下は、atcoder-cli のissue ですが、atcoder-cli は内部的に oj を使っているので、同様の原因のようです。
atcoder-cli
oj は AtCoder に特化したツールというよりも、Online Judge 全般のためのツールなので、もう少し AtCoder に特化した環境を作るために atcoder-cli を使います。
インストール
README の通りです。
$ npm install -g atcoder-cli
ログイン
$ acc login
oj と atcoder-cli をインストールした状態で、先ほど紹介した aclogin を使うと以下のような感じで REVEL_SESSION を書き換えてくれます。
$ aclogin
検知されたツール:
- oj
- acc
AtCoder の REVEL_SESSION クッキーを貼り付けてください: XXXXXXX
✅ oj: クッキーを /Users/tsuzuki-takaaki/Library/Application Support/online-judge-tools/cookie.jar に保存しました
✅ acc: クッキーを /Users/tsuzuki-takaaki/Library/Preferences/atcoder-cli-nodejs/session.json に保存しました
✅ すべてのツール (2/2) にクッキーを保存しました
コンテスト用のテンプレートの作成
$ acc new <contest>
このコマンドを実行すると、
- 各問題ごとのディレクトリを作成
- 各問題用のサンプルケースをダウンロード
してくれます。
$ acc new abc434
abc434/contest.acc.json created.
create project of Sky Inc, Programming Contest 2025 (AtCoder Beginner Contest 434)
? select tasks (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ A Balloon Trip
◉ B Bird Watching
◉ C Flapping Takahashi
◉ D Clouds
◉ E Distribute Bunnies
◉ F Concat (2nd)
◉ G Keyboard
$ tree abc434
abc434
├── a
│ └── tests
│ ├── sample-1.in
│ ├── sample-1.out
│ ├── sample-2.in
│ ├── sample-2.out
│ ├── sample-3.in
│ └── sample-3.out
├── b
│ └── tests
│ ├── sample-1.in
│ └── sample-1.out
├── c
│ └── tests
│ ├── sample-1.in
│ └── sample-1.out
├── contest.acc.json
├── d
│ └── tests
│ ├── sample-1.in
│ └── sample-1.out
├── e
│ └── tests
│ ├── sample-1.in
│ ├── sample-1.out
│ ├── sample-2.in
│ ├── sample-2.out
│ ├── sample-3.in
│ └── sample-3.out
├── f
│ └── tests
│ ├── sample-1.in
│ └── sample-1.out
└── g
└── tests
├── sample-1.in
└── sample-1.out
カスタム設定
今の状態だと、普段使っている言語のテンプレートを毎回 touch しないといけないので、この辺も一緒に作られたら嬉しいと思いますが、カスタムテンプレートを使うことで解決できます。
https://github.com/Tatamo/atcoder-cli?tab=readme-ov-file#provisioning-templates
これも README に書かれている通りですが、
atcoder-cli の設定ファイル用のディレクトリに対象のカスタムテンプレート用のディレクトリを作成し、そこに作られて欲しいファイルを作成しておきます。
main.rb という空の ruby ファイルが作られるようにしてみます。
$ acc config-dir
/Users/tsuzuki-takaaki/Library/Preferences/atcoder-cli-nodejs
$ cd $(acc config-dir)
$ mkdir ruby
$ touch ruby/main.rb
$ vim ruby/template.json
{
"task": {
"program": ["main.rb"],
"submit": "main.rb"
}
}
acc new する時に上記のテンプレートがデフォルトで選ばれるように設定しておきます。
$ acc config default-template ruby
この状態で、acc new すると、各問題用に main.rb のファイルが作られるようになります。
$ acc new abc434
$ tree abc434
abc434
├── a
│ ├── main.rb
│ └── tests
│ ├── sample-1.in
│ ├── sample-1.out
│ ├── sample-2.in
│ ├── sample-2.out
│ ├── sample-3.in
│ └── sample-3.out
├── b
│ ├── main.rb
│ └── tests
│ ├── sample-1.in
│ └── sample-1.out
# ...
テストの実行
atcoder-cli にはそのコマンドは生えていないので、oj を使ってテストの実行をします
$ oj test -c "ruby main.rb" -d tests
[INFO] online-judge-tools 12.0.0 (+ online-judge-api-client 10.10.1)
[INFO] 3 cases found
[INFO] sample-1
[INFO] time: 0.197356 sec
[SUCCESS] AC
[INFO] sample-2
[INFO] time: 0.075148 sec
[SUCCESS] AC
[INFO] sample-3
[INFO] time: 0.074849 sec
[SUCCESS] AC
[INFO] slowest: 0.197356 sec (for sample-1)
[INFO] max memory: 16.880000 MB (for sample-2)
[SUCCESS] test success: 3 cases
提出
提出機能は、oj の提出機能のところで説明したのと同様の理由で使えなさそうでした。