template-generator
template-generator copied to clipboard
Analyze problems of competitive programming and automatically generate boilerplate
online-judge-tools/template-generator
What is this
This tool analyzes problems and generates template codes for competitive programming.
Online Demo: https://online-judge-tools.github.io/template-generator-webapp/
How to install
$ pip3 install online-judge-template-generator
Usage
oj-template command analyzes the specified problem and generates the template files (e.g. main.cpp) including input/output part (e.g. int n; std::cin >> n;) and the generators (e.g. generate.py) of random test cases for the problem. See Examples.
This works on many online judges which oj command works.
$ oj-template [-t TEMPLATE] URL
oj-prepare command prepares some template files and test cases for a problem or a contest at once. This is a thin wrapper of oj command and oj-template command.
This works on many online judges which oj command works.
$ oj-prepare URL
Supported languages
The following template files are prepared as builtin of oj-template command.
main.cpp: solution in C++main.py: solution in Pythongenerate.py: random case generator in Pythongenerate.cpp: random case generator in C++
The builtin templates invoke clang-format command and yapf command when they exist.
Please install them too if you want to generate better formatted code.
Generating random cases
To generate random cases, please run oj-prepare https://... command, edit the generated generate.py file, and run the following command:
$ oj generate-input "python3 generate.py"
You can also generate the file generate.py with the running the command oj-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
The template file for oj-template command can be specified with the -t option.
You can see the list of builtin template files at onlinejudge_template_resources/template/.
For example, if you want to use generate.cpp, please run as oj-template -t generate.cpp https://....
You can make a new template by yourself. The format of template files is Mako's one. Please write by reference to existing files like fastio_sample.cpp or customize_sample.cpp> API documentation exists at onlinejudge_template.generator package.
To specify your new template file with -t option, please include the path separator character / in the given path (this is similar to the behavior of executing a command out of PATH in shell).
For example, if you write a template file named customized.py, please run oj-template -t ./customized.py https://... or oj-template -t /path/to/customized.py https://....
Also you can use certain directory (when you use Linux, it's ~/.config/online-judge-tools/template/) to place template files like ~/.config/online-judge-tools/template/customized.py. If templates exist in this directory, you can specify them as oj-template -t customized.py https://.... If templates files whose names are the same to builtin templates, they are override the builtin files.
oj-prepare
There is the config file for oj-prepare at ~/.config/online-judge-tools/prepare.config.toml (in Linux).
Please write as the following.
contest_directory = "~/Desktop/{service_domain}/{contest_id}/{problem_id}"
problem_directory = "."
[templates]
"main.py" = "main.py"
"naive.py" = "main.py"
"generate.py" = "generate.py"
Available items:
problem_directory(string): When a URL of a problem is given to the command, use{problem_directory}for the directory.- default:
. - available vairables:
{problem_id}: problem ID (e.g.abc123_d)
- default:
contest_directory(string): When a URL of a contest is given to the command, use{contest_directory}/{problem_directory}for the directory.- default:
{problem_id} - available vairables:
{problem_id}: problem ID (e.g.abc123_d){contest_id}: contest ID (e.g.abc123){service_domain}: the domain of the online judge (e.g.codeforces.com){service_name}: the name of the online judge (e.g.Codeforces)
- default:
templates(table of string): places the generated code specified by value (the right of=) into paths specified by key (the left of=).- 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:
License
MIT License