🦖

(付録(仮))WSLのUbuntuにatcoder-cliとojを準備する

2025/03/04に公開

競技プログラミングを始めたばかりの人は、サイトの解答フォームにコードを直接書いたり、ローカルで書いたコードをコピペで張り付けたりしたあと、サイトのテスト機能を使ってテストし、提出ボタンで提出していると思います。

しかし、競技プログラミング等の解答コードを競プロサイトの解答スペースではなく、自分のお気に入りのエディタで作成し、出来上がったコードが正常に動くかローカルでチェックして、それからサイトへコマンド一発で提出する。これが、競プロ初心者の第一歩です!

この為に巷でよく使われるのが、oj(Online Judge Tools)atcoder-cliの二つのツールです。ojは、色々ある競プロサイトと汎用的に連携するために開発された便利ツールです。そして、このojをatcoderに特化して、より便利に使えるようにするのがatcoder-cliです。

この記事では、まず両ツールのインストールの肝を紹介した後、具体的な使い方を紹介していきます。

尚、これらのツールを使うにはatcoderアカウントが必要です。持っていない人は先にアカウントを準備しておきましょう。

https://atcoder.jp/

ページの右上の「新規登録」からアカウントを作ることが出来ます。

インストールの肝

両ツールについては、各配布ページに詳細なインストール方法や使い方が載っているので、そこにも目を通す必要があると思いますが、ここでは主に今どきのWLS上Ubuntu環境の話に特化してインストールの肝を紹介します。(もちろん、他のLinuxシステムでも参考になると思います)

oj(Online Judge tools)のインストール

https://github.com/online-judge-tools/oj

ojは、Onlline Judge Toolsという、Pythonのパッケージです。

Pythonのパッケージのインストールは、昨今、色々な方法で説明される状況になっていますが、ここではpipxを利用したインストール方法を紹介します。pipxをお勧めする理由は、インストールしたいパッケージがライブラリ用途ではなくて、コマンド用途として使うものであるという点です。ojはまさに、そういう場合に当たり、そして、pipxはそんなコマンドを簡単にユーザー領域にpythonの他の環境から独立してインストールしてくれる代替pipなのです。興味のある方は下にあるコラムにも目を通してみてください。

pipxでojをインストールする

まず、pipxをインストールします。

prompt
sudo apt install pipx

pipxがインストール出来たら、そのpipxを使って、ojをインストールします。

以下のコマンドで、pipxを介して、online-judge-toolsパッケージとそれが必要とするパッケージが独立した環境にインストールされます。(ユーザー環境内であることも安心)--include-depsオプションは、インストールするものが必要とするパッケージをこの環境に一緒にインストールさせるためのものです。

prompt
pipx install online-judge-tools --include-deps

但し、実は、--include-depsを付けていても、ojが必要とするsetuptoolsパッケージがインストールされず、この状態でojを実行するとエラーになります。

そこで、必ず、このsetuptoolsパッケージをこの環境に手動でインストールします。これは、pipxのinjectコマンドで出来るので、次のコマンドを実行してsetuptoolsパッケージをこの環境に追加インストールします。

prompt
pipx inject online-judge-tools setuptools

以上で、ojのインストール作業は完了です。

インストールされているかどうか、パスが通っているかどうか等の確認のためバージョン情報を確認してみましょう。

prompt
oj --version

pipxでのメンテナンス

ついでに、pipxによるパッケージのメンテナンスも頭の片隅に入れておきましょう。

パッケージの更新

prompt
pipx upgrade online-judge-tools

パッケージのアンインストール

prompt
pipx uninstall online-judge-tools

atcoder-cliのインストール

https://github.com/Tatamo/atcoder-cli

atcoder-cliの利用には、nodejsが必要になります。もし、システムにnodejsが無いならば、Ubuntuのパッケージとしてnodejsとそのパッケージ管理ツールであるnpmの2つをインストールします。

prompt
sudo apt install nodejs npm

インストールが終わったら、npmコマンドでatcoder-cliをインストールします。
npmコマンドでは以下の様に、--prefixオプションを使うことで、グローバルではなく、ユーザー領域の ~/.localにインストールすることが出来ます。

prompt
npm install -g --prefix ~/.local atcoder-cli

ツールを使う準備

accコマンド及びojコマンドを使うためには、まず、各コマンドでatcoderにログインしておく必要があります。いったんログインしておけば、その状態が継続するので、コマンドを使うたびにログインしなくてもよくなります。

AtCoderにログイン

accでログイン

prompt
acc login

コマンドを実行後、ログインプロンプトが出るのでアカウントとパスワードを入力


accでatcoderアカウントにログイン

次に、ojでログイン

prompt
oj login https://atcoder.jp/

accと同様にコマンドを実行後、ログインプロンプトが出るのでアカウントとパスワードを入力します。


ojでatcoderアカウントにログイン

accの動作設定

以下のコマンドで、accの設定がイイ感じになります。

prompt
acc config default-task-choice all

扱う言語をHaskellにする

AtCoderであなたが戦いに挑むプログラム言語の準備を行います。

あなたが設定したい言語はなんですか?
1. Haskell
2. Haskell
3. Haskell
> _

もちろん、いいんですよ、、cppでもpythonでも、、

しかしここでは、Haskellを例に、紹介を進めます。

accの設定ファイルを置く場所~/.config/atcoder-cli-nodejsに移動します。

prompt
cd ~/.config/atcoder-cli-nodejs

このディレクトリに自分の扱う言語用のディレクトリを作成して、ディレクトリの中に入ります。

prompt
mkdir haskell
cd haskell

template.jsonを作成して以下の内容にします。

template.json
{
  "task":{
    "program": ["Main.hs"],
    "submit": "Main.hs",
    "testdir": "tests"
  }
}

次に、自分好みの初期コードを書いたMain.hsを作成します。

Main.hs
main=do
    s <- getLine
    putStrLn s

haskellのコードで戦う準備が完了したら、accに以下のコマンドで戦う言語がhaskellであることを伝えます。

prompt
acc config default-template haskell

以上で、扱う言語に関する設定は完了です。

ディレクトリの状態を確認しておきましょう。

~/.config/atcoder-cli-nodejs 
 ├── config.json
 ├── haskell
 │   ├── Main.hs
 │   └── template.json
 └── session.json

競プロコード用のディレクトリを作る

これらのツールは、コマンドを実行した場所の直下にコンテスト毎のディレクトリを作ってその中に、回答用コードのテンプレートファイルを作成し、テストケース用のサブディレクトリを作ってその中にテストケースデータファイルをダウンロードしてくれます。

なので、まずはそのルートとなるコンテストデータ置き場用のディレクトリを作成しましょう。

prompt
mkdir ~/procon

以下このディレクトリでの作業を行います。

快適なAtCoder環境のはじまり

いよいよ、ツールを実際に使っていきます。

oj & acc ツールを使ったワークフローは以下の通りです。

  1. 対象コンテストのディレクトリを作成して、そのディレクトリに入る
  2. 解きたい小問のサブディレクトリに入る
  3. コードファイルをエディタで開いて解答
  4. ターミナルでテストケースを試す
  5. ターミナルから提出
  6. 開いたWebページでAC等を確認
  7. 次の問題へ

なお、対象の問題のページを別途Webブラウザー等で開いておくことを忘れてはいけません

https://atcoder.jp/contests/abc101

上部にあるタブから「問題」を選んで問題一覧ページを開いておきましょう。

コンテストディレクトリの作成

以下のコマンドを実行すると、AtcoderのABC101のコンテストの問題がダウンロードされます。

prompt
acc new abc101

accコマンドの書式は以下の通り。

書式
acc new [コンテスト名]

[コンテスト名]の部分は、大体ABCコンテストならば、abc+3桁数字でOKです。

ダウンロードが完了したら作成されたコンテストのディレクトリabc101に入りましょう。

prompt
cd abc101

abc101ディレクトリの下にな、以下の様な構成のファイルが準備されます。

abc101
├── a
│   ├── Main.hs
│   └── tests
│       ├── sample-1.in
│       ├── sample-1.out
│       ├── sample-2.in
│       ├── sample-2.out
│       ├── sample-3.in
│       └── sample-3.out
├── b
│   ├── Main.hs
│   └── tests
│       ├── sample-1.in
│       ├── sample-1.out
│       ├── sample-2.in
│       ├── sample-2.out
│       ├── sample-3.in
│       └── sample-3.out
├── c
│   ├── Main.hs
│   └── tests
│       ├── sample-1.in
│       ├── sample-1.out
│       ├── sample-2.in
│       ├── sample-2.out
│       ├── sample-3.in
│       └── sample-3.out
├── contest.acc.json
└── d
    ├── Main.hs
    └── tests
        ├── sample-1.in
        └── sample-1.out

小問のサブディレクトリに入る

各小問毎にサブディレクトリが用意されています。

ここでは、a問題に挑戦するために、a/のディレクトリに入ります。

prompt
cd a

各小問ディレクトリの中には、自分が設定で用意した、テンプレートの解答ファイルと、ダウンロードしてきたテストケースのファイルが入っているサブディレクトリがあります。

ファイルをお気に入りエディタで開いて解答を書く

お気に入りのエディタで用意してある解答用ファイルを開きましょう。
さぁ、いよいよバトルの開始です!

prompt
nvim Main.hs

例えば、以下の様な解答コードを作成します。

Main.hs
main=do
    s <- getLine
    print $ foldl (\acc c -> if c == '+' then acc + 1 else acc - 1) 0 s

コードをローカルでチェック

コードが書けたら、ターミナルに戻って以下のコマンドを実行します。

prompt
oj t -c "runghc Main.hs" -d tests

サンプル問題でのジャッジが行われるので、ACが出ているのを確認します。


ojによるサンプルテストのジャッジ

ターミナルからAtCoderに提出

コードが大丈夫そうなら、次のコマンドでAtCoderに提出します。

prompt
acc s

メッセージとともに確認の入力を求められるので、指示された文字列を入力します。


AtCoderへの提出の様子

次の問題へ

accojの上述のコマンドは、カレントディレクトリが小問ディレクトリであることが前提となっています。つまり、次の問題に移るときに、エディタ内でb問題のファイルを選択して編集して、カレントディレクトリを移していない等の状況に注意する必要があります。

なので、当該ワークフローを使う場合は、問題毎にカレントディレクトリをきっちりと移動しましょう。

promptカレントディレクトリ移動の例
cd ../b
nvim Main.hs

最後に

この記事は、(付録(仮))シリーズで、何の付録かといえば、将来、出来るであろう「Haskell初心者本」の付録の予定です。

accに関しては、acc newacc addした時に、簡単な処理をしたり、スクリプトを走らせたりすることが出来るので、コードの環境を自分の思いどおりのディレクトリ構成に作り替えることが出来るみたいです。Haskellでも多分、コンテスト単位でstack環境を自動で作るようにできるんだと思いますが、まだ、そこまで試していません(乞うご期待!)。

さて、この記事を最後まで読んでいるという事は、多分あなたも競プロの人だと思います。

でも、多分、、、Haskellで戦っておられるわけでは無い、、、なので、「なんで、そんなマイナーなHaskellの設定なんだよ?! C++のは? Pythonのは? Goのは?」と憤っています??

そんなあなた、諦めてHaskellで競プロやってみませんか?

もう、いいじゃないですか?設定がHaskellになっちゃったんですから!

というわけで、ココまで読んでしまった方!今からもうハスケラーになるしかありませんよ!

ネっ!

Discussion