- Notifications
You must be signed in to change notification settings - Fork44
A Cargo subcommand for competitive programming
License
Apache-2.0, MIT licenses found
Licenses found
qryxip/cargo-compete
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
A Cargo subcommand for competitive programming.
Supports AtCoder, Codeforces, and yukicoder.Other websites are available viaonline-judge-tools/api-client.
- Log in a website,
- (Automatically) register in a contest,
- Retrieves sample/system test cases, and save them as YAML files,
- Test your code for the YAML files,
- Submit your code,
- Watch your submissions. (available for only AtCoder)
| Registeration | Sample Test Cases | System Test Cases | Submiting | Watching Submissions | Submission Details | |
|---|---|---|---|---|---|---|
| AtCoder | ✔️ | ✔️ | ✔️ | ✔️ | ❔ | ❌ |
| Codeforces | ❌ | ✔️ | N/A | ✔️ | ❌ | ❌ |
| yukicoder | N/A | ✔️ | ✔️ | ✔️ | ❌ | ❌ |
| Other websites | ❌ | Depends on online-judge-tools | Depends on online-judge-tools | Depends on online-judge-tools | ❌ | ❌ |
$cargo install cargo-competeIf the build fails, adding--locked may help.
$cargo install --git https://github.com/qryxip/cargo-competeWeprovide the binaries in GitHub Releases.
Generates some files for other commands.
Run this command first.It generates the following files.
Required for other commands.
Sets
build/target-dirto share thetargetdirectory.template-cargo-lock.tomlA template of
Cargo.lockforcargo compete new.Generated only if you answer2 YestoDo you use crates on AtCoder?question.If this file is generated, file path to it is added tonew.template.lockfileincompete.toml.
Seethe section in the Japanese readme.
Logges in a website.
This is not a command for a package.
You don't have to run this command beforehand, because cargo-compete asks credentials if necessary.
Registeres in a contest.
This is not a command for a package.
You don't have to run this command beforehand, because cargo-compete registers in the contest if necessary.
Retrieves test cases and creates a package for the contest.
Requirescompete.toml.Generate it withcargo compete init first.
You can opens the pages in your browser with the--open option.And you can also open the source files and the test cases in your browser by testingopen incompete.toml.If you forget to add--open,cd to the generated package and runcargo compete open.
Generatesbin targets and retrieves the test cases for them.
Requirescompete.toml.Generate it withcargo compete init first.
To use this function, configureadd in thecompete.toml like this.
# for yukicoder[add]url ='{% case args[0] %}{% when "contest" %}https://yukicoder.me/contests/{{ args[1] }}{% when "problem" %}https://yukicoder.me/problems/no/{{ args[1] }}{% endcase %}'is-contest = ["bash","-c",'[[ $(cut -d / -f 4) == "contests" ]]']# optional#target-kind = "bin" # ["bin", "example"]. default to "bin"bin-name ='{% assign segments = url | split: "/" %}{{ segments[5] }}'#bin-alias = '{% assign segments = url | split: "/" %}{{ segments[5] }}' # optional#bin-src-path = './src/bin/{{ bin_alias }}.rs' # optional
❯cargo compete a contest 296 Added `1358` (bin) for https://yukicoder.me/problems/no/1358 Added `1359` (bin) for https://yukicoder.me/problems/no/1359 Added `1360` (bin) for https://yukicoder.me/problems/no/1360 Added `1361` (bin) for https://yukicoder.me/problems/no/1361 Added `1362` (bin) for https://yukicoder.me/problems/no/1362 Added `1363` (bin) for https://yukicoder.me/problems/no/1363 Added `1364` (bin) for https://yukicoder.me/problems/no/1364 Added `1365` (bin) for https://yukicoder.me/problems/no/1365 Saved 1 test case to /home/ryo/src/competitive/yukicoder/testcases/1358.yml Saved 3 test cases to /home/ryo/src/competitive/yukicoder/testcases/1359.yml Saved 3 test cases to /home/ryo/src/competitive/yukicoder/testcases/1360.yml Saved 3 test cases to /home/ryo/src/competitive/yukicoder/testcases/1361.yml Saved 3 test cases to /home/ryo/src/competitive/yukicoder/testcases/1362.yml Saved 1 test case to /home/ryo/src/competitive/yukicoder/testcases/1363.yml Saved 3 test cases to /home/ryo/src/competitive/yukicoder/testcases/1364.yml Saved 3 test cases to /home/ryo/src/competitive/yukicoder/testcases/1365.yml❯cargo compete a problem 9001 Added `9001` (bin) for https://yukicoder.me/problems/no/9001 Saved 1 test case to /home/ryo/src/competitive/yukicoder/testcases/9001.yml
Retrieves test cases for an existing package.
This is a command for a package.cd to the package generated withcargo compete new.
With--open option, you can download system test cases instead of sample ones.
For AtCoder, we have to useDropbox API.Generate an access token with these two permissions in some way,
files.metadata.readsharing.read
and save a JSON file in the following format to{local data directory}/cargo-compete/tokens/dropbox.json.(I'm thinking of better way)
{"access_token":"<access token>"}Retrieves your submissions, and outputs as JSON.
This is a command for a package.cd to the package generated withcargo compete new.
For example, you can get "the URL for the latest submission" by adding| jq -r '.summaries[0].detail.
$# for Linux$xdg-open"$(cargo compete r ss| jq -r'.summaries[0].detail')"
Opens pages in your browser, and opens source and test cases in your editor.
This is a command for a package.cd to the package generated withcargo compete new.
Runs tests.
This is a command for a package.cd to the package generated withcargo compete new.
You don't have to run this command beforehand, because the tests are run inthesubmit command.
Submits your code.
This is a command for a package.cd to the package generated withcargo compete new.
You can convert code with a tool such ascargo-equip andcargo-executable-payload by settingsubmit in thecompete.toml.
[submit]kind ="command"args = ["cargo","+1.70.0","equip","--exclude-atcoder-202301-crates","--remove","docs","--minify","libs","--bin","{{ bin_name }}"]language_id ="5054"
[submit]kind ="command"args = ["cargo","executable-payload","--bin","{{ bin_name }}"]language_id ="5054"
Here is an example forcompete.toml.
# Path to the test file (Liquid template)## Variables:## - `manifest_dir`: Package directory# - `contest`: Contest ID (e.g. "abc100")# - `bin_name`: Name of a `bin` target (e.g. "abc100-a")# - `bin_alias`: "Alias" for a `bin` target defined in `pacakge.metadata.cargo-compete` (e.g. "a")# - `problem`: Alias for `bin_alias` (deprecated)## Additional filters:## - `kebabcase`: Convert to kebab case (by using the `heck` crate)test-suite ="{{ manifest_dir }}/testcases/{{ bin_alias }}.yml"# Open files with the command (`jq` command that outputs `string[] | string[][]`)## VSCode:#open = '[["code", "-a", .manifest_dir], ["code"] + (.paths | map([.src, .test_suite]) | flatten)]'# Emacs:#open = '["emacsclient", "-n"] + (.paths | map([.src, .test_suite]) | flatten)'[template]src ='''fn main() { todo!();}'''[template.new]# `edition` for `Cargo.toml`.edition ="2018"# `profile` for `Cargo.toml`.## By setting this, you can run tests with `opt-level=3` while enabling `debug-assertions` and `overflow-checks`.#profile = '''#[dev]#opt-level = 3#'''dependencies ='''num = "=0.2.1"num-bigint = "=0.2.6"num-complex = "=0.2.4"num-integer = "=0.1.42"num-iter = "=0.1.40"num-rational = "=0.2.4"num-traits = "=0.2.11"num-derive = "=0.3.0"ndarray = "=0.13.0"nalgebra = "=0.20.0"alga = "=0.9.3"libm = "=0.2.1"rand = { version = "=0.7.3", features = ["small_rng"] }getrandom = "=0.1.14"rand_chacha = "=0.2.2"rand_core = "=0.5.1"rand_hc = "=0.2.0"rand_pcg = "=0.2.1"rand_distr = "=0.2.2"petgraph = "=0.5.0"indexmap = "=1.3.2"regex = "=1.3.6"lazy_static = "=1.4.0"ordered-float = "=1.0.2"ascii = "=1.0.0"permutohedron = "=0.2.4"superslice = "=1.0.0"itertools = "=0.9.0"itertools-num = "=0.1.3"maplit = "=1.0.2"either = "=1.5.3"im-rc = "=14.3.0"fixedbitset = "=0.2.0"bitset-fixed = "=0.1.0"proconio = { version = "=0.3.6", features = ["derive"] }text_io = "=0.1.8"whiteread = "=0.5.0"rustc-hash = "=1.1.0"smallvec = "=1.2.0"'''dev-dependencies ='''#atcoder-202004-lock = { git = "https://github.com/qryxip/atcoder-202004-lock" }'''[template.new.copy-files]"./template-cargo-lock.toml" ="Cargo.lock"[new]kind ="cargo-compete"# Platform## - atcoder# - codeforces# - yukicoderplatform ="atcoder"# Path (Liquid template)## Variables:## - `contest`: Contest ID. **May be nil**# - `package_name`: Package namepath ="./{{ contest }}"#[new]#kind = "oj-api"#url = "https://atcoder.jp/contests/{{ id }}"#path = "./{{ contest }}"# for Library-Checker#[add]#url = "https://judge.yosupo.jp/problem/{{ args[0] }}"##is-contest = ["false"] # optional##target-kind = "bin" # ["bin", "example"]. default to "bin"#bin-name = '{{ args[0] }}'##bin-alias = '{{ args[0] }}' # optional##bin-src-path = './src/bin/{{ bin_alias }}.rs' # optional# for yukicoder#[add]#url = '{% case args[0] %}{% when "contest" %}https://yukicoder.me/contests/{{ args[1] }}{% when "problem" %}https://yukicoder.me/problems/no/{{ args[1] }}{% endcase %}'#is-contest = ["bash", "-c", '[[ $(cut -d / -f 4) == "contests" ]]'] # optional##target-kind = "bin" # ["bin", "example"]. default to "bin"#bin-name = '{% assign segments = url | split: "/" %}{{ segments[5] }}'##bin-alias = '{% assign segments = url | split: "/" %}{{ segments[5] }}' # optional##bin-src-path = './src/bin/{{ bin_alias }}.rs' # optional[test]# Toolchain for the test. (optional)toolchain ="1.42.0"# Profile for `cargo build`. ("dev" | "release")## Defaults to `"dev"`.#profile = "dev"[submit]kind ="file"path ="{{ src_path }}"language_id ="5054"#[submit]#kind = "command"#args = ["cargo", "+1.70.0", "equip", "--exclude-atcoder-202301-crates", "--remove", "docs", "--minify", "libs", "--bin", "{{ bin_name }}"]#language_id = "5054"
And here is an example forpackage.metadata inCargo.toml.
[package]name ="practice"version ="0.1.0"authors = ["Ryo Yamashita <qryxip@gmail.com>"]edition ="2018"[package.metadata.cargo-compete.bin]practice-a = {alias ="a",problem ="https://atcoder.jp/contests/practice/tasks/practice_1" }practice-b = {alias ="b",problem ="https://atcoder.jp/contests/practice/tasks/practice_2" }#[package.metadata.cargo-compete.example][[bin]]name ="practice-a"path ="src/bin/a.rs"[[bin]]name ="practice-b"path ="src/bin/b.rs"[dependencies]num ="=0.2.1"num-bigint ="=0.2.6"num-complex ="=0.2.4"num-integer ="=0.1.42"num-iter ="=0.1.40"num-rational ="=0.2.4"num-traits ="=0.2.11"num-derive ="=0.3.0"ndarray ="=0.13.0"nalgebra ="=0.20.0"alga ="=0.9.3"libm ="=0.2.1"rand = {version ="=0.7.3",features = ["small_rng"] }getrandom ="=0.1.14"rand_chacha ="=0.2.2"rand_core ="=0.5.1"rand_hc ="=0.2.0"rand_pcg ="=0.2.1"rand_distr ="=0.2.2"petgraph ="=0.5.0"indexmap ="=1.3.2"regex ="=1.3.6"lazy_static ="=1.4.0"ordered-float ="=1.0.2"ascii ="=1.0.0"permutohedron ="=0.2.4"superslice ="=1.0.0"itertools ="=0.9.0"itertools-num ="=0.1.3"maplit ="=1.0.2"either ="=1.5.3"im-rc ="=14.3.0"fixedbitset ="=0.2.0"bitset-fixed ="=0.1.0"proconio = {version ="=0.3.6",features = ["derive"] }text_io ="=0.1.8"whiteread ="=0.5.0"rustc-hash ="=1.1.0"smallvec ="=1.2.0"[dev-dependencies]
Test cases are saved as YAML files.
# https://atcoder.jp/contests/practice/tasks/practice_1---type:Batchtimelimit:2smatch:Linescases: -name:sample1in:| 1 2 3 testout:| 6 test -name:sample2in:| 72 128 256 myonmyonout:| 456 myonmyonextend: -type:Textpath:"./a"in:/in/*.txtout:/out/*.txt
# https://atcoder.jp/contests/ddcc2019-final/tasks/ddcc2019_final_a---type:Batchtimelimit:2smatch:Float:relative_error:1e-8absolute_error:1e-8cases: -name:sample1in:| 5 -->--out:| 3.83333333333333 -name:sample2in:| 7 -------out:| 6.5 -name:sample3in:| 10 -->>>-->--out:| 6.78333333333333extend: -type:Textpath:"./a"in:/in/*.txtout:/out/*.txt
# https://judge.yosupo.jp/problem/sqrt_mod---type:Batchtimelimit:10smatch:Checker:cmd:~/.cache/online-judge-tools/library-checker-problems/math/sqrt_mod/checker "$INPUT" "$ACTUAL_OUTPUT" "$EXPECTED_OUTPUT"shell:Bashcases:[]extend: -type:SystemTestCases
The format isTestSuite in the following schemas.
A test suite for a normal problem.
| Field | Type | Default | Description |
|---|---|---|---|
timelimit | Duration |null | ~ | Time limit |
match | Match | Judging method | |
cases | Case[] | [] | Sets of input and output |
extend | Extend[] | [] | Additional sets of input and output |
A string that can parsed withhumantime::format_duration.
Anuntagged ADT.
Compares whole strings.
Compareswords splitted by whitespace.
Compareslines.
Compares wordssplitted by whitespace.
absolute_error andrelative_error are applied for pairs of words that can parsed as floating point numbers.
| Field | Type | Default | Description |
|---|---|---|---|
relative_error | PositiveFiniteFloat64 |null | ~ | Relative error |
absolute_error | PositiveFiniteFloat64 |null | ~ | Absolute error |
A 64-bit floating point number that is positive and is notinf.
Checks with a shell script.
The following environment variables are given for the script.
INPUTACTUAL_OUTPUTEXPECTED_OUTPUT(only if theCase.outis present)
| Field | Type | Default | Description |
|---|---|---|---|
cmd | str | Command | |
shell | Shell | Shell |
Anuntagged ADT.
Bash.
| Field | Type | Default | Description |
|---|---|---|---|
name | str | "" | Name |
in | str | Input | |
out | str |null | ~ | Output |
timelimit | Duration |null | ~ | Overridestimelimit |
match | Match |null | ~ | Overridesmatch |
| Field | Type | Default | Description |
|---|---|---|---|
path | str | Directory | |
in | Glob | Text files for input | |
out | Glob | Text files for output | |
timelimit | Duration |null | ~ | Overridestimelimit |
match | Match |null | ~ | Overridesmatch |
A glob.
System test cases.
System test cases are stored under{ cache directory }/cargo-compete/system-test-cases.They are automatically downloaded if missing whentesting code.
| Field | Type | Default | Description |
|---|---|---|---|
problem | Url |null | ~ | URL of the problem |
A URL.
A test suite for an interactive problem.
| Field | Type | Default | Description |
|---|---|---|---|
timelimit | Duration |null | ~ | Time limit |
A dummy test suite for dummy problems such as ones inAPG4b.
| Field | Type | Default | Description |
|---|
The cookies and tokens are saved under{ local data directory }/cargo-compete.
.├── cookies.jsonl└── tokens ├── codeforces.json ├── dropbox.json └── yukicoder.json
cargo-compete reads these environment variables if they exist, and use them.
$DROPBOX_ACCESS_TOKEN$YUKICODER_API_KEY$CODEFORCES_API_KEY$CODEFORCES_API_SECRET
For unsupported websites,oj-api(.exe) in the$PATH is used whendownloading andsubmitting.
[package]name ="library-checker"version ="0.0.0"edition ="2018"publish =false[package.metadata.cargo-compete.bin]aplusb = {problem ="https://judge.yosupo.jp/problem/aplusb" }
Seethe section in the Japanese readme.
Dual-licensed underMIT orApache-2.0.
About
A Cargo subcommand for competitive programming
Topics
Resources
License
Apache-2.0, MIT licenses found
Licenses found
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Contributors10
Uh oh!
There was an error while loading.Please reload this page.


