はじめに
AtCoderのABCコンテストで、コンテストごとに毎回新しいフォルダ作って、マクロを積んだテンプレファイルを作成するっていう作業がめんどくさいって方のための記事です。
コンテスト名が付けられたフォルダ&c++テンプレを自動生成する方法をこの記事で紹介します。
手順
シェルスクリプトとMakefileを用いて、コンテスト名が付けられたフォルダとc++テンプレを自動で生成します。
-
Makefileとシェルスクリプト(create_abcFolder_atcoder.sh)を作成して(ファイルの中身は後の方で記載)、以下のように作業フォルダ(例:join_abc_beginner_contest)に配置
. └── join_abc_beginner_contest ├── Makefile └── create_abcFolder_atcoder.sh
-
シェルスクリプトに実行権限を付与。以下のコマンドをターミナルで実行
chmod +x create_abcFolder_atcoder.sh
-
コンテスト名が付けられたフォルダとc++テンプレを自動生成。以下のコマンドを実行
make
-
以下のように、次の番号のABCフォルダが作成され、その中にテンプレートファイルが自動で生成
# 実行前のディレクトリ構造 . └── join_abc_beginner_contest ├── Makefile └── create_abcFolder_atcoder.sh
# 実行後のディレクトリ構造 . ├── join_abc_beginner_contest ├── ABC001 │ ├── a.cpp │ ├── b.cpp │ ├── c.cpp │ └── d.cpp ├── Makefile └── create_abcFolder_atcoder.sh
フォルダが無い場合は、"ABC001"というフォルダが新規に生成され、その中にA問題~D問題(D問題以降はどうせ解けないし...)用のc++ファイルを自動生成してくれます。フォルダが既に1つ以上ある場合は、フォルダの番号("001"にあたる部分)が最大のものを見つけて、その最大番号+1したフォルダ(今回の場合、"ABC002")が生成されます。
必要なファイル
Makefile
以下の内容のMakefileを作成します。このMakefileは、シェルスクリプトを実行する役割を持ちます。(ファサード的な?)
all:
./create_abcFolder_atcoder.sh
シェルスクリプト(create_abcFolder_atcoder.sh)
以下の内容のシェルスクリプトを作成します。このスクリプトは、次の番号のABCフォルダを自動で生成し、その中にc++テンプレートファイルを生成します。注目してほしいのは、テンプレート内容で、現時点では私がいつも使ってるテンプレになっておりますので、ご自身のものがあれば、それに差し替えてください。
#!/bin/bash
# ABCで始まるフォルダをリストアップ
folders=$(ls -d ABC[0-9][0-9][0-9] 2>/dev/null)
# フォルダがない場合、最初のフォルダを作成
if [ -z "$folders" ]; then
next_num=1
else
# 最大の番号を見つける
max_num=$(echo "$folders" | sed 's/ABC//' | sort -n | tail -n 1)
# 次の連番を計算
next_num=$((10#$max_num + 1))
fi
# 次の連番を3桁の形式にする
next_folder=$(printf "ABC%03d" "$next_num")
# 新しいフォルダを作成
mkdir "$next_folder"
# 新しいフォルダ作成成功のメッセージ
echo "Created folder: $next_folder"
# テンプレート内容
template='#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define rep3(i, m, n) for (int i = (m); i < (int)(n); ++i)
#define repR(i, n) for (int i = (int)(n) - 1; i >= 0; --i)
#define rep3R(i, m, n) for (int i = (int)(n) - 1; i >= (int)(m); --i)
#define all(x) std::begin(x), std::end(x)
#define mPrint(msg) cout << msg << endl;
#define dprint(msg) cout << "-----\n" \
<< msg << "\n-----\n";
#define arrPrint(arr) \
{ \
bool first = true; \
for (const auto &elem : arr) \
{ \
if (!first) \
cout << " "; \
cout << elem; \
first = false; \
} \
cout << endl; \
}
int main()
{
return 0;
}'
# 作成したフォルダ内に移動
cd "$next_folder" || exit
# ファイル名リスト
files="a b c d"
# 引数のファイル名リストを処理
for filename in $files; do
# ファイルを作成し、テンプレート内容を書き込む
echo "$template" > "$filename.cpp"
# ファイル作成成功のメッセージ
echo "$filename.cpp has been created."
done
まとめ
この記事では、AtCoderのABCコンテスト用に、コンテスト名が付けられたフォルダ&c++テンプレを自動生成する方法をこの記事で紹介しました。この方法を使えば、コンテストごとに新しいフォルダとファイルを手動で作成する手間が省けます。ぜひお試しください!