AtCoderでエディタからテストと提出が出来るまで
概要
AtCoderを始めたのですが、エディタからテストや提出ができるようになったので、その方法を紹介します。
最終的には以下のようなディレクトリ構成になります。
atcoder_rust
をgit管理していてエディタで開いて実際にコーディングするのはabc386
などコンテストのディレクトリです。
コンテストの中のディレクトリ構成は比較的自由に変更可能です。
(問題毎にディレクトリ分けてmain.rsを作ったりとかetc)
各々好きなように設定していただければと思います。
atcoder_rust
├── abc386
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── contest.acc.json
│ ├── src
│ │ └── bin
│ │ ├── a.rs
│ │ ├── b.rs
│ │ ├── c.rs
│ │ └── d.rs
│ └── testcases
│ ├── a
│ │ ├── sample-1.in
│ │ ├── sample-1.out
│ │ └── sample-2.in
│ ├── b
│ │ ├── sample-1.in
│ │ ├── sample-1.out
│ │ ├── sample-2.in
│ │ └── sample-2.out
│ ├── c
│ │ ├── sample-1.in
│ │ ├── sample-1.out
│ │ ├── sample-2.in
│ │ └── sample-2.out
│ └── d
│ ├── sample-1.in
│ ├── sample-1.out
│ ├── sample-2.in
│ └── sample-2.out
├── submit.sh
└── test.sh
環境
PC : M2 Mac, Sequoia 15.0.1
Editor : RustRover (VSCodeの設定も紹介してます)
Language: Rust, 他の言語でも可能
方法
やることざっくり
- accをインストール
- ojをインストール
- テンプレートを作成
- テスト・提出スクリプトを作成
- (エディタから実行出来るように設定)
導入
accのインストール
npm install -g atcoder-cli
acc --version
もしNode.jsがインストールされておらずnpmコマンドが使えない場合は、先にNode.jsをインストールしてください。
accの設定
AtCoder にログインするため、次のコマンドを実行します。
acc login
? username: <自分のアカウント>
? password: [hidden]
OK
OKと表示されればログイン成功です。
ojのインストール
oj(online-judge-tools)はAtCoder に限らずオンラインジャッジで配布されているテストケースを自動取得してローカルテストを行うためのツールです。
codeforcesやhackerrankなど他のオンラインジャッジでも使用可能です。
また、ojでも提出は出来ますが、今回はaccを使って提出します。
pip3 install online-judge-tools
oj --version
バージョンが表示されればインストール完了です。
もし oj コマンドが見つからない場合は、実行ファイルが置かれているディレクトリにPATHが通っているか確認しましょう。
ojが正しくインストールされている場合、以下のようにインストールパスを探せます。
python3 -m site --user-base
=> /Users/hoge/Library/Python/3.9
この場合は/Users/hoge/Library/Python/3.9/bin
にojの実行ファイルがあるか確認し、あるのに実行できない場合はPATHを通してください。
export PATH="$HOME/Library/Python/3.9/bin/:$PATH"
などを.zshrc
に追加してください。
ojの設定
ojでもatcoderにログインします。
oj login https://atcoder.jp/
このコマンドを実行するとブラウザが開いてログイン画面が表示されるのでログインしてください。
この時点で以下のコマンドを実行すればコンテストを取得できる状態ですが、まだテンプレート設定が済んでいないため、ここでは実行しません。
acc new [contest_id]
テンプレートの作成
問題の生成時にテンプレートmainファイルを作成する為の設定です。
必要の無い方は飛ばしてください。
これ以降の説明はテンプレートをこの通りに作ってた体で進めています。(テストスクリプト等)
私はRustを使っているため、rust_template
という名前のディレクトリにmain.rs
とtemplate.json
を作成しました。
以下がそのコマンドです。適宜修正して実行してください。
cd `acc config-dir`
mkdir rust_template
cd rust_template
touch main.rs
touch template.json
軽くこのコマンドの説明をしますと、cd `acc config-dir`でaccのコンフィグがあるディレクトリに移動し、そこにrust_templateという名前のディレクトリを作成しています。
その中にmain.rsとtemplate.jsonを作成していて、これがテンプレートのソースや設定になります。
use proconio::input;
fn main() {
input! {
n: i32,
}
}
{
"contest": {
"cmd": "cargo init . && cargo add proconio && rm src/main.rs"
},
"task": {
"program": [
["main.rs", "src/bin/{tasklabel}.rs"]
],
"submit": "src/bin/{tasklabel}.rs",
"testdir": "testcases/{tasklabel}"
}
}
template.jsonの設定方法はこちらですが、上の設定のみで良さそうです。
以下のコマンドでrust_templateディレクトリをデフォルトのテンプレートとして設定しています。
これを設定するとacc new
した際にデフォルトで上で作成したテンプレートが作成される様になります。
acc config default-template rust_template
また、コンテストファイルはデフォルトでディレクトリ毎に分けられているので以下を実行して一つのディレクトリ内に生成する様にします。ここは好みですが、以降のスクリプトはこの設定をしている前提で書いているので一度設定することをお勧めします。(デフォルト設定はacc config default-task-dirname-format "{tasklabel}"
)
acc config default-task-dirname-format "./"
最後に、問題を取得するときにすべての問題を一括取得するように設定します。
これを設定しない場合は、取得したい問題を都度選択する必要があります。
acc config default-task-choice all
テストスクリプトと提出スクリプトの作成
テストスクリプトを作成します。
git管理しているディレクトリに以下のスクリプトを作成してください。
#!/usr/bin/env bash
file_path=$1
file_path=$(cd $(dirname $file_path) && pwd)/$(basename $file_path)
contest_id=$(echo $file_path | sed -E 's|.*/([^/]+)/src/bin/[^/]+|\1|')
filename=$(basename $file_path)
task_label=${filename%.*}
echo "Testing: contest=$contest_id, task=$task_label"
cd $contest_id
oj t -c "cargo run --color always --bin $task_label" -d "testcases/$task_label"
#!/usr/bin/env bash
file_path=$1
file_path=$(cd $(dirname $file_path) && pwd)/$(basename $file_path)
contest_id=$(echo $file_path | sed -E 's|.*/([^/]+)/src/bin/[^/]+|\1|')
filename=$(basename $file_path)
task_label=${filename%.*}
task_id=${contest_id}_${task_label}
submit_path=$contest_id/src/bin/$filename
echo "Submitting: $submit_path (contest=$contest_id, task=$task_id)"
acc submit -c "$contest_id" -t "$task_id" "$submit_path"
この時点で./test.sh src/bin/a.rs
と./submit.sh src/bin/a.rs
でテストと提出が出来るようになっています。
chmodで実行権限を付与してください。
例) sudo chmod 755 ./test.sh
エディタから実行出来るように設定
私はRustRoverを使っているのでExternal toolsにスクリプトをセットし、キーバインドを設定してショートカットで呼び出すようにしています。
ツールの作成
ツールはSettings -> Tools -> External Tools
で以下の様に追加しています。
テストツール作成
提出ツール作成
ショートカットの設定
ショートカットは Settings -> Keymap -> External Tools -> External Tools
から設定しています。
VSCodeの場合
VSCodeから設定する場合は以下のように設定してください。
{
"version": "2.0.0",
"tasks": [
{
"label": "AtcoderRustCodeTest",
"type": "shell",
"command": "./test.sh ${file}",
"presentation": {
"reveal": "always",
"focus": true,
"panel": "shared"
}
},
{
"label": "AtcoderRustCodeSubmit",
"type": "shell",
"command": "./submit.sh ${file}",
"presentation": {
"reveal": "always",
"focus": true,
"panel": "shared"
}
}
]
}
[
{
"key": "ctrl+t",
"command": "workbench.action.tasks.runTask",
"when": "editorTextFocus",
"args": "AtcoderRustCodeTest"
},
{
"key": "ctrl+s",
"command": "workbench.action.tasks.runTask",
"when": "editorTextFocus",
"args": "AtcoderRustCodeSubmit"
}
]
keybindings.jsonはVScode -> Preferences -> Keyboard Shortcuts
から設定できます。
これでエディタからテストと提出が出来るようになりました。
(追記)vscodeで開くディレクトリはatcoder_rust
である必要がありました(.vscodeやスクリプトが無いため)。解決策としてはtemplateディレクトリにシェルスクリプトも追加するようにcmdを編集する等があるかと思いますが、試していないので各自設定をお願いします。
VSCodeの方も以下の様にすることでvscodeでコンテストディレクトリを開いた場合でも正常に動く様になります
template.json
を以下の様に変更
{
"contest": {
"cmd": "cargo init . && cargo add proconio && rm src/main.rs",
"static": [".vscode", "test.sh", "submit.sh"] // ここを追記
},
"task": {
"program": [
["main.rs", "src/bin/{tasklabel}.rs"]
],
"submit": "src/bin/{tasklabel}.rs",
"testdir": "testcases/{tasklabel}"
}
}
さらに、rust_template
ディレクトリの中に.vscode
, test.sh
, submit.sh
をコピーする
この状態でacc new
することで各コンテストディレクトリにスクリプトと.vscodeがコピーされることになりvscodeでコンテストディレクトリを開いてもスクリプトが機能します。
コンテストの取得
ここまでで実際にコンテストを取得してテスト&提出する準備が出来たので実際にacc new
でコンテストを取得して試してみましょう。
(私の場合は)atcoder_rust
ディレクトリに移動してacc new abc100
(例)としてからrustrover abc100
(or code abc100
)とするとコンテストを取得してコーディング出来ます。
対象のファイルを開いた状態で、ctrl+t
でテスト、ctrl+s
で提出が出来ると思います。
テスト実行結果
テストショートカットでテストを実行した結果
提出実行結果
提出ショートカットで提出を実行した結果
提出の確認の為にAre you sure? Please type "abca"
などと聞かれるのでabca
と入力してエンターを押すと提出されます。
おわりに
ここまで、AtCoderをはじめとするオンラインジャッジにおいて、ローカル環境での効率的なテストと提出のワークフローを整える方法を紹介してきました。
エディタ連携やスクリプトの作成を一度設定してしまえば、以後のコンテストでの開発速度が格段に上がり、コードの品質も保ちやすくなります。
ぜひ自分の環境に合わせて各種ツールをカスタマイズし、快適な競プロライフを楽しんでください。
Discussion