👋

JavaScriptでAtCoderを始める方法(環境構築~実際のテストまで)Windows編

2023/12/03に公開

はじめに

この記事は みすてむず いず みすきーしすてむず Advent Calendar 2023 の4日目の参加記事です。
カレンダー:
https://adventar.org/calendars/8596
みすてむず いず みすきーしすてむず:
https://misskey.systems/

昨日はたまさんの今年また沼った文房具の話でした。
文房具、好きなんですが、なーんかやっぱりうまくあわないなーってなってやめることが多いですw
でも文房具界隈のアカウントを紹介されていたので、もしかしたら沼に…

AtCoderとは

以下2つ引用します。

AtCoder公式サイト
https://atcoder.jp/

AtCoderは、世界最高峰の競技プログラミングサイトです。
リアルタイムのオンラインコンテストで競い合うことや、
5,000以上の過去問にいつでもチャレンジすることができます。

AtCoder に登録したら次にやること ~ これだけ解けば十分闘える!過去問精選 10 問 ~
https://qiita.com/drken/items/fd4e5e3630d0f5859067

プログラミングを使って、パズル的な問題を、制限時間内に出来るだけ多く解くスポーツ

利点

競技プログラミングは仕事などの役に立たないのではと言われることもあるようですが、やっている実感としてはコーディングに対するスピード感が上がったような気がします。つまり、仕様を読み込む・機械らしい振る舞いに置き換える・コードにするという一連の動作が洗練されていくのではないかなと思っています。
またJavaScriptを選択する利点についても言及します。
競技プログラミングは、C++やPythonなどで取り組む方が多いようですし、実際プログラミングをやってみたい!気合と時間はある!というのであればPythonなんかを勉強してみるのもいいでしょう。JavaScriptの利点は「世界で一番使われている(と言われる)言語であること」「ブラウザさえあればどこでも動く」というところかなと思います。
作るのも、使うのも、調べるのも楽なのは大きなアドバンテージですよね。
競技プログラミングをやるだけでは、正直なにか実用的なものが作れるようになるかというと足りませんが、もう少し踏み込んで学習すれば、WEBアプリケーションが作れる日も近い!はず!

本稿でできるようになること

JavaScriptでAtCoderに挑戦するための環境構築と、その環境を用いたAtCoderへの挑戦方法をお伝えします。
実は、本当に何も準備しなくても一応ブラウザだけで完結することは可能です。
ただ、一度準備をしてしまえばデバッグや提出が楽になりますし、エディターの補完機能は現代のプログラマーの必須道具ですからね。

環境構築方法

macとWindowsで一部手順が異なりますが、結果だけ言えば、Node.jsとonline-judge-tools、atcoder-cliが導入された環境を作ります。
筆者はWindowsのため、macの手順は一部誤りがあるかもしれません。一応知り合いに試してみてもらっているので大丈夫なはずです。

  1. VSCodeをインストールする
  2. WSL2、Ubuntuを導入する
  3. Node.jsをインストールする
  4. online-judge-toolsをインストールする
  5. atcoder-cliをインストールする
  6. 各種設定を行う

1. VSCodeをインストールする

こういうところは省いていきますよ~
下記リンクからどうぞ。
https://code.visualstudio.com/Download

インストールができたら拡張機能に下記を追加してください。
https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh

2. WSL2、Ubuntuを導入する

下記ページを参考にしてください。
https://learn.microsoft.com/ja-jp/windows/wsl/install

びっくりするほど楽になりましたね…
PowerShellを管理者モードで開いて下記を入力するだけだそうです。

wsl --install

初期でインストールされるのもUbuntuらしいので文句なしです。

3. Node.jsをインストールする

一応Node.jsとはなにかを簡単に述べます。
Node.jsとはJavaScriptを実行するための環境です。本来のJavaScriptはブラウザ上でのみ動作しますが、Node.jsではコンピュータ自体の機能にアクセスできますので、サーバーサイド側のアプリケーションを作成できます。

3.1 asdfをインストールする

asdfとは、Node.jsのバージョン管理を行うツールです。
他にもnvmとかnとか色々あるけど自分が読んだ教本でおすすめされてたのでこれにしています。Node.jsがインストールできればいいので、正直多分なんでもいいんですが、バージョン管理はできたほうがいいですね。
インストール方法について、基本は下記ページの指示に従ってください。
https://asdf-vm.com/guide/getting-started.html

インストールしたWSLを実行すると、コマンドラインの画面でUbuntuが起動するはずです。
初回は、インストールを待つかもしれません。
その後ユーザー名とパスワードを聞かれますので、入力、設定してください。
終わったら以下をコピペしてください。シェルの入力は頭に$ がついていますので、そこは外してコピーしてくださいね。

$ sudo apt update
$ sudo apt -y upgrade
$ sudo apt install curl git
$ git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.13.1

上記のコマンドは、最初から入っているパッケージの最新化や、バージョン管理ツールGitのインストール、asdf本体のインストールを行っています。
次に下記を実行してください。

$ vim ~/.bashrc

上記コマンドは、「.bashrc」というファイルをエディタで開くもので、文字列が下まで並んだ画面が開くはずです。
そこで、カーソルキーで一番下までスクロールし、aを入力すると、insertモード(編集モード)に変わるので、一番下に下記文言を加えてください。
うまく操作できない場合は「vim」で操作方法を調べてみてくださいね。

. "$HOME/.asdf/asdf.sh"
. "$HOME/.asdf/completions/asdf.bash"
alias oj-t-js='oj t -c "node main.js" -d ./js/'
alias acc-s-js='acc submit -s -- -l 5009'

追記できたら、ESCキーでinsertモードが終了します。
続けて:wqと打つと保存して閉じます。
ちなみに内容ですが上2行はasdfの有効化のため。
下に行は先取りだけど、AtCoderの提出とかを楽にするツールの設定。
エイリアス(コマンドを短縮登録しておく機能)を設定し、簡単にソースコードのテスト、提出が行えるようにするものです。
最後に.bashrcを読み込み直しさせます。

$ source ~/.bashrc

3.2 Node.jsをインストールする

下記をコマンドラインに入力します。

$ asdf plugin add nodejs
$ asdf install nodejs latest
$ asdf global nodejs latest

ここではasdfを用いて最新のNode.jsを入れていますが、実際に競技中に用いるのは過去のバージョンになると思います。
ここまでうまく行っていると、nodeとコマンドを打つと、下記のようなNode.jsのJavaScript実行画面が表示されるはずです。

$ node
Welcome to Node.js v21.1.0.
Type ".help" for more information.
>

試しに計算をさせてみる。
頭の2*3が入力で、6が出力です。

> 2*3
6

この入力画面はCtrl+Cを二回入力することで終了させることができます。
今後JavaScriptファイルを実行させたいときは、

node XX(ファイル名).js

と入力することで、JavaScriptを実行できます。

4. online-judge-toolsをインストールする

AtCoderの問題を、いちいちWEBページ上から貼り付けなどせずに、コマンドラインから提出できるようにするツールです。

$ sudo apt install python3 python3-pip
$ pip3 install --upgrade pip
$ pip3 install online-judge-tools
# online-judge-toolsのインストールをチェック
$ oj --version

バージョンが出力されればOKです!

5. atcoder-cliをインストールする

AtCoderの問題に対して、テストケースを取得して自動でテスト実行してくれるツールです。

$ npm install -g npm
$ npm install -g atcoder-cli
# accのインストールをチェック
$ acc -v

6. 各種設定を行う

まずはAtCoderに登録しておいてくださいね~。
https://atcoder.jp/

ぽんぽんいきます。

提出用にAtCoderにログインする
ID、パスワードを聞かれますので、作成したAtCoderのアカウント情報を入力してください。

$ oj login https://atcoder.jp

設問データ取得用にAtCoderにログインする

$ acc login

設定の変更

$ vim ~/.config/atcoder-cli-nodejs/config.json

下記のようなファイルが開くはず

{
	"oj-path": "/usr/local/bin/oj",
	"default-contest-dirname-format": "{ContestID}",
	"default-task-dirname-format": "{tasklabel}",
	"default-test-dirname-format": "tests",
	"default-task-choice": "inquire",
	"default-template": ""
}

該当箇所を下記のように書き換える。(aでinsertモードにするのを忘れずに!終わったらESC→:wqで保存して終了です)

"default-test-dirname-format": "js",
"default-task-choice": "all",
"default-template": "js"

テンプレートファイルを作成

$ mkdir ~/.config/atcoder-cli-nodejs/js
$ vim ~/.config/atcoder-cli-nodejs/js/main.js

新規でファイルが開くので、下記を貼り付け。

main.js
function Main(input) {
    input = input.split("\n");
    console.log(input);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));

テンプレートファイルを使用するよう設定を作成。

$ vim ~/.config/atcoder-cli-nodejs/js/template.json

下記を書き込み。

{
    "task": {
     "program": ["main.js"],
     "submit": "main.js"
    }
}

あとはAtCoder用のディレクトリを作っておきましょう。

$ mkdir atcoder

以上で環境設定が完了です!!!!

取り組み方

AtCoderのサイトから参加するコンテストを選び、参加登録をしましょう。
過去のものだったらそのまま画面上部のタブから「問題」を選んで開始できます。
まずは試しにテスト問題をやってみましょう。
「AtCoder Beginners Selection(ABS)」を選んで参加登録。
https://atcoder.jp/contests/abs/tasks/practice_1

問題の中の一番上、PracticeAを選んでください。

そうすると問題文が表示されます。
そうしたらWSLのターミナルを開いて、任意のフォルダに移動してください。
ここまで指示通りにやっていればatcoderというディレクトリを作っているので、下記のとおりに。

# cdというコマンドはチェンジディレクトリノ意味で、開いているディレクトリを移動する際に使います
$ cd ~/atcoder

そしたらテスト用のデータをダウンロードしてくる。

# accというツールを使って、新しくabsの問題をダウンロードする。
$ acc new abs

違うコンテストをしたい場合は、absの部分を書き換える。例えば

$ acc new abc356

とか。
この名前の部分は、AtCoderのサイトのURL末尾を見るとわかりやすい。
absのコンテストトップページ:https://atcoder.jp/contests/abs

そうすると、今いるフォルダの下に問題をダウンロードしてきてくれる。
設定によってはこんな画面が出てくるので、ダウンロードしたい問題を選ぼう。

? select tasks (Press <space> to select, <a> to toggle all, <i> to invert selection)
 ◯ ABC049C Daydream
 ◯ ABC086C Traveling
❯◉ PracticeA Welcome to AtCoder
 ◯ ABC086A Product
 ◯ ABC081A Placing Marbles
 ◯ ABC081B Shift only
 ◯ ABC087B Coins
(Move up and down to reveal more choices)

今の設定なら全問まとめてダウンロードしてるはず。
ディレクトリの中身を見たいときはコマンドlsを打つ。

# lsは今いるディレクトリの中身を教えてくれます。あるいはls ./absのように後ろにディレクトリ名をつけると、そのディレクトリの中を教えてくれます。
$ ls     
abs

すると上記の様に、absってフォルダだけですよと教えてくれます。
なのでabsを開いてみましょう。

# cdは移動
$ cd abs
# lsは中身の確認
$ ls
abc049c  abc081b  abc085b  abc086a  abc087b  contest.acc.json
abc081a  abc083b  abc085c  abc086c  abc088b  practicea

中に問題の数分ディレクイトリが作成されています。
今回は練習用のものをやるので、practiceaを開きましょう。

$ cd practicea
$ ls
js  main.js

中身は「js」というディレクトリと、「main.js」というソースコードが入っています。
「js」ディレクトリはテスト用のデータを格納するところで、もう一つ「main.js」がテンプレートに登録したソースコードをコピーしてくれたものです。
ここからはmain.jsを編集して、デバッグ、テスト、送信する、という作業です。

$ code main.js

これでVSCode上でテンプレートと同じ中身のファイルが表示されるはずなので、ここを編集していきましょう。

さて、ブラウザに戻って問題文を読んで見ましょう。

a,b,c,sというデータが与えられて、a,b,cを足し合わせた結果とsを出力するらしいですね。

ソースコードの一例

main.js
function Main(input) {
	input = input.split("\n");
	tmp = input[1].split(" ");
	var a = parseInt(input[0], 10);
	var b = parseInt(tmp[0], 10);
	var c = parseInt(tmp[1], 10);
	var s = input[2];
	//出力
	console.log('%d %s',a+b+c,s);
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));

プログラムの細かい解説はここではしません。
上記を保存してターミナルへ戻り、手元で一度テスト実行してみましょう。

$ node main.js

上記を打つと、入力待ち状態で停止します。
なので、問題に沿った入力を与えましょう。

ブラウザに戻り、入力例をコピーしてターミナルに貼り付けるのが良いです。
貼り付けたらCtrl+Dで入力が終わったよと伝えると結果が表示されるはずです。

$ node main.js
1
2 3
test
6 node
$

2~4行目が入力したデータ、5行目が結果の出力です。
この出力結果が正解だとOK、違う結果になってしまっていたらソースコードを直すことになります。
うまくプログラムができたと思ったら、テストデータを使って最終チェックをしましょう。

$ oj-t-js
[INFO] online-judge-tools 11.5.1 (+ online-judge-api-client 10.10.1)
[INFO] 2 cases found
[WARNING] GNU time is not available: time

[INFO] sample-1
[INFO] time: 0.101661 sec
[SUCCESS] AC

[INFO] sample-2
[INFO] time: 0.089247 sec
[SUCCESS] AC

[INFO] slowest: 0.101661 sec  (for sample-1)
[SUCCESS] test success: 2 cases

oj-t-jsは、設定で作ったエイリアスで、とにかくこれを入力すれば、今いるディレクトリのソースコードをテストしてくれます。
online-judge-toolsが今回はサンプルを2つ使ってテストしてくれました。
うまくいくとAC、不正解だとWAが表示されます。あとは実行時間制限を越してしまっている場合などはTLEと表示されたり。常にACを目指していくことになります。

テストがうまく行ったので提出をしましょう。

$ acc-s-js

するとちゃんとログインしていて、提出できる状態なら一番最後に下記のような文言が出てくるはずです。

[WARNING] the problem "https://atcoder.jp/contests/abs/tasks/practice_1" is specified to submit, but no samples were downloaded in this directory. this may be mis-operation
Are you sure? Please type "pra1" 

これは、本当に提出していいですか?という確認のようなもので、「Please type "pra1" 」とあるように、良いなら"pra1"と入力してくれということなので、その通りに入力しましょう。
すると送信をしてくれて、少し待つと勝手にブラウザを開いて提出完了ページに飛ぶはずです。
飛べない場合は、下記のような文言が出ているはずなので、そのURLをCtrlを押しながらクリックしましょう。

[SUCCESS] result: https://atcoder.jp/contests/abs/submissions/1111111

提出結果ページはこんな感じ。提出したソースコードが一番上に表示される。

下にスクロールすると、提出結果がわかります。場合によってはACではなく「WJ」と表示されていると思いますがその場合は、今採点中なので待ってくれという状態なのでそのまま待つか、次の問題をはじめましょう。

あとはどんどん問題を解いていくだけ!次の問題のディレクトリに移動しましょう。

# 「../」というのは、ひとつ上のディレクトリ、を指す。なので「cd ../」は一個上のディレクトリを開くことを指す。
$ cd ../
$ ls
abc049c  abc081b  abc085b  abc086a  abc087b  contest.acc.json
abc081a  abc083b  abc085c  abc086c  abc088b  practicea

# 次はabc086aをやろうかなあ
$ cd abc086a

# なお最初から次のディレクトリがわかっていればこういう書き方も可能
$ cd ../abc086a

# cd ../ まで打ってTabを押せば、ディレクトリの候補がでるので、それでも一覧を見れる

以上でAtCoderの取り組み方解説は以上です!!

おわりに

元々身内用に作ったもので、口頭説明を挟む気満々なのでLinuxコマンドの説明や、個々の用語の解説ができていないので、本当の初心者にはちょっとむずかしいかもしれません…
本当はmacの分もあるんですけど力尽きました…
ドキュメンテーションって大変!

Node.jsなどに触ったことがない身としては結構苦労したので、誰かの役にたっていれば嬉しいです。

明日はぬーさんの「過去に行ったどこかの記録でも書きます」とのことです!

その他参考サイト

競プロ環境構築#1 共通編
https://oucrc.net/articles/e6vkrz4uqtt/
Windows上のVS CodeでRemote-WSLを使い。WSL2のUbuntu 20.04へアクセスする。| Zenn
https://zenn.dev/s_ryuuki/articles/4b9631674adea4
Getting Started for oj command (日本語)
https://github.com/online-judge-tools/oj/blob/master/docs/getting-started.ja.md

Discussion