競技プログラミングの問題を解析してテンプレートコードを出力してくれるツールです。 kyuridenamida/atcoder-tools を参考に、その本質部分だけを抜き出して再実装しました。 内部構造については How it works に書かれています。
主目的は以下のふたつです:
- 不適切な入出力方法を用いたことによる TLE を回避すること。たとえば「Codeforces で
std::endl
を使って TLE する」みたいなのをなくしたい - ランダムケースを生成してのテストを気軽に行えるようにすること。たとえば、サンプル AC して提出してみたら謎の WA が出たとき「これランダムケース生成して愚直解と比較すれば原因分かるだろうけど、面倒なんだよな」ってなりがちですが、この面倒を半減させ高速にデバッグできるようにしたい
オンライン上の試用版: https://online-judge-tools.github.io/template-generator-webapp/
有志による紹介記事 (日本語):
$ pip3 install online-judge-template-generator
oj-template
コマンドは、指定された問題を解析し、その問題のための入出力パート (int n; std::cin >> n;
など) を含むテンプレートファイル (main.cpp
など) やランダムケース生成器 (generate.py
など) を自動生成します。詳細は Examples を見てください。
oj
コマンド が認識できる問題であれば何に対してでも動作します。
$ oj-template [-t TEMPLATE] URL
oj-prepare
コマンドは、指定された問題やコンテストに対し、テンプレート生成やサンプルのダウンロードを一括で行います。
これは oj
コマンドと oj-template
コマンドの薄いラッパーです。
oj
コマンド が認識できる問題であれば何に対してでも動作します。
$ oj-prepare URL
oj-template
が認識する組み込みのテンプレートとして以下が使えます。
main.cpp
: C++ 解法コードmain.py
: Python 解法コードgenerate.py
: Python ランダムケース生成器generate.cpp
: C++ ランダムケース生成器
ランダムケースの生成は、oj-prepare https://...
コマンドを実行し、生成された generate.py
を修正した後に、次のように実行してください。
$ oj generate-input "python3 generate.py"
ファイル generate.py
は oj-template -t generate.py "https://..."
というコマンドの実行によっても生成できます。
$ oj-template https://codeforces.com/contest/1300/problem/D
...
#include <bits/stdc++.h>
#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 REP_R(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)
using namespace std;
const string YES = "YES";
const string NO = "nO";
bool solve(int n, const vector<int64_t> & a, const vector<int64_t> & b) {
// TODO: edit here
}
// generated by online-judge-template-generator v4.4.0 (https://github.com/kmyk/online-judge-template-generator)
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
constexpr char endl = '\n';
int n;
cin >> n;
vector<int64_t> a(n), b(n);
REP (i, n) {
cin >> a[i] >> b[i];
}
auto ans = solve(n, a, b);
cout << (ans ? YES : NO) << endl;
return 0;
}
$ oj-template -t generate.py https://judge.yosupo.jp/problem/staticrmq
...
#!/usr/bin/env python3
import random
import onlinejudge_random as random_oj
def main():
N = random.randint(1, 10 ** 9) # TODO: edit here
a = [None for _ in range(N)]
Q = random.randint(1, 10 ** 9) # TODO: edit here
l = [None for _ in range(Q)]
r = [None for _ in range(Q)]
for i in range(N):
a[i] = random.randint(1, 10 ** 9) # TODO: edit here
for i in range(Q):
l[i] = random.randint(1, 10 ** 9) # TODO: edit here
r[i] = random.randint(1, 10 ** 9) # TODO: edit here
print(N, Q)
print(*[a[i] for i in range(N)])
for i in range(Q):
print(l[i], r[i])
if __name__ == "__main__":
main()
$ oj-prepare https://atcoder.jp/contests/abc158
...
$ tree
.
├── abc158_a
│ ├── main.cpp
│ ├── main.py
│ ├── generate.py
│ └── test
│ ├── sample-1.in
│ ├── sample-1.in
│ ├── sample-1.out
│ ├── sample-2.in
│ ├── sample-2.out
│ ├── sample-3.in
│ └── sample-3.out
├── ...
├── ...
├── ...
├── ...
└── abc158_f
├── main.cpp
├── main.py
├── generate.py
└── test
├── sample-1.in
├── sample-1.out
├── sample-2.in
├── sample-2.out
├── sample-3.in
├── sample-3.out
├── sample-4.in
└── sample-4.out
13 directories, 50 files
oj-template
のためのテンプレートは -t
オプションによって指摘できます。
組み込みで用意されているテンプレートの一覧は onlinejudge_template_resources/template/ で見られます。
たとえば generate.cpp を利用したい場合は oj-template -t generate.cpp https://...
としてください。
テンプレートを自分で作成することもできます。 テンプレート記法は Mako のものを使います。 fastio_sample.cpp とか customize_sample.cpp とかを見ていい感じに書いてください。 API ドキュメントは onlinejudge_template.generator package にあります。
自分で書いたテンプレートを -t
オプションで指定するときは、文字列中にパス区切り文字 /
が含まれるようにしてパスを指定してください (シェルスクリプトでの実行ファイルの指定と同様です)。
たとえば customized.py
というテンプレートを書いたときは、oj-template -t ./customized.py https://...
や oj-template -t /path/to/customized.py https://...
のように指定してください。
また、特定のディレクトリ (Linux の場合は ~/.config/online-judge-tools/template/
) の下に ~/.config/online-judge-tools/template/customized.py
のようにファイルを配置しておくことで、oj-template -t customized.py https://...
のように指定できるようにもなります。組み込みのテンプレートと同じ名前のテンプレートがこのディレクトリにあれば上書きされます。
oj-prepare
の設定は (Linux の場合は) ~/.config/online-judge-tools/prepare.config.toml
で行えます。MacOS の場合は /Users/{user_name}/Library/Application Support/online-judge-tools/prepare.config.toml
で行えます。以下のように書いてください。
contest_directory = "~/Desktop/{service_domain}/{contest_id}/{problem_id}"
problem_directory = "."
[templates]
"main.py" = "main.py"
"naive.py" = "main.py"
"generate.py" = "generate.py"
設定項目:
problem_directory
(string): 問題の URL が指定された場合は{problem_directory}
にファイルが用意される。- default:
.
- 使える変数:
{problem_id}
: 問題 ID (abc123_d
など)
- default:
contest_directory
(string): コンテストの URL が指定された場合は{contest_directory}/{problem_directory}
にファイルが用意される。(default:- default:
{problem_id}
- 使える変数:
{problem_id}
: 問題 ID (abc123_d
など){contest_id}
: コンテスト ID (abc123
など){service_domain}
: サービスのドメイン (atcoder.jp
など){service_name}
: サービスの名前 (AtCoder
など)
- default:
templates
(table of string): value (右側) のテンプレートによる生成結果を key (左側) で指定したパスに配置する。- example:
{ "solution.cpp" = "main.cpp", "naive.py" = main.py", "generate.cpp" = "generate.cpp" }
- default:
{ "main.cpp" = "main.cpp", "main.py" = "main.py", "generate.py" = "generate.py" }
- example:
MIT License