Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A Cargo subcommand for competitive programming

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
NotificationsYou must be signed in to change notification settings

qryxip/cargo-compete

Repository files navigation

CIcodecovdependency statusCrates.ioCrates.ioJoin the chat at https://gitter.im/cargo-compete/community

日本語

A Cargo subcommand for competitive programming.

Supports AtCoder, Codeforces, and yukicoder.Other websites are available viaonline-judge-tools/api-client.

Features

  • 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)
RegisterationSample Test CasesSystem Test CasesSubmitingWatching SubmissionsSubmission Details
AtCoder✔️✔️✔️✔️
Codeforces✔️N/A✔️
yukicoderN/A✔️✔️✔️
Other websitesDepends on online-judge-toolsDepends on online-judge-toolsDepends on online-judge-tools

Installation

From Crates.io

$cargo install cargo-compete

If the build fails, adding--locked may help.

Frommaster branch

$cargo install --git https://github.com/qryxip/cargo-compete

From GitHub Releases

Weprovide the binaries in GitHub Releases.

Usages

cargo compete init

Generates some files for other commands.

Run this command first.It generates the following files.

  • compete.toml

    Required for other commands.

  • .cargo/config.toml

    Setsbuild/target-dir to share thetarget directory.

  • template-cargo-lock.toml

    A template ofCargo.lock forcargo compete new.Generated only if you answer2 Yes toDo you use crates on AtCoder? question.If this file is generated, file path to it is added tonew.template.lockfile incompete.toml.

Screenshot

cargo compete migrate cargo-atcoder

Seethe section in the Japanese readme.

cargo compete login

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.

cargo compete participate

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.

cargo compete new

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.

Record

cargo compete add

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.ymlcargo 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

cargo compete retrieve testcases /cargo compete download

Retrieves test cases for an existing package.

This is a command for a package.cd to the package generated withcargo compete new.

Screenshot

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.read
  • sharing.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>"}

asciicast

cargo compete retrieve submission-summaries

Retrieves your submissions, and outputs as JSON.

This is a command for a package.cd to the package generated withcargo compete new.

asciicast

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')"

cargo compete open

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.

cargo compete test

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.

cargo compete submit

Submits your code.

This is a command for a package.cd to the package generated withcargo compete new.

asciicast

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"

Configuration

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 suite

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.

TestSuite

Aninternally tagged ADT.

TestSuite::Batch

A test suite for a normal problem.

FieldTypeDefaultDescription
timelimitDuration |null~Time limit
matchMatchJudging method
casesCase[][]Sets of input and output
extendExtend[][]Additional sets of input and output

Duration

A string that can parsed withhumantime::format_duration.

Match

Anuntagged ADT.

Match::Exact ="Exact"

Compares whole strings.

Match::SplitWhiteSpace ="SplitWhitespace"

Compareswords splitted by whitespace.

Match::Lines ="Lines"

Compareslines.

Match::Float

Compares wordssplitted by whitespace.

absolute_error andrelative_error are applied for pairs of words that can parsed as floating point numbers.

FieldTypeDefaultDescription
relative_errorPositiveFiniteFloat64 |null~Relative error
absolute_errorPositiveFiniteFloat64 |null~Absolute error

PositiveFiniteFloat64

A 64-bit floating point number that is positive and is notinf.

Match::Checker

Checks with a shell script.

The following environment variables are given for the script.

  • INPUT
  • ACTUAL_OUTPUT
  • EXPECTED_OUTPUT (only if theCase.out is present)
FieldTypeDefaultDescription
cmdstrCommand
shellShellShell

Shell

Anuntagged ADT.

Shell::Bash ="Bash"

Bash.

Case

FieldTypeDefaultDescription
namestr""Name
instrInput
outstr |null~Output
timelimitDuration |null~Overridestimelimit
matchMatch |null~Overridesmatch

Extend

Aninternally tagged ADT.

Extend::Text

FieldTypeDefaultDescription
pathstrDirectory
inGlobText files for input
outGlobText files for output
timelimitDuration |null~Overridestimelimit
matchMatch |null~Overridesmatch

Glob

A glob.

Extend::SystemTestCases

System test cases.

System test cases are stored under{ cache directory }/cargo-compete/system-test-cases.They are automatically downloaded if missing whentesting code.

FieldTypeDefaultDescription
problemUrl |null~URL of the problem

Url

A URL.

TestSuite::Interactive

A test suite for an interactive problem.

FieldTypeDefaultDescription
timelimitDuration |null~Time limit

TestSuite::Unsubmittable

A dummy test suite for dummy problems such as ones inAPG4b.

FieldTypeDefaultDescription

Cookies and tokens

The cookies and tokens are saved under{ local data directory }/cargo-compete.

.├── cookies.jsonl└── tokens    ├── codeforces.json    ├── dropbox.json    └── yukicoder.json

Environment variables

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" }

Video

Compared with cargo-atcoder

Seethe section in the Japanese readme.

License

Dual-licensed underMIT orApache-2.0.

About

A Cargo subcommand for competitive programming

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Contributors10


[8]ページ先頭

©2009-2025 Movatter.jp