Skip to content

Latest commit

 

History

History
234 lines (176 loc) · 10.4 KB

README.ja.md

File metadata and controls

234 lines (176 loc) · 10.4 KB

online-judge-tools/template-generator

test Documentation Status PyPI LICENSE

README in English

What is this

競技プログラミングの問題を解析してテンプレートコードを出力してくれるツールです。 kyuridenamida/atcoder-tools を参考に、その本質部分だけを抜き出して再実装しました。 内部構造については How it works に書かれています。

主目的は以下のふたつです:

  • 不適切な入出力方法を用いたことによる TLE を回避すること。たとえば「Codeforces で std::endl を使って TLE する」みたいなのをなくしたい
  • ランダムケースを生成してのテストを気軽に行えるようにすること。たとえば、サンプル AC して提出してみたら謎の WA が出たとき「これランダムケース生成して愚直解と比較すれば原因分かるだろうけど、面倒なんだよな」ってなりがちですが、この面倒を半減させ高速にデバッグできるようにしたい

Resources

オンライン上の試用版: https://online-judge-tools.github.io/template-generator-webapp/

有志による紹介記事 (日本語):

How to install

$ pip3 install online-judge-template-generator

Usage

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

Supported languages

oj-template が認識する組み込みのテンプレートとして以下が使えます。

  • main.cpp: C++ 解法コード
  • main.py: Python 解法コード
  • generate.py: Python ランダムケース生成器
  • generate.cpp: C++ ランダムケース生成器

Generating random cases

ランダムケースの生成は、oj-prepare https://... コマンドを実行し、生成された generate.py を修正した後に、次のように実行してください。

$ oj generate-input "python3 generate.py"

ファイル generate.pyoj-template -t generate.py "https://..." というコマンドの実行によっても生成できます。

Examples

$ 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

Settings

oj-template

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

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 など)
  • 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 など)
  • 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" }

License

MIT License