rbx.cp 0.5.42__tar.gz → 0.5.45__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/PKG-INFO +1 -2
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/pyproject.toml +4 -2
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/cli.py +8 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/code.py +76 -3
- rbx_cp-0.5.45/rbx/box/main.py +2 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/package.py +16 -2
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/state.py +1 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/tasks.py +20 -1
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/judge/cacher.py +0 -4
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/judge/digester.py +0 -3
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/judge/sandbox.py +7 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/judge/sandboxes/stupid_sandbox.py +10 -1
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/judge/sandboxes/timeit.py +109 -5
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/judge/storage.py +0 -4
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/main.py +0 -4
- rbx_cp-0.5.42/rbx/box/main.py +0 -6
- rbx_cp-0.5.42/rbx/testdata/box1/gen1.cpp +0 -7
- rbx_cp-0.5.42/rbx/testdata/box1/gen2.cpp +0 -9
- rbx_cp-0.5.42/rbx/testdata/box1/genScript.py +0 -2
- rbx_cp-0.5.42/rbx/testdata/box1/hard-tle.sol.cpp +0 -26
- rbx_cp-0.5.42/rbx/testdata/box1/ole.cpp +0 -17
- rbx_cp-0.5.42/rbx/testdata/box1/problem.rbx.yml +0 -39
- rbx_cp-0.5.42/rbx/testdata/box1/re.sol.cpp +0 -23
- rbx_cp-0.5.42/rbx/testdata/box1/sol.cpp +0 -22
- rbx_cp-0.5.42/rbx/testdata/box1/tests/1.in +0 -1
- rbx_cp-0.5.42/rbx/testdata/box1/tle-and-incorrect.sol.cpp +0 -33
- rbx_cp-0.5.42/rbx/testdata/box1/tle.sol.cpp +0 -35
- rbx_cp-0.5.42/rbx/testdata/box1/validator.cpp +0 -11
- rbx_cp-0.5.42/rbx/testdata/box1/wa.sol.cpp +0 -22
- rbx_cp-0.5.42/rbx/testdata/caching/executable.py +0 -1
- rbx_cp-0.5.42/rbx/testdata/compatible +0 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/checker.cpp +0 -21
- rbx_cp-0.5.42/rbx/testdata/interactive/gen.cpp +0 -11
- rbx_cp-0.5.42/rbx/testdata/interactive/interactor.cpp +0 -63
- rbx_cp-0.5.42/rbx/testdata/interactive/problem.rbx.yml +0 -40
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_ac_pe.cpp +0 -75
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_ac_re.cpp +0 -76
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_ac_too_many_iter.cpp +0 -72
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_inf_cout_with_flush.cpp +0 -79
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_inf_cout_without_flush.cpp +0 -78
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_ml.cpp +0 -78
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_tl_after_ans.cpp +0 -74
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_wa.cpp +0 -74
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/interactive-binary-search_mm_naive_cin.cpp +0 -17
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/main.cpp +0 -26
- rbx_cp-0.5.42/rbx/testdata/interactive/testplan.txt +0 -6
- rbx_cp-0.5.42/rbx/testdata/interactive/validator.cpp +0 -16
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/LICENSE +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/README.md +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/__init__.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/annotations.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/autoenum.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/__init__.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/builder.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/cd.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/checkers.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/compile.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/conftest.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/contest/__init__.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/contest/build_contest_statements.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/contest/contest_package.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/contest/contest_utils.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/contest/main.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/contest/schema.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/contest/statements.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/creation.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/deferred.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/download.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/environment.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/extensions.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/formatting.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/generators.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/generators_test.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/lazy_importing_main.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/lazy_importing_test.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/packaging/boca/extension.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/packaging/boca/packager.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/packaging/contest_main.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/packaging/main.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/packaging/moj/packager.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/packaging/packager.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/packaging/polygon/packager.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/packaging/polygon/test.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/packaging/polygon/xml_schema.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/presets/__init__.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/presets/fetch.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/presets/lock_schema.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/presets/schema.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/retries.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/sanitizers/warning_stack.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/schema.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/setter_config.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/solutions.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/solutions_test.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/statements/__init__.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/statements/build_statements.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/statements/builders.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/statements/joiners.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/statements/latex.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/statements/latex_jinja.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/statements/schema.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/stresses.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/stressing/__init__.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/stressing/finder_parser.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/stressing/generator_parser.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/testcase_extractors.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/testcase_utils.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/testcases/__init__.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/testcases/main.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/ui/__init__.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/ui/captured_log.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/ui/css/app.tcss +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/ui/main.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/ui/run.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/unit.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/validators.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/box/validators_test.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/checker.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/clone.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/config.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/conftest.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/console.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/create.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/edit.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/__init__.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/caching.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/conftest.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/judge/__init__.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/judge/sandboxes/__init__.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/judge/sandboxes/isolate.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/judge/test.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/judge/testiso.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/steps.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/steps_with_caching.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading/steps_with_caching_run_test.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/grading_utils.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/hydration.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/metadata.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/providers/__init__.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/providers/codeforces.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/providers/provider.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/checkers/boilerplate.cpp +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/default_config.json +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/default_setter_config.mac.yml +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/default_setter_config.yml +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/envs/default.rbx.yml +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/envs/isolate.rbx.yml +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/checker.sh +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/compare +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/compile/c +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/compile/cc +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/compile/cpp +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/compile/java +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/compile/kt +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/compile/pas +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/compile/py2 +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/compile/py3 +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/run/c +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/run/cc +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/run/cpp +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/run/java +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/run/kt +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/run/py2 +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/boca/run/py3 +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/packagers/moj/scripts/compare.sh +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/contest/contest.rbx.yml +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/contest/statement/contest.rbx.tex +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/contest/statement/olymp.sty +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/contest/statement/template.rbx.tex +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/preset.rbx.yml +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/.gitignore +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/gen.cpp +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/problem.rbx.yml +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/random.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/random.txt +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/sols/main.cpp +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/sols/slow.cpp +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/sols/wa.cpp +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/statement/olymp.sty +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/statement/projecao.png +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/statement/statement.rbx.tex +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/statement/template.rbx.tex +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/tests/samples/000.in +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/tests/samples/001.in +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/validator.cpp +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/presets/default/problem/wcmp.cpp +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/resources/templates/template.cpp +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/run.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/schema.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/submit.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/submitors/__init__.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/submitors/codeforces.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/submitors/submitor.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/test.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/testcase.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/testcase_rendering.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/testing_utils.py +0 -0
- {rbx_cp-0.5.42 → rbx_cp-0.5.45}/rbx/utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: rbx.cp
|
3
|
-
Version: 0.5.
|
3
|
+
Version: 0.5.45
|
4
4
|
Summary:
|
5
5
|
Author: Roberto Sales
|
6
6
|
Requires-Python: >=3.9,<4.0
|
@@ -13,7 +13,6 @@ Classifier: Programming Language :: Python :: 3.13
|
|
13
13
|
Requires-Dist: chardet (>=5.2.0,<6.0.0)
|
14
14
|
Requires-Dist: fastapi (>=0.115.8,<0.116.0)
|
15
15
|
Requires-Dist: filelock (>=3.14.0,<4.0.0)
|
16
|
-
Requires-Dist: gevent (>=24.2.1,<25.0.0)
|
17
16
|
Requires-Dist: gitpython (>=3.1.43,<4.0.0)
|
18
17
|
Requires-Dist: jinja2 (>=3.1.4,<4.0.0)
|
19
18
|
Requires-Dist: lark (>=1.2.2,<2.0.0)
|
@@ -1,19 +1,21 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "rbx.cp"
|
3
|
-
version = "0.5.
|
3
|
+
version = "0.5.45"
|
4
4
|
description = ""
|
5
5
|
packages = [
|
6
6
|
{include = "rbx"}
|
7
7
|
]
|
8
8
|
authors = ["Roberto Sales"]
|
9
9
|
readme = "README.md"
|
10
|
+
exclude = [
|
11
|
+
"rbx/testdata/",
|
12
|
+
]
|
10
13
|
|
11
14
|
[tool.poetry.dependencies]
|
12
15
|
python = "^3.9"
|
13
16
|
typer = "^0.15.1"
|
14
17
|
fastapi = "^0.115.8"
|
15
18
|
filelock = "^3.14.0"
|
16
|
-
gevent = "^24.2.1"
|
17
19
|
mechanize = "^0.4.10"
|
18
20
|
jinja2 = "^3.1.4"
|
19
21
|
pydantic = "2.8.2"
|
@@ -103,6 +103,13 @@ def main(
|
|
103
103
|
help='Whether to compile and run testlib components with sanitizers enabled. '
|
104
104
|
'If you want to run the solutions with sanitizers enabled, use the "-s" flag in the corresponding run command.',
|
105
105
|
),
|
106
|
+
debug_logs: bool = typer.Option(
|
107
|
+
False,
|
108
|
+
'--debug-logs',
|
109
|
+
'--debug',
|
110
|
+
'-d',
|
111
|
+
help='Whether to save extra debug logs along with the evaluation results.',
|
112
|
+
),
|
106
113
|
):
|
107
114
|
state.STATE.run_through_cli = True
|
108
115
|
state.STATE.sanitized = sanitized
|
@@ -111,6 +118,7 @@ def main(
|
|
111
118
|
'[warning]Sanitizers are running just for testlib components.\n'
|
112
119
|
'If you want to run the solutions with sanitizers enabled, use the [item]-s[/item] flag in the corresponding run command.[/warning]'
|
113
120
|
)
|
121
|
+
state.STATE.debug_logs = debug_logs
|
114
122
|
|
115
123
|
|
116
124
|
# @app.command('ui', hidden=True)
|
@@ -216,6 +216,52 @@ class PreparedRun:
|
|
216
216
|
metadata: RunLogMetadata
|
217
217
|
|
218
218
|
|
219
|
+
@dataclasses.dataclass
|
220
|
+
class CaptureSpec:
|
221
|
+
prefix: str
|
222
|
+
output: Optional[DigestOrDest] = None
|
223
|
+
merged_capture: Optional[pathlib.Path] = None
|
224
|
+
|
225
|
+
|
226
|
+
def _prepare_for_communication(
|
227
|
+
run: PreparedRun,
|
228
|
+
stdin: pathlib.Path,
|
229
|
+
stdout: pathlib.Path,
|
230
|
+
reverse_io: bool = False,
|
231
|
+
capture: Optional[CaptureSpec] = None,
|
232
|
+
):
|
233
|
+
run.sandbox_params.set_stdio(
|
234
|
+
stdin=stdin,
|
235
|
+
stdout=stdout,
|
236
|
+
)
|
237
|
+
run.sandbox_params.reverse_io = reverse_io
|
238
|
+
if capture is not None:
|
239
|
+
run.sandbox_params.timeit_prefix = capture.prefix
|
240
|
+
|
241
|
+
if capture.output is not None:
|
242
|
+
output_path = PosixPath('capture')
|
243
|
+
run.sandbox_params.timeit_dups['do'].append(output_path)
|
244
|
+
|
245
|
+
run.artifacts.outputs.append(
|
246
|
+
GradingFileOutput(
|
247
|
+
src=output_path,
|
248
|
+
**capture.output.expand(),
|
249
|
+
touch=True,
|
250
|
+
)
|
251
|
+
)
|
252
|
+
|
253
|
+
if capture.merged_capture is not None:
|
254
|
+
merged_output_path = package.get_merged_capture_path().resolve()
|
255
|
+
run.sandbox_params.timeit_dups['Do'].append(merged_output_path)
|
256
|
+
|
257
|
+
run.artifacts.outputs.append(
|
258
|
+
GradingFileOutput(
|
259
|
+
src=merged_output_path,
|
260
|
+
dest=capture.merged_capture,
|
261
|
+
)
|
262
|
+
)
|
263
|
+
|
264
|
+
|
219
265
|
def _prepare_run(
|
220
266
|
code: CodeItem,
|
221
267
|
executable: DigestOrSource,
|
@@ -484,6 +530,7 @@ class CommunicationItem:
|
|
484
530
|
outputs: Optional[List[GradingFileOutput]] = None
|
485
531
|
extra_args: Optional[str] = None
|
486
532
|
extra_config: Optional[ExecutionConfig] = None
|
533
|
+
capture: Optional[DigestOrDest] = None
|
487
534
|
|
488
535
|
def prepare(self) -> PreparedRun:
|
489
536
|
return _prepare_run(
|
@@ -500,6 +547,7 @@ class CommunicationItem:
|
|
500
547
|
async def run_communication(
|
501
548
|
interactor: CommunicationItem,
|
502
549
|
solution: CommunicationItem,
|
550
|
+
merged_capture: Optional[pathlib.Path] = None,
|
503
551
|
retry_index: Optional[int] = None,
|
504
552
|
):
|
505
553
|
fifo_in, fifo_out = package.get_fifos()
|
@@ -510,10 +558,35 @@ async def run_communication(
|
|
510
558
|
interactor_prepared.metadata.retryIndex = retry_index
|
511
559
|
solution_prepared.metadata.retryIndex = retry_index
|
512
560
|
|
513
|
-
|
514
|
-
|
561
|
+
interactor_prefix = 'INTERACTOR:'
|
562
|
+
solution_prefix = 'SOLUTION:'
|
563
|
+
|
564
|
+
if merged_capture is not None:
|
565
|
+
package.get_merged_capture_path().write_text(
|
566
|
+
f'{interactor_prefix}\n{solution_prefix}\n'
|
567
|
+
)
|
515
568
|
|
516
|
-
|
569
|
+
_prepare_for_communication(
|
570
|
+
interactor_prepared,
|
571
|
+
fifo_out,
|
572
|
+
fifo_in,
|
573
|
+
capture=CaptureSpec(
|
574
|
+
prefix=interactor_prefix,
|
575
|
+
output=interactor.capture,
|
576
|
+
merged_capture=merged_capture,
|
577
|
+
),
|
578
|
+
)
|
579
|
+
_prepare_for_communication(
|
580
|
+
solution_prepared,
|
581
|
+
fifo_in,
|
582
|
+
fifo_out,
|
583
|
+
reverse_io=True,
|
584
|
+
capture=CaptureSpec(
|
585
|
+
prefix=solution_prefix,
|
586
|
+
output=solution.capture,
|
587
|
+
merged_capture=merged_capture,
|
588
|
+
),
|
589
|
+
)
|
517
590
|
|
518
591
|
interactor_run_params = steps.CoordinatedRunParams(
|
519
592
|
command=interactor_prepared.command,
|
@@ -393,16 +393,23 @@ def get_compilation_files(code: CodeItem) -> List[Tuple[pathlib.Path, pathlib.Pa
|
|
393
393
|
return res
|
394
394
|
|
395
395
|
|
396
|
+
@functools.cache
|
397
|
+
def get_shared_dir(root: pathlib.Path = pathlib.Path()) -> pathlib.Path:
|
398
|
+
shared_dir = get_problem_cache_dir(root) / '.shared'
|
399
|
+
shared_dir.mkdir(parents=True, exist_ok=True)
|
400
|
+
return shared_dir
|
401
|
+
|
402
|
+
|
396
403
|
@functools.cache
|
397
404
|
def get_empty_sentinel_path(root: pathlib.Path = pathlib.Path()) -> pathlib.Path:
|
398
|
-
path =
|
405
|
+
path = get_shared_dir(root) / '.empty'
|
399
406
|
path.write_text('')
|
400
407
|
return path
|
401
408
|
|
402
409
|
|
403
410
|
@functools.cache
|
404
411
|
def get_fifos(root: pathlib.Path = pathlib.Path()) -> Tuple[pathlib.Path, pathlib.Path]:
|
405
|
-
path =
|
412
|
+
path = get_shared_dir(root) / '.fifos'
|
406
413
|
shutil.rmtree(path, ignore_errors=True)
|
407
414
|
path.mkdir(parents=True, exist_ok=True)
|
408
415
|
fifo_in = path / 'fifo.in'
|
@@ -412,6 +419,13 @@ def get_fifos(root: pathlib.Path = pathlib.Path()) -> Tuple[pathlib.Path, pathli
|
|
412
419
|
return fifo_in, fifo_out
|
413
420
|
|
414
421
|
|
422
|
+
@functools.cache
|
423
|
+
def get_merged_capture_path(root: pathlib.Path = pathlib.Path()) -> pathlib.Path:
|
424
|
+
path = get_shared_dir(root) / '.merged_capture'
|
425
|
+
path.write_text('')
|
426
|
+
return path
|
427
|
+
|
428
|
+
|
415
429
|
def clear_package_cache():
|
416
430
|
pkgs = [sys.modules[__name__]]
|
417
431
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import pathlib
|
2
2
|
from typing import Optional
|
3
3
|
|
4
|
-
from rbx.box import checkers, package
|
4
|
+
from rbx.box import checkers, package, state
|
5
5
|
from rbx.box.code import CommunicationItem, run_communication, run_item
|
6
6
|
from rbx.box.environment import EnvironmentSandbox, ExecutionConfig, VerificationLevel
|
7
7
|
from rbx.box.retries import Retrier
|
@@ -49,6 +49,7 @@ async def run_solution_on_testcase(
|
|
49
49
|
timelimit_override: Optional[int] = None,
|
50
50
|
use_retries: bool = True,
|
51
51
|
use_timelimit: bool = True,
|
52
|
+
capture_pipes: bool = False,
|
52
53
|
) -> Evaluation:
|
53
54
|
if interactor_digest is not None:
|
54
55
|
return await _run_communication_solution_on_testcase(
|
@@ -63,6 +64,7 @@ async def run_solution_on_testcase(
|
|
63
64
|
timelimit_override=timelimit_override,
|
64
65
|
use_retries=use_retries,
|
65
66
|
use_timelimit=use_timelimit,
|
67
|
+
capture_pipes=capture_pipes,
|
66
68
|
)
|
67
69
|
|
68
70
|
async def run_fn(retry_index: int) -> Evaluation:
|
@@ -155,7 +157,10 @@ async def _run_communication_solution_on_testcase(
|
|
155
157
|
timelimit_override: Optional[int] = None,
|
156
158
|
use_retries: bool = True,
|
157
159
|
use_timelimit: bool = True,
|
160
|
+
capture_pipes: bool = False,
|
158
161
|
) -> Evaluation:
|
162
|
+
capture_pipes = capture_pipes or state.STATE.debug_logs
|
163
|
+
|
159
164
|
async def run_fn(retry_index: int) -> Evaluation:
|
160
165
|
actual_sandbox = package.get_singleton_sandbox()
|
161
166
|
interactor_sandbox = package.get_singleton_interactor_sandbox()
|
@@ -185,6 +190,9 @@ async def _run_communication_solution_on_testcase(
|
|
185
190
|
log_path = output_path.with_suffix('.log')
|
186
191
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
187
192
|
|
193
|
+
interactor_capture_path = (
|
194
|
+
output_path.with_suffix('.pin') if capture_pipes else None
|
195
|
+
)
|
188
196
|
interactor_item = CommunicationItem(
|
189
197
|
code=package.get_interactor(),
|
190
198
|
executable=DigestOrSource.create(interactor_digest),
|
@@ -204,17 +212,28 @@ async def _run_communication_solution_on_testcase(
|
|
204
212
|
touch=True,
|
205
213
|
)
|
206
214
|
],
|
215
|
+
capture=DigestOrDest.create(interactor_capture_path)
|
216
|
+
if interactor_capture_path
|
217
|
+
else None,
|
218
|
+
)
|
219
|
+
solution_capture_path = (
|
220
|
+
output_path.with_suffix('.pout') if capture_pipes else None
|
207
221
|
)
|
208
222
|
solution_item = CommunicationItem(
|
209
223
|
code=solution,
|
210
224
|
executable=DigestOrSource.create(compiled_digest),
|
211
225
|
extra_config=extra_config,
|
226
|
+
capture=DigestOrDest.create(solution_capture_path)
|
227
|
+
if solution_capture_path
|
228
|
+
else None,
|
212
229
|
)
|
213
230
|
|
231
|
+
merged_capture_path = output_path.with_suffix('.pio') if capture_pipes else None
|
214
232
|
interactor_run_log, run_log = await run_communication(
|
215
233
|
interactor=interactor_item,
|
216
234
|
solution=solution_item,
|
217
235
|
retry_index=retry_index,
|
236
|
+
merged_capture=merged_capture_path,
|
218
237
|
)
|
219
238
|
|
220
239
|
checker_result = await checkers.check_communication(
|
@@ -9,8 +9,6 @@ import tempfile
|
|
9
9
|
import typing
|
10
10
|
from typing import IO, List, Optional
|
11
11
|
|
12
|
-
import gevent
|
13
|
-
|
14
12
|
from rbx.grading.judge import digester, storage
|
15
13
|
|
16
14
|
logger = logging.getLogger(__name__)
|
@@ -318,8 +316,6 @@ class FileCacher:
|
|
318
316
|
d.update(buf)
|
319
317
|
while len(buf) > 0:
|
320
318
|
written = dst.write(buf)
|
321
|
-
# Cooperative yield.
|
322
|
-
gevent.sleep(0)
|
323
319
|
if written is None:
|
324
320
|
break
|
325
321
|
buf = buf[written:]
|
@@ -2,8 +2,6 @@ import hashlib
|
|
2
2
|
import pathlib
|
3
3
|
from typing import IO
|
4
4
|
|
5
|
-
import gevent
|
6
|
-
|
7
5
|
|
8
6
|
class Digester:
|
9
7
|
"""Simple wrapper of hashlib using our preferred hasher."""
|
@@ -26,7 +24,6 @@ def digest_cooperatively_into_digester(
|
|
26
24
|
buf = f.read(chunk_size)
|
27
25
|
while len(buf) > 0:
|
28
26
|
digester.update(buf)
|
29
|
-
gevent.sleep(0)
|
30
27
|
buf = f.read(chunk_size)
|
31
28
|
|
32
29
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import abc
|
2
|
+
import collections
|
2
3
|
import dataclasses
|
3
4
|
import io
|
4
5
|
import logging
|
@@ -114,6 +115,12 @@ class SandboxParams(pydantic.BaseModel):
|
|
114
115
|
extra_timeout: Optional[int] = None # ms
|
115
116
|
reverse_io: bool = False
|
116
117
|
|
118
|
+
# For timeit
|
119
|
+
timeit_dups: Dict[str, List[pathlib.Path]] = dataclasses.field(
|
120
|
+
default_factory=lambda: collections.defaultdict(list)
|
121
|
+
)
|
122
|
+
timeit_prefix: Optional[str] = None
|
123
|
+
|
117
124
|
def get_cacheable_params(self) -> Dict[str, Any]:
|
118
125
|
return self.model_dump(mode='json', exclude_unset=True, exclude_none=True)
|
119
126
|
|
@@ -105,8 +105,17 @@ class StupidSandbox(SandboxBase):
|
|
105
105
|
file_args.append(f'-e{self.params.stderr_file}')
|
106
106
|
if self.params.reverse_io:
|
107
107
|
file_args.reverse()
|
108
|
+
args.extend(file_args)
|
108
109
|
|
109
|
-
|
110
|
+
if self.params.timeit_dups:
|
111
|
+
for i, files in self.params.timeit_dups.items():
|
112
|
+
assert i.lower() in ['di', 'do', 'de']
|
113
|
+
for file in files:
|
114
|
+
args.append(f'-{i}{file}')
|
115
|
+
if self.params.timeit_prefix:
|
116
|
+
args.append(f'-P{self.params.timeit_prefix}')
|
117
|
+
|
118
|
+
return args
|
110
119
|
|
111
120
|
def get_root_path(self) -> pathlib.Path:
|
112
121
|
"""Return the toplevel path of the sandbox.
|
@@ -6,7 +6,7 @@ import signal
|
|
6
6
|
import stat
|
7
7
|
import sys
|
8
8
|
from time import monotonic
|
9
|
-
from typing import List, Optional
|
9
|
+
from typing import Any, Dict, List, Optional, Set, Union
|
10
10
|
|
11
11
|
|
12
12
|
@dataclasses.dataclass
|
@@ -22,12 +22,96 @@ class Options:
|
|
22
22
|
memory_limit: Optional[int] = None # kb, but passed in args as mb
|
23
23
|
fs_limit: Optional[int] = None # kb
|
24
24
|
files_to_open: List[int] = dataclasses.field(default_factory=list)
|
25
|
+
file_duplicates: Dict[int, List[str]] = dataclasses.field(default_factory=dict)
|
26
|
+
prefixed: Set[str] = dataclasses.field(default_factory=set)
|
27
|
+
prefix: str = ''
|
25
28
|
|
26
29
|
|
27
30
|
def exit_with(code: int):
|
28
31
|
sys.exit(code)
|
29
32
|
|
30
33
|
|
34
|
+
def get_tee_command(files: List[str]) -> str:
|
35
|
+
path = (
|
36
|
+
os.path.join(os.path.dirname(os.path.realpath(__file__)), 'tee.py')
|
37
|
+
+ ' '
|
38
|
+
+ ' '.join(files)
|
39
|
+
)
|
40
|
+
return sys.executable + ' ' + path
|
41
|
+
|
42
|
+
|
43
|
+
valid_modes = ['a', 'w']
|
44
|
+
|
45
|
+
|
46
|
+
@dataclasses.dataclass
|
47
|
+
class Tee:
|
48
|
+
file: Any
|
49
|
+
prefix: Union[str, bytes] = ''
|
50
|
+
|
51
|
+
|
52
|
+
def create_tee(files, mode, buffer_size=4096, prefix=''):
|
53
|
+
"""Get a file object that will mirror writes across multiple files objs
|
54
|
+
|
55
|
+
Options:
|
56
|
+
files A list of files and/or file objects. All strings will be
|
57
|
+
treated as file paths and opened for writing. Everything
|
58
|
+
else is assumed to be a file-like object that implements
|
59
|
+
both the write() and flush() methods.
|
60
|
+
|
61
|
+
mode Which mode to use when opening new files. Valid values
|
62
|
+
are 'a' (append) and 'w' (overwrite).
|
63
|
+
|
64
|
+
buffer_size
|
65
|
+
Control the size of the buffer between writes to the
|
66
|
+
resulting file object and the list of files.
|
67
|
+
"""
|
68
|
+
if mode not in valid_modes:
|
69
|
+
raise IOError(
|
70
|
+
'Only valid modes to create_tee() are: %s' % ', '.join(valid_modes)
|
71
|
+
)
|
72
|
+
|
73
|
+
tee_list = []
|
74
|
+
for file in files:
|
75
|
+
if isinstance(file, Tee):
|
76
|
+
tee_list.append(file)
|
77
|
+
else:
|
78
|
+
tee_list.append(Tee(file))
|
79
|
+
for tee in tee_list:
|
80
|
+
if isinstance(tee.file, str):
|
81
|
+
tee.file = open(tee.file, f'{mode}b')
|
82
|
+
if isinstance(tee.prefix, str):
|
83
|
+
tee.prefix = tee.prefix.encode()
|
84
|
+
|
85
|
+
pipe_read, pipe_write = os.pipe()
|
86
|
+
pid = os.fork()
|
87
|
+
if pid == 0:
|
88
|
+
# Child -- Read bytes from the pipe and write them to the specified
|
89
|
+
# files.
|
90
|
+
try:
|
91
|
+
# Close parent's end of the pipe
|
92
|
+
os.close(pipe_write)
|
93
|
+
|
94
|
+
bytes = os.read(pipe_read, buffer_size)
|
95
|
+
while bytes:
|
96
|
+
for tee in tee_list:
|
97
|
+
if tee.prefix:
|
98
|
+
tee.file.write(tee.prefix)
|
99
|
+
tee.file.write(bytes)
|
100
|
+
tee.file.flush()
|
101
|
+
# TODO maybe add in fsync() here if the fileno() method
|
102
|
+
# exists on file
|
103
|
+
|
104
|
+
bytes = os.read(pipe_read, buffer_size)
|
105
|
+
except Exception:
|
106
|
+
pass
|
107
|
+
finally:
|
108
|
+
os._exit(255)
|
109
|
+
else:
|
110
|
+
# Parent -- Return a file object wrapper around the pipe to the
|
111
|
+
# child.
|
112
|
+
return os.fdopen(pipe_write, 'w', closefd=False)
|
113
|
+
|
114
|
+
|
31
115
|
def parse_opts() -> Options:
|
32
116
|
options = Options(output_file=sys.argv[1], argv=[])
|
33
117
|
options.files_to_open = []
|
@@ -50,10 +134,21 @@ def parse_opts() -> Options:
|
|
50
134
|
elif opt.startswith('-e'):
|
51
135
|
options.stderr_file = opt[2:]
|
52
136
|
options.files_to_open.append(2)
|
137
|
+
elif opt.startswith('-d') or opt.startswith('-D'):
|
138
|
+
is_prefixed = opt.startswith('-D')
|
139
|
+
possibilities = [None, 'o', 'e']
|
140
|
+
index = possibilities.index(opt[2])
|
141
|
+
if index not in options.file_duplicates:
|
142
|
+
options.file_duplicates[index] = []
|
143
|
+
options.file_duplicates[index].append(opt[3:])
|
144
|
+
if is_prefixed:
|
145
|
+
options.prefixed.add(opt[3:])
|
53
146
|
elif opt.startswith('-c'):
|
54
147
|
options.chdir = opt[2:]
|
55
148
|
elif opt.startswith('-f'):
|
56
149
|
options.fs_limit = int(opt[2:])
|
150
|
+
elif opt.startswith('-P'):
|
151
|
+
options.prefix = opt[2:]
|
57
152
|
else:
|
58
153
|
raise Exception(f'Invalid option {opt}')
|
59
154
|
num_opts += 1
|
@@ -108,10 +203,18 @@ def redirect_fds(options: Options):
|
|
108
203
|
if i == 0:
|
109
204
|
# stdin
|
110
205
|
open_args = [os.O_RDONLY]
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
206
|
+
if i in options.file_duplicates:
|
207
|
+
dups = [
|
208
|
+
Tee(f, prefix=options.prefix if f in options.prefixed else '')
|
209
|
+
for f in options.file_duplicates[i]
|
210
|
+
]
|
211
|
+
tee = create_tee(dups + [file], 'a', prefix=options.prefix)
|
212
|
+
fd = tee.fileno()
|
213
|
+
else:
|
214
|
+
fd = os.open(
|
215
|
+
file,
|
216
|
+
*open_args,
|
217
|
+
)
|
115
218
|
os.dup2(fd, i)
|
116
219
|
os.close(fd)
|
117
220
|
|
@@ -221,3 +324,4 @@ def main():
|
|
221
324
|
|
222
325
|
if __name__ == '__main__':
|
223
326
|
main()
|
327
|
+
# type: ignore
|
@@ -6,8 +6,6 @@ import tempfile
|
|
6
6
|
from abc import ABC, abstractmethod
|
7
7
|
from typing import IO, AnyStr, List, Optional
|
8
8
|
|
9
|
-
import gevent
|
10
|
-
|
11
9
|
logger = logging.getLogger(__name__)
|
12
10
|
|
13
11
|
TOMBSTONE = 'x'
|
@@ -40,11 +38,9 @@ def copyfileobj(
|
|
40
38
|
if maxlen > 0 and maxlen < len(buffer):
|
41
39
|
buffer = buffer[:maxlen]
|
42
40
|
while len(buffer) > 0:
|
43
|
-
gevent.sleep(0)
|
44
41
|
written = destination_fobj.write(buffer)
|
45
42
|
buffer = buffer[written:]
|
46
43
|
maxlen -= written
|
47
|
-
gevent.sleep(0)
|
48
44
|
|
49
45
|
|
50
46
|
@dataclasses.dataclass
|
rbx_cp-0.5.42/rbx/box/main.py
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
#include <bits/stdc++.h>
|
2
|
-
#include <ctime>
|
3
|
-
|
4
|
-
using namespace std;
|
5
|
-
|
6
|
-
void busy_loop() {
|
7
|
-
double wait = 5.0;
|
8
|
-
int start = clock();
|
9
|
-
int end = clock();
|
10
|
-
while (((double) (end - start)) / CLOCKS_PER_SEC < wait)
|
11
|
-
{
|
12
|
-
end = clock();
|
13
|
-
}
|
14
|
-
}
|
15
|
-
|
16
|
-
int32_t main() {
|
17
|
-
ios::sync_with_stdio(false);
|
18
|
-
cin.tie(0);
|
19
|
-
|
20
|
-
int n; cin >> n;
|
21
|
-
|
22
|
-
busy_loop();
|
23
|
-
|
24
|
-
cout << "hard" << endl;
|
25
|
-
return 0;
|
26
|
-
}
|
@@ -1,17 +0,0 @@
|
|
1
|
-
|
2
|
-
#include <bits/stdc++.h>
|
3
|
-
|
4
|
-
using namespace std;
|
5
|
-
|
6
|
-
int32_t main() {
|
7
|
-
ios::sync_with_stdio(false);
|
8
|
-
cin.tie(0);
|
9
|
-
|
10
|
-
int n;
|
11
|
-
cin >> n;
|
12
|
-
|
13
|
-
for (int i = 1; i <= 100000; i++) { // more than output limit of 100kb
|
14
|
-
cout << 123456 << "\n";
|
15
|
-
}
|
16
|
-
return 0;
|
17
|
-
}
|
@@ -1,39 +0,0 @@
|
|
1
|
-
---
|
2
|
-
name: "test-problem"
|
3
|
-
timeLimit: 1000
|
4
|
-
memoryLimit: 256
|
5
|
-
outputLimit: 100 # 100 kb
|
6
|
-
generators:
|
7
|
-
- name: "gen1"
|
8
|
-
path: "gen1.cpp"
|
9
|
-
- name: "gen2"
|
10
|
-
path: "gen2.cpp"
|
11
|
-
validator:
|
12
|
-
path: "validator.cpp"
|
13
|
-
testcases:
|
14
|
-
- name: "gen1"
|
15
|
-
testcaseGlob: "tests/*.in"
|
16
|
-
subgroups:
|
17
|
-
- name: "gen"
|
18
|
-
generators:
|
19
|
-
- name: "gen1"
|
20
|
-
- name: "gen2"
|
21
|
-
args: "424242"
|
22
|
-
- name: "genScript"
|
23
|
-
generatorScript:
|
24
|
-
path: "genScript.py"
|
25
|
-
solutions:
|
26
|
-
- path: "sol.cpp"
|
27
|
-
outcome: "ac"
|
28
|
-
- path: "wa.sol.cpp"
|
29
|
-
outcome: "fail"
|
30
|
-
- path: "re.sol.cpp"
|
31
|
-
outcome: "rte"
|
32
|
-
- path: "tle.sol.cpp"
|
33
|
-
outcome: "tle"
|
34
|
-
- path: "tle-and-incorrect.sol.cpp"
|
35
|
-
outcome: "tle"
|
36
|
-
- path: "hard-tle.sol.cpp"
|
37
|
-
outcome: "tle"
|
38
|
-
- path: "ole.cpp"
|
39
|
-
outcome: "ole"
|