🌟

AtCoderでエディタからテストと提出が出来るまで

2025/01/02に公開

概要

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, 他の言語でも可能

方法

やることざっくり

  1. accをインストール
  2. ojをインストール
  3. テンプレートを作成
  4. テスト・提出スクリプトを作成
  5. (エディタから実行出来るように設定)

導入

accのインストール

zsh
npm install -g atcoder-cli
acc --version

もしNode.jsがインストールされておらずnpmコマンドが使えない場合は、先にNode.jsをインストールしてください。

accの設定

AtCoder にログインするため、次のコマンドを実行します。

zsh
acc login
? username: <自分のアカウント>
? password: [hidden]
OK

OKと表示されればログイン成功です。

ojのインストール

oj(online-judge-tools)はAtCoder に限らずオンラインジャッジで配布されているテストケースを自動取得してローカルテストを行うためのツールです。

codeforcesやhackerrankなど他のオンラインジャッジでも使用可能です。

また、ojでも提出は出来ますが、今回はaccを使って提出します。

zsh
pip3 install online-judge-tools
oj --version

バージョンが表示されればインストール完了です。

もし oj コマンドが見つからない場合は、実行ファイルが置かれているディレクトリにPATHが通っているか確認しましょう。

ojが正しくインストールされている場合、以下のようにインストールパスを探せます。

zsh
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にログインします。

zsh
oj login https://atcoder.jp/

このコマンドを実行するとブラウザが開いてログイン画面が表示されるのでログインしてください。

この時点で以下のコマンドを実行すればコンテストを取得できる状態ですが、まだテンプレート設定が済んでいないため、ここでは実行しません。

zsh
acc new [contest_id]

テンプレートの作成

問題の生成時にテンプレートmainファイルを作成する為の設定です。

必要の無い方は飛ばしてください。

これ以降の説明はテンプレートをこの通りに作ってた体で進めています。(テストスクリプト等)

私はRustを使っているため、rust_templateという名前のディレクトリにmain.rstemplate.jsonを作成しました。
以下がそのコマンドです。適宜修正して実行してください。

zsh
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を作成していて、これがテンプレートのソースや設定になります。

main.rs
use proconio::input;

fn main() {
    input! {
        n: i32,
    }
}
template.json
{
  "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した際にデフォルトで上で作成したテンプレートが作成される様になります。

zsh
acc config default-template rust_template

また、コンテストファイルはデフォルトでディレクトリ毎に分けられているので以下を実行して一つのディレクトリ内に生成する様にします。ここは好みですが、以降のスクリプトはこの設定をしている前提で書いているので一度設定することをお勧めします。(デフォルト設定はacc config default-task-dirname-format "{tasklabel}")

zsh
acc config default-task-dirname-format "./"

最後に、問題を取得するときにすべての問題を一括取得するように設定します。

これを設定しない場合は、取得したい問題を都度選択する必要があります。

zsh
acc config default-task-choice all

テストスクリプトと提出スクリプトの作成

テストスクリプトを作成します。
git管理しているディレクトリに以下のスクリプトを作成してください。

test.sh
#!/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"
submit.sh
#!/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で以下の様に追加しています。

テストツール作成

testツール作成

提出ツール作成

提出ツール作成

ショートカットの設定

ショートカットは Settings -> Keymap -> External Tools -> External Toolsから設定しています。
ショートカットの設定

VSCodeの場合

VSCodeから設定する場合は以下のように設定してください。

.vscode/tasks.json
{
  "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"
      }
    }
  ]
}
keybindings.json
[
  {
    "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を以下の様に変更

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で提出が出来ると思います。

テスト実行結果

テストショートカットでテストを実行した結果
test実行

提出実行結果

提出ショートカットで提出を実行した結果

提出の確認の為にAre you sure? Please type "abca"などと聞かれるのでabcaと入力してエンターを押すと提出されます。

おわりに

ここまで、AtCoderをはじめとするオンラインジャッジにおいて、ローカル環境での効率的なテストと提出のワークフローを整える方法を紹介してきました。

エディタ連携やスクリプトの作成を一度設定してしまえば、以後のコンテストでの開発速度が格段に上がり、コードの品質も保ちやすくなります。

ぜひ自分の環境に合わせて各種ツールをカスタマイズし、快適な競プロライフを楽しんでください。

Discussion