Skip to content
analyze problem statements of competitive programming and automatically generate input / output parts
Python C++
Branch: master
Clone or download

Latest commit

Fetching latest commit…
Cannot retrieve the latest commit at this time.

Files

Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github/workflows
docs
onlinejudge_prepare
onlinejudge_random
onlinejudge_template
onlinejudge_template_resources
tests
LICENSE
README.md
setup.cfg
setup.py

README.md

Online Judge Template Generator

test Documentation Status PyPI LICENSE

(CAUTION: the current version is unstable. see Compatibility / 注意: 現在はまだ開発中のバージョンです。互換性については読んでおいてください)

What is this

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

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

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

How to install

$ pip3 install online-judge-template-generator

Usage

oj-template コマンドは、指定された問題に対し、入出力パートを自動生成します。 入出力解析は (精度は別として) たいていのオンラインジャッジで動きます。

$ oj-template [-t TEMPLATE] URL

oj-prepare コマンドは、指定された問題やコンテストに対し、テンプレート生成やサンプルのダウンロードを一括で行います。 oj コマンド が動くやつなら何に対してでも動きます。

$ oj-prepare URL

Supported languages

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

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

Generating random cases

ランダムケースの生成は、oj-prepare コマンドがデフォルトで生成する generate.py を修正した後に、次のように実行してください。

$ oj generate-input "python3 generate.py"

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

また、ランダムケース生成を補助するための module onlinejudge_random が用意されています。詳細はドキュメントを確認してください。

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 vam, const vector<int64_t> & kfi, const vector<int64_t> & vkw) {
    // TODO: edit here
}

// generated by online-judge-template-generator (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 vam;
    cin >> vam;
    vector<int64_t> kfi(vam), vkw(vam);
    REP (i, vam) {
        cin >> kfi[i] >> vkw[i];
    }
    bool ans = solve(vam, kfi, vkw);
    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 のためのテンプレートは ~/.config/online-judge-tools/template/ の下に ~/.config/online-judge-tools/template/customized.py のように作って oj-template -t customized.py https://... のように指定する。 テンプレート記法は Mako のものを使う。 fastio.cpp とか customize_sample.cpp とかを見てそれっぽく書けば動く。

oj-prepare の設定は ~/.config/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 (左側) で指定したパスに配置する。
    • default: { "main.cpp" = "main.cpp", "main.py" = "main.py", "generate.py" = "generate.py" }

License

MIT License

You can’t perform that action at this time.