競プロ初心者こそ環境構築しよう(codeforces編)[cftoolsの使い方]

# イントロ
　[以前書いていたatcoder向けの環境構築の記事](https://qiita.com/Adaachill/items/3d4ddad56c5c2cc372cd)が僕の記事の中では人気でありがたいことに今でもポツポツLGTMなどをもらっています。

　twitterなどを見ていてもatcoderの参加者は急激に伸びており、客観的にも[記事によると](https://edtech-media.com/archives/35798)日本人登録者が10万人を超え、コンテストへの参加人数を見ても最近のABCという初心者向けのコンテストでは1万人近くが参加するなど、競技プログラミングに参加する人数の増加が伺えます。

　以前の記事では、atcoderを使う時に便利なものとして、atcoder-cli とonline-judge-toolsを使って自動でコンテストサイトからサンプルをダウンロードしてローカルでテストする方法、コマンドライン上で提出する方法を紹介をしたのですが、今回は海外のコンテストサイト[CodeForces](https://codeforces.com/)で同様のことを行えるツールとしてcf-toolsを紹介しようと思います。

## インストール
[Codeforces Tool](https://github.com/xalanq/cf-tool)
このツールは上記で言及したコンテストのサンプルを自動で取得し、コードを提出するということが行えるほか、他人のコードをダウンロードしたり、masterとなる基本のコードが書かれたファイルを自動で作ってくれたりします。

go で書かれているソースコードから直接ダウンロードする方法もgithubのReadMeには書かれていますが、今回はpre-compile　されたbinary file からダウンロードすることにします。

僕の例を載せておきます'Macでの例)
- macOS 10.15.1 で検証
- VScodeで書いているのでvscodeのterminalから導入


[Release page](https://github.com/xalanq/cf-tool/releases)から、Mac,Linux,WindowsそれぞれにOSの32,64bit用のバイナリファイルがzip形式で圧縮されて提供されているので、自分のマシンにあったものをダウンロードしてください。

　僕のケースでは64bitのMacなので[cf_v1.0.0_darwin_64.zip](https://github.com/xalanq/cf-tool/releases/download/v1.0.0/cf_v1.0.0_darwin_64.zip)をダウンロードします。(因みにDarwinというのはappleが開発するOSでMacやiPadの基礎になるOSだということです。(https://ja.wikipedia.org/wiki/Darwin_(%E3%82%AA%E3%83%9A%E3%83%AC%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0))

```
wget https://github.com/xalanq/cf-tool/releases/download/v1.0.0/cf_v1.0.0_darwin_64.zip
unzip cf_v1.0.0_darwin_64.zip
# 適当な場所に展開したあと、pathを通してください
cf_v1.0.0_darwin_64/cf -h # でhelpが表示されればインストールできています
```

## 設定
まずは使いやすくするために`cf config`でtemplateの設定やログインの設定をしましょう。

```
cf config
open ${dir}/.cf/config: no such file or directory
Create a new configuration in ${dir}/.cf/config
open ${dir}/.cf/session: no such file or directory
Create a new session in ${dir}/.cf/session
Configure the tool
0) login
1) add a template
2) delete a template
3) set default template
4) run "cf gen" after "cf parse"
5) set host domain
6) set proxy
7) set folders' name
Please choose one (index): #まずはターミナルからloginできるようにメールアドレスやパスワードを登録しましょう 
0
Configure handle/email and password
Note: The password is invisible, just type it correctly.
handle/email: ${your email}
password: ${password}
Login your email
Succeed!!
Welcome ${コドフォのユーザーネームが表示されるはずです}
#続いてtemplateの設定をしましょう
$cf config
Configure the tool
0) login
1) add a template
2) delete a template
3) set default template
4) run "cf gen" after "cf parse"
5) set host domain
6) set proxy
7) set folders' name
Please choose one (index): 
1 # templateを追加する際は1を選択します（複数追加することも可能です）
Add a template
Language list:
~~~#自分の使う言語を選びます(僕はpypyを使うのでPypyを選びます。）
Select a language (e.g. "42"): 
41
PyPy 3.6 (7.2.0)
Template:
  You can insert some placeholders into your template code. When generate a code from the
  template, cf will replace all placeholders by following rules:

  $%U%$   Handle (e.g. xalanq)
  $%Y%$   Year   (e.g. 2019)
  $%M%$   Month  (e.g. 04)
  $%D%$   Day    (e.g. 09)
  $%h%$   Hour   (e.g. 08)
  $%m%$   Minute (e.g. 05)
  $%s%$   Second (e.g. 00)
#署名を付けたい人は付けてもいいかもしれませんが、僕は飛ばしました。
Template absolute path(e.g. "~/template/io.cpp"): 
# teplateを置く場所を絶対パスで指定します
~/workspace/competitive_programing/codeforces/a.py               
The suffix of template above will be added by default.
Other suffix? (e.g. "cxx cc"), empty is ok: 
 
Template's alias (e.g. "cpp" "py"): 
py
Script in template:
Template will run 3 scripts in sequence when you run "cf test":
    - before_script   (execute once)
    - script          (execute the number of samples times)
    - after_script    (execute once)
  You could set "before_script" or "after_script" to empty string, meaning not executing.
  You have to run your program in "script" with standard input/output (no need to redirect).

  You can insert some placeholders in your scripts. When execute a script,
  cf will replace all placeholders by following rules:

  $%path%$   Path to source file (Excluding $%full%$, e.g. "/home/xalanq/")
  $%full%$   Full name of source file (e.g. "a.cpp")
  $%file%$   Name of source file (Excluding suffix, e.g. "a")
  $%rand%$   Random string with 8 character (including "a-z" "0-9")
Before script (e.g. "g++ $%full%$ -o $%file%$.exe -std=c++11"), empty is ok: 
# コンパイラ言語ではscriptを実行する前にコンパイルする必要があるのでコンパイルのコマンドを記述します（今回はpythonでscript言語のため何も書きません)
Script (e.g. "./$%file%$.exe" "python3 $%full%$"): 
# scriptを実行するためのコマンドを記述します。(c++ ./a.out, python python a.pyなど）
python3 $%full%$
After script (e.g. "rm $%file%$.exe" or "cmd.exe /C del $%file%$.exe" in windows), empty is ok: 
#もしコマンド終了時に処理を行いたい場合は記述します。（ファイル消去、git addなど）
Make it default (y/n)? 
y
```

## 実際にコンテストのテストケースを取得する
コンテストのテストケースを取得するコマンドは`cf race`　と`cf parse`の２つがあります
`cf race`では`cf parse`の機能に加え自動で問題文のページを開いたりする機能があります。コンテスト中に使う時は`cf race`を使うと良いと思います。
また、コマンドを打つ際、contest 番号を指定しますが、その時は、URLに書いてある番号を入力する必要があるようです。（コンテストの種別ごとの番号ではないです。div1 635なら1336がコンテスト番号になります。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253261/caa5f7ad-5adc-201d-954f-a4792f42fb34.png)


```
cf parse 100 # 試しにcnntest 100を取得してみる
#cf/contest/100/　にディレクトリが作られ、その下に自動で全ての問題のディレクトリが作られ、test caseがダウンロードされる
# codeforcescf parse 100を実行した時のでディレクトリ構成
codeforces/cf/contest/100
|--a
| |--ans1.txt
| |--ans2.txt
| |--in1.txt
| |--in2.txt
|--b
| |--ans1.txt
| |--ans2.txt
| |--in1.txt
| |--in2.txt
~~~以下省略~~~

#cf raceでもcf parse同様に自動で ./cf/contest/contest_num に問題ごとのフォルダを作りtestcaseをダウンロードします
$ cf race 1335
Race CONTEST 1335
Open https://codeforces.com/contest/1335
Open https://codeforces.com/contest/1335/problems
Parse CONTEST 1335
The problem(s) will be saved to ~/workspace/competitive_programing/codeforces/cf/contest/1335
Parsing F
Parsing C
Parsing E2
Parsing A
Parsing E1
Parsing B
Parsing D
Parsed A with 1 samples. Non standard input output format.
Parsed F with 1 samples. Non standard input output format.
Parsed E1 with 1 samples. Non standard input output format.
Parsed B with 1 samples. Non standard input output format.
Parsed D with 1 samples. Non standard input output format.
Parsed C with 1 samples. Non standard input output format.
Parsed E2 with 1 samples. Non standard input output format.
```

## コードをテストする
コードのテストは`cf test`から行います(複数のtemplateを用意した場合はどのtemplateを使うかを設定できます）

```
$ cf test
There are multiple languages match the file.
  0: PyPy 3.6 (7.2.0)
  1: PyPy 3.6 (7.2.0)
Please choose one (index): 
1
Passed #1 ... 0.026s 5.902MB
```

## コードの提出
コードの提出はその問題のディレクトリからコマンドを叩けば自動的にその問題のページに提出してくれます。

```
$ cf submit
There are multiple languages match the file.
  0: PyPy 3.6 (7.2.0)
  1: PyPy 3.6 (7.2.0)
Please choose one (index): 
1
Submit CONTEST 1335, problem a
Current user: knk_kei
Submitted
      #: 77217852
   when: 2020-04-19 04:21
   prob: A - Candies and Two Sisters
   lang: PyPy 3
 status: Accepted                   
   time: 155 ms
 memory: 2.64 MB
```

## 主なコマンドのまとめ
`cf cofig`: ログインの設定やtemplateの設定
`cf submit`: コードの提出
`cf list`:
`cf parse`:問題のtest caseのinputと答えをとってくる
`cf test`:現在のパスのテストケースを実行する
`cf race ${contest_num}` :自動的にコンテストの全ての問題ページを開き、test aseを取得する。まだ、始まっていなければカウントダウンする(僕が開始前のコンテストで試したところ、カウントダウン機能はなく、最初の問題のみscrapingしようとしてとまりました）
`cf stand`:順位表ページをブラウザで開く

# まとめ
今回はcodeforcesに参加する時にコマンドラインで操作を完結させてくれるツールcodeforces toolついて紹介しました。
僕自身、導入しながらの紹介のため、使っていく中での工夫やトラブルシューティングはあるとは思います。ぜひコメントしていただけると幸いです。

他にユーザースクリプトやwebサービスなどについても要望があれば追記しようと思います。