VSCodeでAtCoderをしたい!!

最近AtCoderのエディタもインデントをそろえたり、補完をしてくれたりと結構便利なんですが、それでもVSCode上でAtCoderのテストや提出をできるようにしたかったのでやってみました！
※この記事はpythonでの提出を前提で書いています。

### この記事での環境
- Windows 11 Home 22H2
- VSCode 1.83.1
- python 3.11.5

## 参考にしたサイト

https://qiita.com/ShortArrow/items/0bacd3a4bcbcbac50e60

https://qiita.com/ajim/items/4d350710ba70056f5f6f

https://github.com/online-judge-tools/oj/blob/master/docs/getting-started.ja.md

https://github.com/online-judge-tools/template-generator/blob/master/README.ja.md

## 準備

pipから以下をインストールします。
- `online-judge-tools`
- `online-judge-template-generator`

これらは問題をスクレイピングしてDLしてくれるツールです。ほかにも提出やテストもしてくれます。
```
> pip3 install online-judge-tools online-judge-template-generator
```
:::note warn
依存関係であるMarkupSafeのバージョンが2.0.1より高いものがインストールされている場合は2.0.1にダウングレードしてください。
:::
## ログイン
提出するためにログインする必要があります。
```
> oj login -u [ユーザー名] -p [パスワード] "https://atcoder.jp/"
```
`oj`コマンドが存在しない的な感じのエラーの場合はお使いのshellを再起動してください。

## 問題をDLする
問題を取得するときにURLを入力する必要があります。
```
> oj-prepare https://atcoder.jp/contests/abc326
```
すると現在のディレクトリに以下のようなファイル群ができるはずです。
```
.\
├─abc326_a
│  │  generate.py
│  │  main.cpp
│  │  main.py
│  │
│  └─test
│          sample-1.in
│          sample-1.out
│          sample-2.in
│          sample-2.out
│          sample-3.in
│          sample-3.out
│
~~~~~~~~~~~~~~~省略~~~~~~~~~~~~~~~

│
└─abc326_g
    │  generate.py
    │  main.cpp
    │  main.py
    │
    └─test
            sample-1.in
            sample-1.out
            sample-2.in
            sample-2.out
            sample-3.in
            sample-3.out
```
これでDLは完了しました。
## 問題を解く
それぞれのディレクトリにできた`main.py`の`solve`関数の中身に回答していきます。
`online-judge-template-generator`が自動で問題の読み込みの所を書いていてくれているのでそこで悩む必要はなくなります。
## テストを行う
まず、`main.py`があるディレクトリに移動します。
```
> cd abc326_a
```
次に、以下のコマンドでテストします。
```
> oj test -c 'python main.py' -t 2
```
- -c でpythonを指定してあげます。他の言語はここら辺を変更するとおそらくできるのではないかと思います。
- -tオプションはTLEの時間です。デフォルトでは無制限なので設定しておきます。

:::note info
テストが成功すると以下のような画面が出ると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3305928/ae2a61c2-1549-6855-2833-2da9a9256f9b.png)
:::
## 提出
以下のコマンドで提出ができます。

```
oj submit main.py -l 5082
```
うまくいけばブラウザが開き、結果が表示されます。

-lオプションは提出する言語を選択しています。本当だったらうまく推測してくれるっぽいですが指定なしだと、提出する言語が特定出来なかった的なエラーが出たので指定しています。
2023.10.30日現在、
- (CPython 3.11.4) -> 5055
- (Cython 0.29.34) -> 5082

を指定すればよさそうです。
-lオプションを書かずにコマンドを動かして、うまく提出できなかった時に番号は見れます（笑）

## VSCodeのタスクに登録
テストや提出するときにshellに毎回打ち込むのはめんどくさいのでVSCodeのタスクに登録しておきます。

**メニュー→ターミナル→タスクの構成** でtasks.jsonが生成されます。
以下に登録した内容を記載しておきます。
```
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "download problem",
            "detail": "問題をダウンロードします",
            "type": "shell",
            "command": "mkdir ${input:problemNo} && cd ${workspaceFolder}\\${input:problemNo} && oj-prepare https://atcoder.jp/contests/${input:problemNo}"
        },
        {
            "label": "test",
            "detail": "テストします",
            "type": "shell",
            "command": "cd ${workspaceFolder}\\${relativeFileDirname} && oj test -c 'python ${file}' -t 2",
        },
        {
            "label": "submit (CPython 3.11.4)",
            "detail": "(CPython 3.11.4)で提出します",
            "type": "shell",
            "command": "cd ${workspaceFolder}\\${relativeFileDirname} && oj submit ${fileBasename} -l 5055"
        },
        {
            "label": "submit (Cython 0.29.34)",
            "detail": "(Cython 0.29.34)で提出します",
            "type": "shell",
            "command": "cd ${workspaceFolder}\\${relativeFileDirname} && oj submit ${fileBasename} -l 5082"
        }
    ],
    "inputs": [
        {
            "id": "problemNo", // ${input:***}で指定したID
            "description": "AtCoderの問題Noを入力してください", // 入力説明文
            "default": "", // デフォルト入力値
            "type": "promptString" // 入力タイプ
        }
    ]
}
```
- 問題をDLするときはワークスペース以下に問題名のフォルダを作成して、その下にDLしたものを置くようにしています。**"inputs"** を利用することでこのタスクを選択したときにテキストフィールドが表示され、そこにコンテスト名(abc326など)を入れるとDLしてくれるようにしています。
- テストと提出は現在開かれているファイルに対して行うようにしてます。

## タスクを実行
**メニュー→ターミナル→タスクの実行...** から実行したいタスクを選択することでタスクを利用できます。

これで、VSCode上でAtCoderのテストと提出ができるようになりました! :tada:

# 最後に
今回はVSCodeでAtCoderをできるようにしました。何かしら参考になるとうれしいです :laughing:

では、みなさま良き競プロライフを :wave: