VSCodeでNimのAtCoder環境を構築
Pythonライクで処理速度の速いAtCoderに最適な言語の1つNimの環境構築について、ご参考までに書いておきます。
環境の前提
- Windows
- WSL2
- VSCode
皆さん、基本はC++やPythonなどを使っていて、完全にNimにスイッチするわけではないでしょう。
ぜひ、この機会にDockerの導入を検討ください。
コンテナごとに環境を持てて、非常に快適です。
VSCodeのdevcontainerでAtCoder環境を構築という記事も、あわせてご覧ください。
インストール(Dockerfile)
ここではDockerfileとして挙げておきますが、そうでなくても、(見ればわかると思いますが)WORKDIR → cdと読み替えて、RUN以下のコマンドを打っていけばいいだけです。
Dockerfileとしては、基本はubuntunに、2023年の言語アップデート時の提案シート通りにinstall commandを書いただけ。
みんな大好きonline-judge-tools(まだ、コンテスト中は使えますから…)も入れてあります。
(online-judge-toolsについては、このDockerfileを使ったVSCodeのdevcontainer内でsubmitしても、結果表示のブラウザが立ち上がらなかったので、submit.pyのshow resultのところのutils.webbrowser_register_explorer_exe()の行をコメントアウトして使っています。)
Nim Language Serverが開発され、LLVMで高度なデバッグができるよ、ということのようですが、わたくしにはうまく使いこなせませんでしたので、コメントアウトしてあります…
FROM ubuntu:22.04
# Nim
RUN apt update && apt install -y curl xz-utils g++ git build-essential time
RUN curl https://nim-lang.org/choosenim/init.sh -sSf | bash -s -- -y
ENV PATH=/root/.nimble/bin:$PATH
# neo
RUN nimble install neo -y
# OpenBLAS
RUN apt install libopenblas-base -y
# Nim-ACL
RUN nimble install https://github.com/zer0-star/Nim-ACL
# bignum
RUN nimble install bignum -y
# Nim Language Server
RUN nimble install nimlangserver -y
# LLVM
#RUN apt install clang-format clang-tidy clang-tools clang clangd libc++-dev libc++1 libc++abi-dev libc++abi1 libclang-dev libclang1 liblldb-dev libllvm-ocaml-dev libomp-dev libomp5 lld lldb llvm-dev llvm-runtime llvm python3-clang -y
# gbd
RUN apt install -y gdb
# online-judge-tools
RUN apt install -y python3-pip &&\
#pip3 install online-judge-tools
pip3 install git+https://github.com/sukenori/oj.git
# Docker
RUN apt install -y docker.io
参考①(devcontainer.json)
あくまで、VSCodeのdevcontainerでAtCoder環境を構築の通りのディレクトリ構造にしたら、こうなりますよ、という参考として挙げておきます。
{
"name": "AtCoder-Nim",
"build": {
"dockerfile": "Dockerfile_AtCoder-Nim"
},
"workspceMount": "source=C:/Users/ユーザー名/OneDrive/Development/Competitive_Programming/Workspaces/AtCoder/AtCoder-Nim,target=/workspaces/AtCoder-Nim,type=bind",
"workspaceFolder": "/workspaces/AtCoder-Nim",
"mounts": [
"source=C:/Users/ユーザー名/OneDrive/Development/Competitive_Programming/Solved_Code,target=/workspaces/Solved_Code,type=bind",
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"
],
"customizations": {
"vscode": {
"extensions": [
"NimLang.nimlang",
//"vadimcn.vscode-lldb",
"GitHub.copilot",
"GitHub.copilot-chat",
"ms-azuretools.vscode-docker"
]
}
},
"postCreateCommand": "./.devcontainer/postCreateCommand.sh"
}
参考②(postCreateCommand.sh)
文字通り、コンテナクリエイト後に走るスクリプトですので、ojのログインなんかをします。
2023年の言語アップデート時点では、Nimは1.6.14ですので、choosenim 1.6.14としてダウングレードしておいてもいいと思います。
#!/bin/bash
RUN choosenim 1.6.14
oj login -u ログイン名 -p パスワード https://atcoder.jp/
参考③(.code-workspace)
さっきマウントしておいたディレクトリで、ワークスペースを構成します。
(提出コード集部分は一例です。)
コンテストが終わったら、.Contesutから中身を移していったりします。
{
"folders": [
{
"name": "AtCoder-Nim",
"path": "/workspaces/AtCoder-Nim"
},
{
"name": "AtCoder_Beginner_Contest",
"path": "/workspaces/Solved_Code/AtCoder/AtCoder_Beginner_Contest"
},
{
"name": "AtCoder_Regular_Contest",
"path": "/workspaces/Solved_Code/AtCoder/AtCoder_Regular_Contest"
},
{
"name": "AtCoder_Grand_Contest",
"path": "/workspaces/Solved_Code/AtCoder/AtCoder_Grand_Contest"
},
{
"name": "ABC_Like_Contest",
"path": "/workspaces/Solved_Code/AtCoder/ABC_Like_Contest"
},
{
"name": "ARC_Like_Contest",
"path": "/workspaces/Solved_Code/AtCoder/ARC_Like_Contest"
}
],
"settings": {
"terminal.integrated.env.linux": {
"PATH": "${env:PATH}:/workspaces/AtCoder/.workspaces/Nim"
}
}
}
tasks.json
ojの自動化を導入するので、コンパイル、テストのダウンロード、テスト、提出の各taskを用意します。
コンパイルオプションは、これもしつこく言語アップデート時の提案シートに揃えてみたりしています。
(汚らしいですが、デバッグを試みた跡がコメントアウトしてあります。)
コンパイルをデフォルトのタスクにして、提出のタスクにショーカットをつければ、その2つのショートカットでほぼほぼCLI要らずになります。というのも、提出のタスクは、testディレクトリの削除→サンプルケースのダウンロード→テスト→提出のコンボにしてあるからです。URL渡しは、サンプルケースのダウンロード時に、出てくるウィンドウに問題文URLをコピペするだけです(Chrome拡張機能を使うとさらにいい感じです)。
{
"version": "2.0.0",
"tasks": [
{
"label": "nim build",
"group": {
"kind": "build",
"isDefault": true
},
"type": "shell",
"command": "${userHome}/.nimble/bin/nim",
"args": [
"cpp",
//"c",
"-d:release",
"--opt:speed",
"--multimethods:on",
//"--warning[SmallLshouldNotBeUsed]:off",
"--hints:off",
"-o:a.out",
"${file}",
//"-g",
//"--cc:clang",
//"--debuginfo:on"
//"--cc:gcc",
//"--debugger:native"
],
"presentation": {
"panel": "shared"
}
},
{
"label": "remove test",
"type": "shell",
"command": "rm",
"args": [
"-rf",
"${workspaceFolder}/test"
],
"presentation": {
"panel": "shared"
}
},
{
"label": "download test",
"type": "shell",
"command": "oj",
"args": [
"d",
"${input:url}",
"-d",
"${workspaceFolder}/test",
"-s"
],
"presentation": {
"panel": "shared",
"showReuseMessage": false
},
"dependsOn": ["remove test"],
"dependsOrder": "sequence"
},
{
"label": "test",
"type": "shell",
"command": "oj",
"args": [
"t",
"-c",
"${workspaceFolder}/a.out",
"-d",
"${workspaceFolder}/test/"
],
"presentation": {
"panel": "shared"
}
},
{
"label": "nim submit",
"type": "shell",
"command": "oj",
"args": [
"s",
"${input:url}",
"${file}",
"-w",
"0",
"-y"
],
"presentation": {
"panel": "shared"
},
"dependsOn": ["nim build","download test","test"],
"dependsOrder": "sequence"
},
],
"inputs": [
{
"type":"promptString",
"id":"url",
"description": "URL of the task"
}
]
}
尊敬する優秀なNim使いの皆さんによって、Nim-ACLも整備され、非常に快適な環境が整えられています。
それだけに、後は、実力だけなんですよね…
Discussion