競プロerのための環境構築(mac, c++)

# 0. はじめに
この記事では，macで競技プログラミング（通称: 競プロ）を快適に(?)楽しむための環境構築について書いていきます。とくに自分がつまずいたところと，それの解消方法を書いていきます。
### 設定すること
- ローカルでコンパイルできるようにする
- 自動でテストするようにする
- Terminalからsubmitできるようにする

### Requirements
- c++で競技プログラミングをしようと思っている
- モチベがある

### 自分の（この記事で目指す）環境について
OS: **macOS**
エディタ: CLion（学生は無料!）
コンパイル/テスト: **Terminal** / **online-judge-tools**(後述)
提出: **online-judge-tools**

---
この記事では，以下のプログラムをベースに話を進めていきます。

```c++:main.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  cin >> n;
  cout << 1+n << '\n';
}
```

# 1. ローカルでコンパイルできるようにする
#### まずはgccのインストール
C++のプログラムをコンピューターが実行できるようにするためには，プログラムをコンパイルすることが必要です。そこで，XCodeをダウンロードしました。これでターミナルから`g++ main.cpp`とコンパイルできるはず！！（出来ません）
コンパイルが出来なかった理由は，`#include <bits/stdc++.h>`を使おうとしていたからです。ローカルで設定する必要があります。
そのために，

- stdc++.hを作る
- CPLUS_INCLUDE_PATHの編集

をします。

#### stdc++.hの作成
`AtCoder`のディレクトリの中に，`include`ディレクトリを作成し，その中に`bits`ディレクトリを作成し，stdc++.hファイルを以下の内容で保存しました。

```c++:stdc++.h
#include <iostream>
#include <string>
#include <vector>
#include <algorithm> 
#include <utility>
#include <tuple>
#include <cstdint>
#include <cstdio> // printf
#include <map> // map
#include <queue> // queue, priority_queue
#include <set> // set
#include <stack> // stack
#include <deque> // deque
#include <unordered_map> // unordered_map
#include <unordered_set> // unordered_set
#include <bitset> // bitset
#include <iomanip> // setprecision
#include <numeric> 
#include <cctype> // isupper, islower, isdigit, toupper, tolower
```
`~/Desktop/AtCoder/include/bits/stdc++.h`という状況。
（AtCoder以外のコンテストに出たいときにデスクトップがコンテスト名だらけにならないために, `Desktop/Competitive-programming/AtCoder`とかの構成の方が拡張性に優れていると思います)

#### CPLUS_INCLUDE_PATHの編集
Terminalを開いて，ホームディレクトリで`vim ~/.zshrc`と入力し，`.zshrc`を編集します。

```zsh:.zshrc
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/Users/名前/Desktop/AtCoder/apg4b/include/
```
`.zshrc`に上記を追記します。
これで，ローカルでコンパイルできるようになりました！嬉しいですね。
[APG4b 付録1.コードテストの使い方](https://atcoder.jp/contests/apg4b/tasks/APG4b_ak#local_setting)

```shell:コンパイル(Terminal)
g++ main.cpp
```

```shell:実行(Terminal)
$ ./a.out
7
8
```
となるはず。

#### 
# 2. 自動でテストするようにする
[online-judge-tools] (https://online-judge-tools.readthedocs.io/en/master/introduction.ja.html)を使います。
そのためには，brewをインストールする必要があります。
[brewの公式ページ](https://brew.sh/index_ja.html)にある以下のコマンドをターミナルにコピペ。

```bash:Terminal
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```
その後，Pythonとonline-judge-toolsをインストールします。

```bash:Pythonをインストール(Terminal)
brew install python
```
```bash:online-judge-tools(Terminal)
pip3 install online-judge-tools --user
```

これで, `main.cpp`があるディレクトリに行き，テストケースをダウンロードし，`main.cpp`をコンパイル後，ターミナルで`oj t ./a.out`とすればテストできます。
また，

```shell
alias test='g++ main.cpp && oj t'
```
こうすれば，コンパイル→テストまでを自動で実行できます。嬉しいので，`alias test='g++ main.cpp && oj t'`を`.zshrc`に早速追記します。

###### 【読者への宿題?】
コンテスト名と　問題名（a,b,c,d,...)　もしくは 解く問題の数を入力したら自動でコンテストのディレクトリやファイルの作成，テストケースのダウンロードをそれぞれしてくれるスクリプトを作成しても単調な作業をすることを防げます。

# 3. Terminalからsubmitできるようにする

```shell
oj submit main.cpp
```
2.で[online-judge-tools] (https://online-judge-tools.readthedocs.io/en/master/introduction.ja.html)をダウンロードしたので，これで提出できます。一刻をも争う大会なので，数文字で提出できるのは嬉しいですね！（同ディレクトリ内で異なるURLからテストケースをダウンロードした場合，URLをその都度，指定する必要があります)

# 4.　設定ファイルの中身
実際のファイルの中身を紹介します。本記事で紹介していないことも使っています。

##### `.zshrc`
<details><summary>**.zshrc**</summary><div>

```zsh:.zshrc
# colors
autoload -U colors
colors
PROMPT='%K{235}%F{255}%2~ %B%k%F{red} %#%f %b%f%'

# PATHS
export LSCOLORS='exfxcxdxbxegedabagacad'
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/Users/HOGEHOGE/Desktop/AtCoder/apg4b/include/

PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Users/HOGEHOGE/Desktop/AtCoder/online-judge-tools:/Users/HOGEHOGE/Library/Python/3.8/bin:$PATH"
export PATH

# suggestions
autoload -U compinit
compinit
setopt correct
zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}

# suggestions
source ~/developer/zsh-autosuggestions/zsh-autosuggestions.zsh
ZSH_AUTOSUGGEST_STRATEGY=(history completion)
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'

# alias
alias compile='g++ -std=c++17 -O2 ${1:-main.cpp}'
alias odl='oj dl'
alias gotoContest='cd Desktop/AtCoder/Contest/ && ls'
alias ls='ls -F -G -1'
alias tree='tree -N -A -C'
alias rell='/Library/Frameworks/Python.framework/Versions/3.8/bin/python3 /Users/HOGEHOGE/Desktop/AtCoder/Library/contest_oj.py'

# functions

function test() {
  g++ -std=gnu++17 -O2 -Wall -Wextra main.cpp && oj t -i && rm ./a.out
}

function submit() {
  oj submit $1 ${2:-main.cpp} -y -w 0.00
}
```

</div></details>

##### `stdc++.h`
<details><summary>**stdc++.h**</summary><div>

```c++:stdc++.h
#include <iostream>
#include <string>
#include <vector>
#include <algorithm> 
#include <utility>
#include <tuple>
#include <cstdint>
#include <cstdio> // printf
#include <map> // map
#include <queue> // queue, priority_queue
#include <set> // set
#include <stack> // stack
#include <deque> // deque
#include <unordered_map> // unordered_map
#include <unordered_set> // unordered_set
#include <bitset> // bitset
#include <iomanip> // setprecision
#include <numeric> 
#include <cctype> // isupper, islower, isdigit, toupper, tolower

/* DEBUG */
#pragma once
using namespace std;

string to_string(const string& s) {
  return '"' + s + '"';
}

template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}

#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
```
</div></details>


##### デバッグ用のコードについて
`stdc++.h`にデバッグ用のコードを置くことで，ファイルごとにデバッグ用のコードを記述する必要がなくなります。上記のstdc++.hをプリコンパイル[^4]して使っています。ちなみに`stdc++.h`内のデバッグ用のコードはtourist由来です（問題があったら削除します）。

[^4]: コンパイルにかかる時間を短縮するために使いました。

# 5. 参考資料
[**1) C++入門 AtCoder Programming Guide for beginners (APG4b)**](https://atcoder.jp/contests/APG4b)

[**1.1) APG4b 付録1.コードテストの使い方**](https://atcoder.jp/contests/apg4b/tasks/APG4b_ak#local_setting)


[**2) VisualStudioで競技プログラミングの環境を作る(MacとC++) - Qiita**](https://qiita.com/kaikusakari/items/6b2c0b9ad95ba50ad45b)

[**3) online-judge-tools**] (https://online-judge-tools.readthedocs.io/en/master/introduction.ja.html)


[**4) 江添亮のC++入門**](https://ezoeryou.github.io/cpp-intro/)
プリコンパイルについて知りたい時に使いました。