Cheatsheet#
CLI#
Below you can find a list of common rbx commands. You can read more about each of them in the CLI reference.
Where a command has a page of its own, the next to it takes you there.
| Task | Command |
|---|---|
| Show help message | rbx --help |
| Show the installed version | rbx --version |
| Open rbx configuration for editing | rbx config edit |
Create a new package in folder package |
rbx create |
| Compile a file given its path | rbx compile my/file.cpp |
| Compile every asset of the package | rbx compile -a |
| Compile a file with extra compiler flags | rbx compile my/file.cpp -- -DLOCAL -g |
| Open the problem configuration in a text editor | rbx edit |
| Generate all testcases | rbx build |
| Generate all testcases and their visualizations | rbx build --visualize |
| Print a summary of the problem | rbx summary |
| Print the summary as JSON | rbx summary --format json |
| See what is wrong with the problem | rbx issues |
| Explain each issue in full | rbx issues -d |
| Print the expanded variables of the problem | rbx vars |
| Print the expanded variables as JSON | rbx vars --json |
| Print what statement expressions read from stdin render to | rbx vars --render |
| Use dynamic timing to estimate time limits | rbx time |
| Estimate time limits skipping the language picker | rbx time -a |
| Estimate limits and write them into a profile | rbx time -p icpc -i |
| Run all solutions and check their tags | rbx run |
| Run all solutions with sanitizer | rbx run -s |
| Run all solutions with dynamic timing | rbx run -t |
| Run all solutions except the slow ones | rbx run -v2 |
| Run all solutions without checking | rbx run --no-check |
| Run a single solution | rbx run sols/my-solution.cpp |
| Run only the main solution | rbx run @main |
| Choose solutions and run | rbx run -c |
| Run only the solutions expected to be too slow | rbx run -o tle |
| Run only the solutions carrying a tag | rbx run --tag brute-force |
| Stop a solution at its first non-accepted verdict | rbx run --ff |
| Run against a timing profile | rbx run -p icpc |
| Report how long the checker spent judging | rbx run -b1 |
| Copy the run report to the clipboard | rbx run --share png |
| Run a submission downloaded from BOCA | rbx run @boca/123 |
| Run a submission downloaded from MOJ | rbx run @moj/<contest>/<id> |
| Run all solutions interactively | rbx irun |
| Choose solutions and run interactively | rbx irun -c |
| Run solutions in a single testcase | rbx irun -t samples/0 |
| Run solutions in a generator testcase | rbx irun -g gen 5 10 |
| Run interactively and print the outputs | rbx irun -p |
| Print the outputs with stderr interleaved | rbx irun -p -e |
| Interactively visualize outputs of a recent run | rbx ui |
| Run the validator interactively | rbx validate |
| Run the validator over an existing test | rbx validate -p tests/manual/000.in |
Run a stress test with name break |
rbx stress break |
| Run a stress test for a generator | rbx stress gen -g "[1..10]" -f "[sols/main.cpp ~ INCORRECT]" |
| Run unit tests for validator and checker | rbx unit |
| Download all libraries declared by the preset | rbx download lib |
| Download testlib to the current folder | rbx download testlib |
| Download jngen to the current folder | rbx download jngen |
| Download tgen to the current folder | rbx download tgen |
| Download a built-in testlib checker | rbx download checker wcmp.cpp |
| Download a BOCA submission into the package | rbx download remote @boca/123 |
| Download a MOJ submission into the package | rbx download remote @moj/<contest>/<id> |
Generate the rbx.h header in the package |
rbx header |
| Build all statements | rbx statements build |
| Build a specific variant | rbx statements build <variant> |
| Build statements for English | rbx statements build --languages en |
| Build statements against a timing profile | rbx statements build -p icpc |
| Build statements without samples | rbx statements build --no-samples |
| Build all tutorials (editorials) | rbx tutorials build |
| Package problem for Polygon | rbx package polygon |
| Package problem and upload it to Polygon | rbx package polygon -u |
| Package problem for BOCA | rbx package boca |
| Package problem for BOCA but only validate | rbx package boca -v1 |
| Package problem for MOJ | rbx package moj |
| List all languages available in the environment | rbx languages |
| Format all YAML configuration files in the package | rbx fix |
| Clear cache | rbx clear |
| Clear the global cache as well | rbx clear -g |
Contest CLI#
| Task | Command |
|---|---|
| Show help message | rbx contest --help |
| Create a new contest | rbx contest create |
| Add a new problem to the contest with letter A | rbx contest add |
| Remove a problem from the contest | rbx contest remove A |
| Remove a problem at a certain path | rbx contest remove path/to/problem |
| Open the contest configuration in a text editor | rbx contest edit |
| Build all statements | rbx contest statements build |
| Build a specific statement | rbx contest statements build <name> |
| Build statements for English | rbx contest statements build --languages en |
| Build statements against a timing profile | rbx contest statements build -p icpc |
| Build all tutorials (editorials) | rbx contest tutorials build |
| Package contest for Polygon | rbx contest package polygon |
| Package contest for BOCA | rbx contest package boca |
| Build each problem in the contest | rbx contest each build |
| Build each problem, not stopping at failures | rbx contest each -k build |
| Package each problem in the contest | rbx contest each package boca |
| Build problem A in the contest | rbx contest on A build |
| Build a problem by name, alias or folder | rbx contest on knapsack build |
| Build problems A to C in the contest | rbx contest on A..C build |
| Build every problem but C | rbx contest on '*,!C' build |
| Chain commands for a problem | rbx contest on A build :: run |
| Reopen a past run and read its output | rbx contest each |
| Reopen past runs touching problem A | rbx contest on A |
| Print a summary of the contest | rbx contest summary |
| See what is wrong with each problem | rbx contest issues |
| List all contests in the current directory | rbx contest list |
| Scaffold a new contest variant | rbx contest add_variant div2 |
| Run a command against a contest variant | rbx -C div2 contest statements build |
Testcase CLI#
| Task | Command |
|---|---|
| Open a testcase in your editor | rbx testcases view samples/0 |
| Open only the input of a testcase | rbx testcases view samples/0 -i |
| Show how a testcase was generated | rbx testcases info samples/0 |
| Show information about a whole group | rbx testcases info main |
| Pick generated tests and freeze them | rbx testcases promote |
| Freeze a specific generated test | rbx testcases promote main/3 |
Tip
rbx testcases is also spelled rbx tc.
Configuration CLI#
| Task | Command |
|---|---|
| Show the path to the setter configuration | rbx config path |
| Print the setter configuration | rbx config list |
| List details about the active preset | rbx presets ls |
| Pull the latest version of the installed preset | rbx presets update |
| Re-sync the package with the preset assets | rbx presets sync |
| Create a new preset | rbx presets create |
| Install the editor extension | rbx vscode install |
problem.rbx.yml#
Change problem constraints#
timeLimit: 1000 # In milliseconds
memoryLimit: 256 # In megabytes
modifiers:
java:
time: 5000 # Override time for Java
Add testlib assets#
Set a built-in testlib checker#
Set a custom checker#
See here how to write a custom testlib checker.
Add a generator#
Add a new generator entry to the generators field.
See here how to write a testlib-based generator.
Tip
To actually generate tests with this new generator, you have to add testcase groups and call the generator.
Set a validator#
See here how to write a testlib-based validator.
Set an interactor#
See here how to write a testlib-based interactor.
Add a new solution#
Implement your solution (for instance, a wrong solution in sols/my-wa-solution.cpp) and add it to the solutions field.
You can see the list of possible expected outcomes here.
Tag a solution#
Tags are free-form labels you can later filter runs by, with rbx run --tag <tag>.
Add testcases#
Add a testcase group with manually defined tests#
testcases:
# ...other testcase groups
- name: "manual-tests"
testcaseGlob: "tests/manual/*.in" # (1)!
-
Import all tests in the
tests/manual/folder in lexicographic order.The test input files must end in
.in.
Add a testcase group with a list of generated tests#
testcases:
# ...other testcase groups
- name: "single-generated"
generators:
- name: "gen"
args: "1000 123" # (1)!
- name: "gen"
args: "1000 456" # (2)!
- A generated test obtained from the output of the command
gen 1000 123. - A generated test obtained from the output of the command
gen 1000 456.
Add a testcase group with a list of generated tests from a generator script#
Add a testcase group with a list of generated tests from a dynamic generator script#
Add testgroup-specific validator#
validator:
path: "my-validator.cpp"
testcases:
- name: "small-group"
# Define tests...
validator:
path: "my-small-validator.cpp" # (1)!
- name: "large-group"
# Define tests...
- Add a specific validator to verify constraints of a smaller sub-task of the problem.
Vary constraints per testgroup#
Prefer this over a testgroup-specific validator (and over branching on the group name inside the validator) whenever the subtasks differ only in their constraints.
vars:
N:
min: 1
max: 1000
testcases:
- name: "small"
# Define tests...
vars:
N:
max: 50 # (1)!
- name: "large"
# Define tests... # (2)!
-
Overrides
N.maxfor this group only. The merge is leaf-by-leaf, soN.minstays at the package-level1. The validator is untouched:getVar<int>("N.max")returns50here and1000elsewhere. -
No override, so the package-level values apply.
Add variables#
The variables below can be reused across validators and statements.
vars:
N:
min: 1
max: 1000
V:
max: 100000
MOD: py`10**9+7` # Backticks force the var to be evaluated as a Python expression.
Use variables#
Add statements#
Problem statements are keyed by (language, variant) and have no name. See writing statements.
Add a rbxTeX statement#
statements:
# ...other statements
- language: en
file: "statements/statement.rbx.tex" # (1)!
params: { show_limits: true } # (2)!
assets: ['statements/*.png'] # (3)!
-
Path to the rbxTeX source, relative to the package root.
typedefaults torbx-tex, so it's omitted. -
Free-form values passed to the template as
params.*. -
Extra globs shipped alongside the statement on export (e.g. to Polygon); files next to
fileare staged automatically.
Reuse another statement with extends#
statements:
- language: en
file: "statements/statement.rbx.tex"
params: { show_limits: true }
- language: pt
extends: en # (1)!
params: { show_limits: false } # (2)!
-
Reuses
en'sfile,type,assets, andparams. -
paramsdeep-merges, soptoverrides onlyshow_limits.
Add a PDF statement#
Add a stress test#
Add a stress to look for an error in a solution#
stresses:
- name: "my-stress"
generator:
name: 'gen'
args: '[1..<N.max>] @' # (1)!
finder: "[sols/my-wa-solution.cpp] ~ INCORRECT" # (2)!
-
The
<N.max>variable expands into thevars.N.maxvalue that could be declared inproblem.rbx.yml.The
[1..<N.max>]picks a random number in this interval before generating every test in the stress run.The
@appends a few extra random characters to the end of the generator call to re-seed the generator. -
Expression that refers to solution
sols/my-wa-solution.cppand check whether it returns an incorrect outcome.
Add a stress to look for a test that causes TLE in a solution#
stresses:
- name: "my-stress"
generator:
name: 'gen'
args: '1000000 @' # (1)!
finder: "[sols/my-potentially-slow-sol.cpp] ~ TLE"
- The
@at the end of theargsstring appends a random string to it. This is necessary here becausegen 100000would return the same testcase over and over, since testlib rng is seeded from its command line argc and argv.
Add unit tests#
unitTests:
validator:
- glob: "unit/validator/valid_*.in" # (1)!
outcome: VALID
- glob: "unit/validator/invalid_*.in"
outcome: INVALID
checker:
- glob: "unit/checker/ac*" # (2)!
outcome: ACCEPTED
- glob: "unit/checker/wa*"
outcome: WRONG_ANSWER
# ...other checker unit tests
-
Matches
.infiles relative to the problem root directory that when validated should be considered valid. -
Matches
.in,.out,.ansfiles that when checked should be considered ACCEPTED.
contest.rbx.yml#
A contest is a roster of problems plus the chrome that wraps them. The problems keep living in
their own folders, each with its own problem.rbx.yml; the contest file only says which ones are
in, in which order, and how the joined book is built. The Contest CLI table above
lists the commands that act on it, and the contest reference has the
full field list.
Name the contest#
-
The only required field. It has to be a valid package name, so no spaces.
-
The human-readable title, per language, keyed by lowercase ISO 639-1 code. Statements read it as
\VAR{contest.title}, already picked for the language being built.
Add a new problem#
problems:
- short_name: "A" # (1)!
path: "problem_folder" # (2)!
color: "ff0000" # (3)!
colorName: "red" # (4)!
aliases: ["apple", "prob-a"] # (5)!
-
Letter of the problem: uppercase letters, optionally followed by digits (
A,B,A1). The order of this list is the order of the contest. -
Path to the problem, relative to the contest folder. Defaults to
./{short_name}/, so a problem living inA/needs nopathat all. -
Optional. A hex color or an X11 color name, used for balloons and in statements.
-
Optional. The name to print for that color, when rbx cannot infer one from
coloritself. -
Optional. Extra names this problem answers to, as in
rbx contest on apple run. Aliases must be unique across the contest, case-insensitively.
A problem can also be selected by the name it declares in its own problem.rbx.yml, or by the
basename of its folder. See selecting problems
for the full selector syntax, including ranges and exclusions.
Add a contest statement#
Contest statements are keyed by name, and each one owns the templates used to render the
problems inside it. See contest statements.
statements:
- name: main-en # (1)!
language: en
file: "statements/contest-en.rbx.tex" # (2)!
standaloneProblemTemplate: "statements/problem-standalone.rbx.tex" # (3)!
contestProblemTemplate: "statements/problem-in-contest.rbx.tex" # (4)!
params: { show_limits: true } # (5)!
-
Required, and unique within the contest. It names the output PDF and is what you pass to
rbx contest statements build main-en. -
The joining document, the one that iterates over the problems.
-
Template used when a problem is built on its own, with
rbx statements build. -
Template used for the problem fragment that gets imported into the contest book.
-
Free-form values handed to both templates as
params.*.
Reuse another statement with extends#
statements:
- name: main-en
language: en
file: "statements/contest-en.rbx.tex"
standaloneProblemTemplate: "statements/problem-standalone.rbx.tex"
contestProblemTemplate: "statements/problem-in-contest.rbx.tex"
- name: main-pt
language: pt
extends: main-en # (1)!
file: "statements/contest-pt.rbx.tex" # (2)!
-
Contest statements extend by
name, not by language.main-ptinherits the build recipe --type,params,assetsand both templates -- and keeps its own identity. -
Everything not spelled out here is inherited.
Add a tutorial (editorial)#
tutorials is a list parallel to statements, with the same fields, built by
rbx contest tutorials build. See tutorials.
tutorials:
- name: editorial-en
language: en
file: "statements/editorial-sheet.rbx.tex" # (1)!
contestProblemTemplate: "statements/editorial-fragment.rbx.tex" # (2)!
-
The joining document for the editorial book.
-
Optional, like
standaloneProblemTemplate. Leave both out and rbx falls back to the bundled default editorial chrome.
Add an infosheet or a cover page#
Pages that are not problems -- an infosheet, an instruction sheet -- are documents. They are
built alongside the statements by rbx contest statements build, and never join on problems.
documents:
- name: infosheet-en
language: en
file: "statements/infosheet-en.jinja.tex"
type: jinja-tex # (1)!
- Required here, and never one of the joining
rbx-*types. A document still receives theproblemslist, but metadata-only: enough for a limits table, not for a full statement.
Add variables shared by every statement#
Contest variables sit one level down from the problem's own, so a template reaches them as
\VAR{contest.vars.year} while plain \VAR{vars.year} still means the problem's. See
template context.
Split the contest into variants#
To ship a Div. 1 and a Div. 2 out of the same folder, turn contest.rbx.yml into a dispatcher and
put each real contest in a sibling file.
-
A sentinel: with
use_variantson, no other field may be set in this file. You can also skip it and keep a real contest here, in which case that one is the default and the siblings are extra variants. -
Each
contest.<id>.rbx.ymlis a full contest. Select one withrbx -C div2 ...orRBX_CONTEST=div2, and scaffold one withrbx contest add_variant div2. A selected variant builds intobuild/variants/div2/; the default contest builds intobuild/.
env.rbx.yml#
The environment is installed globally, not carried inside the package, so it is shared by every problem you work on. The sections below are ordered by how often you will touch them.
| Task | Command |
|---|---|
| Show which environment is in use | rbx environment |
| Install an environment from a file | rbx environment my-env -i env.rbx.yml |
| Switch to another installed environment | rbx environment my-env |
| List the languages the environment defines | rbx languages |
Change how time limits are estimated#
Drives rbx time. Pick either ratios or a formula — declaring both is an error.
Cap how long a solution may run while being timed#
- In milliseconds; defaults to 10s. An accepted solution that hits it is an error.
Estimate a separate limit per group of languages#
timing:
groups:
- languages: ["py"]
whenEmpty: {relativeTo: "cpp", multiplier: 3.0} # (1)!
- languages: ["java", "kt"]
whenEmpty: {relativeTo: "cpp", multiplier: 2.0}
- Used only when the group has no solutions: 3x the limit of the group holding
cpp. Addincrement: 500for a constant offset, in milliseconds.
Languages in no group share a single leftover pool.
Give slow languages more wall time#
timing:
wallTimeMultiplier: 2.0 # (1)!
wallTimeIncrement: 1000
languages:
- name: "java"
timing:
wallTimeIncrement: 3000 # (2)!
- The wall limit is
wallTimeMultiplier * limit + wallTimeIncrement, in milliseconds. - JVM startup headroom. The multiplier is inherited.
Raise the sandbox limits#
Bounds the programs that carry no limits of their own — compilers, checkers, validators, generators. Raise them on a slow machine.
defaultCompilation:
sandbox:
maxProcesses: 1000 # (1)!
timeLimit: 50000 # 50 seconds
wallTimeLimit: 50000
memoryLimit: 1024 # 1gb
defaultExecution:
sandbox:
timeLimit: 50000
wallTimeLimit: 50000
memoryLimit: 1024
- Some compilers fork a lot.
Change how a language is compiled#
languages:
- name: "cpp"
readableName: "C++20"
extension: "cpp"
compilation:
commands: ["g++ -std=c++20 -O2 -o {executable} {compilable}"] # (1)!
execution:
command: "./{executable}"
{compilable}and{executable}are the file names inside the sandbox. Rename them per language withfileMapping.
Add a new language#
languages:
- name: "java"
readableName: "Java"
extension: "java"
compilation:
commands:
- "javac -Xlint -encoding UTF-8 {compilable}"
- "jar cvf {executable} @glob:*.class" # (1)!
execution:
command: "java -Xss100m -Xmx{{ memory }}m -cp {executable} Main"
fileMapping: # (2)!
compilable: "Main.java"
executable: "Main.jar"
@glob:...expands into every file matching the pattern.- Java needs the source named after its class, so the sandbox names are pinned here.
Map a language onto a judge system#
languages:
- name: "cpp"
extensions: # (1)!
boca:
languages: ["cc", "cpp"]
template: "cc"
moj:
languages: ["cpp"]
template: "cpp"
flags: "-std=c++20 -O2 -lm -static"
polygon:
polygonLanguage: "cpp.gcc13-64-winlibs-g++20"
- Tells packaging which language on the target judge this one corresponds to.
Lint your assets at compilation time#
- Shorthand form: applies to every asset kind the linter supports.
- Full form:
applies_torestricts the linter to specific asset kinds.
Warnings are surfaced; errors abort the build. To silence a linter for a whole file: