はじめに
この記事は MacOS で競技プログラミングを始めるためのガイドラインを提供しするものです。記事を最後まで読んでいただけると、
- Visual Studio Code 上で C++ (GCC) と Python のコードを書く、
- デバッグにおいてテストケース(標準入力)を入力する、
- AtCoder Library を使用する、
ということができるようになります。
Visual Studio Code を使ったことがない方や、ターミナルによるコマンド入力に慣れていない方にも分かりやすい解説を心掛けました。またそうした方々への配慮として、
- お使いの PC 環境を極力汚染しない
- 作業フォルダ限定で vscode の設定変更を行う
という方針で環境構築を行なっております。
購入直後の MacOS をスタートラインとします。参考までに私の OS は
- MacBook Air (M2)
- Sonoma 14.4
です。まず1章では競プロ環境に必要なソフトウェアをインストールします。以下の5つのソフトウェアのインストール方法を順に説明していきます;
- Visual Studio Code (IDE; where we write codes)
- Homebrew (packege maneger)
- GCC (c++ compiler)
- Fish (useful shell)
- AtCoder Library (an usuful library for competitive programming)
次に2章で作業フォルダの整備を行います。3章ではvscode上で競プロに必要なデバッグ環境を実現するために、vscodeの特殊ファイルを編集します。最後に4章では、構築された環境を使って、競プロ問題のデバッグから解答提出までの流れを実演します。
1. インストール (Installation)
1.1. Visual Studio Code
Visual Studio Code (以下 vscode) はコードを書くことに特化したテキストエディタです。誤解を恐れずに言えば vscode はコード記述に特化した word です。Word が文書の作成において予測変換、スペルチェックや誤字脱字の指摘によって文書作成のサポートを行ってくれるように、vscode では C++ や Python などのプログラミング言語の記述(コード作成)においてそれらの機能を果たしてくれます。
-
公式サイトから Mac を選んで vscode をダウンロードする。ダウンロードが完了したら vscode を開く
-
Vscode 左側にあるタブから extensions を選択し、"c++" と検索して Microsoft の提供する C/C++ 拡張機能をインストールします。
続いて "python" と検索して Microsoft の Python 拡張機能をインストールします。
-
Vscode の画面上で
command ⌘ + O
を押して、フォルダ一覧(Finder)を開く。そこで任意の名前を付けた新しいフォルダを作成しましょう(私は"cp"と名付けました)。
そのフォルダを選択すると、vscode 上でそれを開くことができます。成功すれば vscode の画面が切り替わり、左上に自身の名付けたフォルダ名が表示されます。
-
続いて vscode の画面上で
control ⌃ + @
を押して、ターミナルを起動します。画面下に入力画面が出現し、タイピングで下に入力が行えるようにしてください。
("We will write commands here..." と入力してみました。)
画面下部の入力空間をターミナルと呼びます。以降のインストールではコマンドを使用しますが、すべてここに入力していきます。
1.2. Homebrew
Homebrew はパッケージ管理を行うソフトウェアです。
ここでは以降のソフトウェアをインストールするために必要なソフトウェアと考えていただければ十分です。(Linux でいうところの apt に相当します。)
- Homebrewの公式サイト にアクセスし、そこに掲載されているコマンド
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
をコピーし(ctrl + c)、ターミナルに貼り付けて(ctrl + v)、実行します(enter)。
2. 端末のログインパスワードを要求されるので、手入力して実行します。成功すればターミナルに homebrew のインストール状況が表示されます。
3. ターミナル上で次のコマンドを実行します:
export PATH=/opt/homebrew/bin:$PATH
4.ターミナル上で brew -v
を実行します。上記コマンドが正しく実行できていれば、
Homebrew 4.2.14
というようにインストールされた homebrew のバージョン情報が表示されます。(お使いの環境によって多少の違いはあります。)
バージョン表示ができなかった方へ
`export`コマンド文において`/opt/homebrew/bin`の部分がお使いのPC環境によって異なる可能性があります。これはインストールされた`homebrew`本体の保管場所(パス)を表します。これを調べるために コマンド`which brew`を実行しましょう。 私の環境下では `/opt/homebrew/bin/brew`と表示されました。この最後の`/brew`部分を除いたものがhomebrewのパスになります。brew
についての注意
以降ではコマンドbrew install ~~
を用いてソフトウェアのインストールを行います。現在の状況は、brew
のパスを一時的にコンピュータに記憶させている(環境パスに指定している)に過ぎません。従って、コンピュータの再起動やvscodeの開き直しを行うと、brew
コマンドが使えなくなってしまいます。
brew
が必要になった場合は、もう一度
export PATH=/opt/homebrew/bin:$PATH
を実行してください。
あるいは、毎度コマンドを打つのが面倒で永続的にbrew
を使用したいという方もいると思います。
その場合は、自己責任を承知の上でこちらのサイトを参考にして .zshrc
ファイルを手動で編集してください。
~/.zshrc
はコンピュータ起動時に自動的に実行するコマンドを管理したファイルです。初期設定として ~/.zshrc
にはコンピュータの通常運転に必須の重要なパスが多く記載されています。上記コマンドはここに homebrew のパスを追加するものです。コンピュータの根幹に関わる重要なファイルですので、ファイルの改変や削除を不用意に行うと、最悪の場合コンピュータが動作しなくなる可能性があります。
1.4 GCC
GCC は C++ を実行するためのコンパイラです。コンパイラとはC++ 言語で書いたテキスト(コード)を機械語に変換してくれるソフトウェアです。人間は0と1で構成された機械語を直接読めず、コンピュータはC++(人間側の言語)を直接読むことができません。コンパイラは両者の間に立って言語の変換 (complile) や微調整を行います。
C++ に対するコンパイラは GCC のみではありません。MacOS にはデフォルトで clang というコンパイラが用意されています。
しかし競技プログラミングでは GCC が主流であるため、今回はこちらをインストールしておきます。
Why should we use GCC for competitive programming?
"bits/stdc++.h"というヘッダーファイルが GCC には存在しますが、clang にはありません。これは C++ の標準ライブラリ(STL)を全てまとめたファイルです。一度に多くの標準ライブラリから参照したいとき、これが存在しない clang では多くのインクルード文を書かなくてはいけません。一方、GCC では`#include `と書くだけで全てのライブラリを使用可能です。この利便性が、提出の速さを競う競技プログラミングで重宝されています。 また実行時間の観点から、多くのケースで clang よりも GCC の方が速いとも言われています。(筆者未検証の事実です。)GCC をインストールするために、ターミナルで次のコマンドを入力して実行しましょう。
brew install gcc
インストールできたか確認するため、もう一度上記コマンドを実行します。正しくインストールできていれば、このような警告文が現れます。
Warning: gcc 13.2.0 is already installed and up-to-date.
To reinstall 13.2.0, run:
brew reinstall gcc
13.2.0
はインストールされた GCC のバージョンを表します。インストールした時期によって異なる可能性があります。
ここで数字の上2桁 (13)を記憶し、次のコマンドを(必要であれば数字部分を修正して)実行してください。
which g++-13
g++-13 のパスが表示されます。
/opt/homebrew/bin/g++-13
このパスは4章で必要になるため、覚えておいてください。
1.3 Fish
Fish は使い勝手の良いシェルです。Word-文書、vscode-コードの関係でいえば、shellはコンピュータに影響を与える特殊なコマンドを入力する画面と言えるでしょう。MacOS においてデフォルトでは zsh (あるいは bash) が搭載されています。vscode内のターミナル内に小さくzsh(あるいはbash)と表示されていると思います。今回はこのシェルをfishに変更しましょう。Fishを導入することの利点は、コマンド入力の強力な予測変換にあります。
シェルとターミナルの違い
ターミナルはコンピュータに与えるコマンドを入力する画面、一方でシェルはターミナルからOS(コンピュータの本体)へとコマンドを伝える内部プログラムを指します。 つまりvscode下部に表示されるコマンド入力画面そのものがターミナルです。 先ほどのwordが文書を書くための画面であるという例を用いれば- word - 文書を書く場所
- IDE (vscode) - コードを書く場所
- ターミナル - コマンドを書く場所
という対応関係になります。
この節の内容はコンピュータの根幹システムの変更を伴うものです。Fish の導入は強く推奨しますが、競技プログラミングの環境構築に必ずしも必要ではありません。元の状態へと戻すコマンドが分からず不安に感じる方は、読み飛ばしていただいても構いません。
- Homebrew から fish をインストールします。
brew install fish
- Fish をコンピュータのシェル候補群に追加します。
sudo sh -c 'echo /opt/homebrew/bin/fish >> /etc/shells'`
- Vscode を一度閉じて(command ⌘ + Q)開きなおします。
- Fish をコンピュータのデフォルトシェルに変更します。
chsh -s /opt/homebrew/bin/fish
- 再度 vscode を閉じて開きなおします。
以下のようにシェルのデザインが変更され、Welcome to fish
と表示されていれば成功です。
- Fish にも homebrew のパスを追加しておきましょう。
fish_add_path /opt/homebrew/bin
1.5 AtCoder Library
AtCoder Libraryは C++ 用の競技プログラミングに特化したライブラリです。ライブラリとは頻出のコードを書き溜めてまとめたファイル群を指します。
-
GitHub 上のレポジトリにアクセスして緑色の
Code
をクリックし、"Download Zip" を選んでダウンロードします。 - Downloads フォルダで中身を確認しましょう。
atcoder
フォルダとexpander.py
という Python ファイルのみが次章で必要になります。
2. 作業フォルダの構築
Vscode に戻り、作成した cp
フォルダの中身を整備していきましょう。
フォルダの中身は vscode の左側の EXPLORER
という領域に適宜追加されていきます。
(画面左上に EXPLORER
および作成したフォルダ名 CP
が表示されていない場合は、画面左のアイコンから一番上の Explorer
を選択しましょう。)
現在 cp
フォルダは空になっているはずです。
最終的に以下の図式のような階層を構築することを、この章の目標とします。
cp
├── .vscode
│ ├── c_cpp_properties.json
│ ├── launch.json
│ └── tasks.json
├── atcoder
│ ├── all
│ ├── convolution
│ ├── convolution.hpp
│ ├── dsu
│ ├── dsu.hpp
│ ├── ...
│ ├── twosat
│ └── twosat.hpp
├── expander.py
├── main.cpp
└── main.py
2.1. main.cpp
および main.py
の生成
まずは C++, Python のコードを記述するためのファイルを生成しましょう。ターミナルに移動して(ctrl + @)
touch main.cpp
touch main.py
と入力します。main.cpp
が C++ のためのファイル、main.py
が Python のためのファイルです(cpp = "c plus plus")。
EXPLORER
にそれぞれのファイル名が反映されているか確認してください。
2.2 .vscode
フォルダの生成
- 画面左の
EXPLORER
からmain.cpp
を選択して開きます。 - 画面右上の歯車マーク (Add Debug Configuration) をクリックして、
C/C++-13: build and debug active file
を選択します。
厳密には、選択肢の下に書かれている compiler: /opt/homebrew/bin/g++-13
という表記を見て選択します。
ここではGCC 導入節の最後で確認したパスと一致するものを選んでください。
この操作で.vscode
というフォルダと、その中に2つの.json
ファイルが追加されます。現時点で以下のようなフォルダ構造になっているはずです。
cp
├── .vscode
│ ├── launch.json
│ └── tasks.json
├── main.cpp
└── main.py
2.3 c_cpp_properties.json
の追加
-
⇧+⌘+P を押してコマンドパレットを表示します。コマンドパレットとは vscode 上部に出現する入力画面のことです。
-
コマンドパレット上で
C/C++: Edit Configurations (UI)
と入力して実行します。
この操作で .vscode
の中に c_cpp_properties.json
というファイルが生成されます。なお、同時に C/C++ Configurations
という設定画面が表示されますが、こちらは必要ありませんので閉じてしまいましょう。
2.4. AtCoder Library を作業フォルダに追加する
- AtCoder Library からダウンロードしたフォルダの中から
atcoder
フォルダとexpander.py
ファイルを選択します。 - Vscode 左側の
EXPLORER
領域にそれらをドラッグして移動します。
以上で作業フォルダの構築は終了しました。
最初に提示した図式と同じ構成になっているかを必ず確認してください。階層構造が一つでも間違っていると、コード実行時にエラーの原因となります。
3. .vscode
内のファイルの編集
.vscode
フォルダに生成された3つの json
ファイル
c_cpp_properties.json
launch.json
tasks.json
を編集していきます。これらを適切に変更することで、
- テストケースの入力(標準入力)
- AtCoder Library の使用
が可能になります。
はじめに、私の環境下で生成されたファイルの中身を示します。
バージョンを表す数字などは使用環境によって多少異なっているかもしれませんが基本的に問題ありません。
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"macFrameworkPath": [
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "macos-clang-arm64"
}
],
"version": 4
}
{
"configurations": [
{
"name": "C/C++: g++-13 build and debug active file",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "lldb",
"preLaunchTask": "C/C++: g++-13 build active file"
}
],
"version": "2.0.0"
}
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++-13 build active file",
"command": "/opt/homebrew/bin/g++-13",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": "build",
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
tasks.json
内の command
変数に記述されているパス(ここでは "/opt/homebrew/bin/g++-13")が GCC のインストール時に確認したパスと一致しているかどうかを調べてください。一致していない場合、節:".vscode
の生成" において正しい設定ファイルを選択できていません。.vscode
内のファイルを全て手動で削除して、もう一度やり直してください。
続いて、以下に編集後のファイルの中身を示します。
// added
や // modified
というコメントアウトがある行を編集してください。(コメント部分や左側の+
を書き写す必要はありません。)
3.1. c_cpp_properties.json
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceFolder}/**",
+ "${workspaceFolder}/atcoder" // added
],
"defines": [],
"macFrameworkPath": [
"/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/System/Library/Frameworks"
],
+ "compilerPath": "/opt/homebrew/bin/g++-13", // modified
"cStandard": "c17",
"cppStandard": "c++17",
+ "intelliSenseMode": "macos-gcc-arm64" // modified
}
],
"version": 4
}
-
includePath
: 修正例の通りに、"${workspaceFolder}/atcoder" をそのまま追加しましょう。また、その上の行に,
を追加することを忘れないようにしてください。 -
compilerPath
: GCC をインストールした際に確認したパスへと修正してください。 -
intelliSenseMode
:clang
部分をgcc
に修正してください。
これらの変更は C++ のコードを書く際に、vscode が正確に予測変換を行うためのものです。
3.2. launch.json
{
"configurations": [
{
"name": "C/C++: g++-13 build and debug active file",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
+ "externalConsole": true, // false -> true
"MIMode": "lldb",
"preLaunchTask": "C/C++: g++-13 build active file"
}
],
"version": "2.0.0"
}
- "externalConsole":
false
からtrue
に変更します。
この変更によってデバッグ時に別窓でターミナルが生成され、テストケースの入力が可能になります。
3.3. tasks.json
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++-13 build active file",
"command": "/opt/homebrew/bin/g++-13",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}",
+ "-I", // added
+ "." // added
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": "build",
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
- "args": 上記の通りに
-I
と.
を追加します。また,
を忘れないようにしましょう。
この追加はコンパイラ(GCC)が AtCoder Library の存在を認識するために必要です。
以上で環境構築は終了です。
4. デバッグ手順解説
こちらの問題とテストケースをもとに、デバッグの方法を解説します。
5
22 75 26 45 72
4.1. C++
#include <bits/stdc++.h>
using namespace std;
int main(){
int N;
cin >> N;
vector<int> A(N);
for (int i = 0; i < N; i++) cin >> A[i];
for (int i = 0; i < N - 1; i++) cout << A[i] * A[i + 1] << " ";
}
-
main.cpp
を開いた状態で "fn 🌐 + F5" 押してデバッグを開始します。すると別窓でターミナルが生成され、標準入力の待機状態になります。
- テストケースをコピーしてターミナルに入力します。自動的に処理が行われ、出力が返ってきます。
- "Command ⌘ + Q" でターミナルを終了し、vscode の画面に戻ることが可能です。
4.2. Python
実は Python のみを競プロで使用したい場合には小難しい環境構築は必要ありませんでした。Vscode のインストールと main.py
の作成の節を参照するだけで十分です。
N = int(input())
A = list(map(int, input().split()))
B = [A[i] * A[i + 1] for i in range(N - 1)]
print(*B)
- 右上の三角形マーク
Run Python File
を選択します。するとターミナルが Python 用に切り替わり、標準入力の待機状態になります。 - ターミナルにテストケースを入力し、出力を確認します。
4.3. C++ with AtCoder Library
最後に AtCoder Library を使用したコードを AtCoder 外部のコンテストサイトで提出する手順について解説します。
こちらの問題を AtCoder Library 内の segtree を用いて解きます。
まずは解答コードを main.cpp
に書きます。
#include <bits/stdc++.h>
#include <atcoder/segtree>
using namespace std;
using namespace atcoder;
int op(int x, int y){
return x + y;
}
int e(){
return 0;
}
int main(){
int N, Q;
cin >> N >> Q;
vector<int> A(N, 0);
segtree<int, op, e> seg(A);
for (int i = 0; i < Q; i++){
int t, x, y;
cin >> t >> x >> y;
x--;
if (t == 0) seg.set(x, seg.get(x) + y);
else cout << seg.prod(x, y) << endl;
}
}
この解答は構築環境下でのデバッグは正しく作動すると思います。(もしこの段階でコンパイルエラーが発生するならば、.vscode
内ファイルの編集からやり直してください。)
しかし、これをジャッジに提出するとコンパイルエラーと言われてしまいます。これはジャッジ側のコンパイラに AtCoder Library が存在しないことが原因です。
この問題を解決するために、使用した自前のライブラリはコードの中に直接展開しなければなりません。
そこで次のコマンドを実行します。
python3 expander.py main.cpp
これによって新たに生成された combined.cpp
というファイルの中身を提出すると、無事に AC できました。
AtCoder Library から追加した expander.py
はそのライブラリから使用したコードを展開して、結果を combined.cpp
に保存するプログラムです。
combined.cpp
の中身をよく観察する、main.cpp
の #include <atcoder/segtree>
と書かれていた部分に、atcoder/segtree.hpp
というファイルの中身が丸ごと挿入されていることが分かると思います。
「コマンド入力 → combined.cpp
を開く → 中身をコピーする」という一連の操作は面倒くさいですね。
これは全て一つのコマンドで実行することができます;
python3 expander.py main.cpp && cat combined.cpp | pbcopy
さらに二回目以降の提出においては、fish を導入していれば最初の一文字 p
を打つだけで予測変換してくれます。
参考