rbx.cp 0.5.0__py3-none-any.whl

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.
Files changed (164) hide show
  1. rbx/__init__.py +0 -0
  2. rbx/annotations.py +127 -0
  3. rbx/autoenum.py +333 -0
  4. rbx/box/__init__.py +0 -0
  5. rbx/box/builder.py +77 -0
  6. rbx/box/cd.py +37 -0
  7. rbx/box/checkers.py +134 -0
  8. rbx/box/code.py +185 -0
  9. rbx/box/compile.py +56 -0
  10. rbx/box/conftest.py +42 -0
  11. rbx/box/contest/__init__.py +0 -0
  12. rbx/box/contest/build_contest_statements.py +347 -0
  13. rbx/box/contest/contest_package.py +76 -0
  14. rbx/box/contest/contest_utils.py +20 -0
  15. rbx/box/contest/main.py +179 -0
  16. rbx/box/contest/schema.py +155 -0
  17. rbx/box/contest/statements.py +82 -0
  18. rbx/box/creation.py +72 -0
  19. rbx/box/download.py +64 -0
  20. rbx/box/environment.py +345 -0
  21. rbx/box/extensions.py +26 -0
  22. rbx/box/generators.py +478 -0
  23. rbx/box/generators_test.py +63 -0
  24. rbx/box/main.py +449 -0
  25. rbx/box/package.py +316 -0
  26. rbx/box/packaging/boca/extension.py +27 -0
  27. rbx/box/packaging/boca/packager.py +245 -0
  28. rbx/box/packaging/contest_main.py +82 -0
  29. rbx/box/packaging/main.py +68 -0
  30. rbx/box/packaging/packager.py +117 -0
  31. rbx/box/packaging/polygon/packager.py +320 -0
  32. rbx/box/packaging/polygon/test.py +81 -0
  33. rbx/box/packaging/polygon/xml_schema.py +106 -0
  34. rbx/box/presets/__init__.py +503 -0
  35. rbx/box/presets/fetch.py +70 -0
  36. rbx/box/presets/lock_schema.py +20 -0
  37. rbx/box/presets/schema.py +59 -0
  38. rbx/box/schema.py +394 -0
  39. rbx/box/solutions.py +792 -0
  40. rbx/box/solutions_test.py +41 -0
  41. rbx/box/statements/__init__.py +0 -0
  42. rbx/box/statements/build_statements.py +359 -0
  43. rbx/box/statements/builders.py +375 -0
  44. rbx/box/statements/joiners.py +113 -0
  45. rbx/box/statements/latex.py +47 -0
  46. rbx/box/statements/latex_jinja.py +214 -0
  47. rbx/box/statements/schema.py +138 -0
  48. rbx/box/stresses.py +292 -0
  49. rbx/box/stressing/__init__.py +0 -0
  50. rbx/box/stressing/finder_parser.py +359 -0
  51. rbx/box/stressing/generator_parser.py +258 -0
  52. rbx/box/testcases.py +54 -0
  53. rbx/box/ui/__init__.py +0 -0
  54. rbx/box/ui/captured_log.py +372 -0
  55. rbx/box/ui/css/app.tcss +48 -0
  56. rbx/box/ui/main.py +38 -0
  57. rbx/box/ui/run.py +209 -0
  58. rbx/box/validators.py +245 -0
  59. rbx/box/validators_test.py +15 -0
  60. rbx/checker.py +128 -0
  61. rbx/clone.py +197 -0
  62. rbx/config.py +271 -0
  63. rbx/conftest.py +38 -0
  64. rbx/console.py +27 -0
  65. rbx/create.py +37 -0
  66. rbx/edit.py +24 -0
  67. rbx/grading/__init__.py +0 -0
  68. rbx/grading/caching.py +356 -0
  69. rbx/grading/conftest.py +33 -0
  70. rbx/grading/judge/__init__.py +0 -0
  71. rbx/grading/judge/cacher.py +503 -0
  72. rbx/grading/judge/digester.py +35 -0
  73. rbx/grading/judge/sandbox.py +748 -0
  74. rbx/grading/judge/sandboxes/__init__.py +0 -0
  75. rbx/grading/judge/sandboxes/isolate.py +683 -0
  76. rbx/grading/judge/sandboxes/stupid_sandbox.py +310 -0
  77. rbx/grading/judge/sandboxes/timeit.py +217 -0
  78. rbx/grading/judge/storage.py +284 -0
  79. rbx/grading/judge/test.py +38 -0
  80. rbx/grading/judge/testiso.py +54 -0
  81. rbx/grading/steps.py +522 -0
  82. rbx/grading/steps_with_caching.py +59 -0
  83. rbx/grading/steps_with_caching_run_test.py +429 -0
  84. rbx/grading_utils.py +148 -0
  85. rbx/hydration.py +101 -0
  86. rbx/main.py +122 -0
  87. rbx/metadata.py +105 -0
  88. rbx/providers/__init__.py +43 -0
  89. rbx/providers/codeforces.py +73 -0
  90. rbx/providers/provider.py +26 -0
  91. rbx/resources/checkers/boilerplate.cpp +20 -0
  92. rbx/resources/default_config.json +48 -0
  93. rbx/resources/envs/default.rbx.yml +37 -0
  94. rbx/resources/envs/isolate.rbx.yml +37 -0
  95. rbx/resources/packagers/boca/checker.sh +43 -0
  96. rbx/resources/packagers/boca/compare +53 -0
  97. rbx/resources/packagers/boca/compile/c +172 -0
  98. rbx/resources/packagers/boca/compile/cc +173 -0
  99. rbx/resources/packagers/boca/compile/cpp +172 -0
  100. rbx/resources/packagers/boca/compile/java +194 -0
  101. rbx/resources/packagers/boca/compile/kt +155 -0
  102. rbx/resources/packagers/boca/compile/pas +172 -0
  103. rbx/resources/packagers/boca/compile/py2 +173 -0
  104. rbx/resources/packagers/boca/compile/py3 +173 -0
  105. rbx/resources/packagers/boca/run/c +128 -0
  106. rbx/resources/packagers/boca/run/cc +128 -0
  107. rbx/resources/packagers/boca/run/cpp +128 -0
  108. rbx/resources/packagers/boca/run/java +194 -0
  109. rbx/resources/packagers/boca/run/kt +159 -0
  110. rbx/resources/packagers/boca/run/py2 +166 -0
  111. rbx/resources/packagers/boca/run/py3 +166 -0
  112. rbx/resources/presets/default/contest/contest.rbx.yml +14 -0
  113. rbx/resources/presets/default/contest/statement/contest.rbx.tex +97 -0
  114. rbx/resources/presets/default/contest/statement/olymp.sty +250 -0
  115. rbx/resources/presets/default/contest/statement/template.rbx.tex +42 -0
  116. rbx/resources/presets/default/preset.rbx.yml +12 -0
  117. rbx/resources/presets/default/problem/.gitignore +6 -0
  118. rbx/resources/presets/default/problem/gen.cpp +9 -0
  119. rbx/resources/presets/default/problem/problem.rbx.yml +44 -0
  120. rbx/resources/presets/default/problem/random.py +3 -0
  121. rbx/resources/presets/default/problem/random.txt +2 -0
  122. rbx/resources/presets/default/problem/sols/main.cpp +9 -0
  123. rbx/resources/presets/default/problem/sols/slow.cpp +15 -0
  124. rbx/resources/presets/default/problem/sols/wa.cpp +9 -0
  125. rbx/resources/presets/default/problem/statement/olymp.sty +250 -0
  126. rbx/resources/presets/default/problem/statement/projecao.png +0 -0
  127. rbx/resources/presets/default/problem/statement/statement.rbx.tex +18 -0
  128. rbx/resources/presets/default/problem/statement/template.rbx.tex +89 -0
  129. rbx/resources/presets/default/problem/tests/samples/000.in +1 -0
  130. rbx/resources/presets/default/problem/tests/samples/001.in +1 -0
  131. rbx/resources/presets/default/problem/validator.cpp +16 -0
  132. rbx/resources/presets/default/problem/wcmp.cpp +34 -0
  133. rbx/resources/templates/template.cpp +19 -0
  134. rbx/run.py +45 -0
  135. rbx/schema.py +64 -0
  136. rbx/submit.py +61 -0
  137. rbx/submitors/__init__.py +18 -0
  138. rbx/submitors/codeforces.py +120 -0
  139. rbx/submitors/submitor.py +25 -0
  140. rbx/test.py +347 -0
  141. rbx/testcase.py +70 -0
  142. rbx/testcase_rendering.py +79 -0
  143. rbx/testdata/box1/gen1.cpp +7 -0
  144. rbx/testdata/box1/gen2.cpp +9 -0
  145. rbx/testdata/box1/genScript.py +2 -0
  146. rbx/testdata/box1/hard-tle.sol.cpp +26 -0
  147. rbx/testdata/box1/ole.cpp +17 -0
  148. rbx/testdata/box1/problem.rbx.yml +39 -0
  149. rbx/testdata/box1/re.sol.cpp +23 -0
  150. rbx/testdata/box1/sol.cpp +22 -0
  151. rbx/testdata/box1/tests/1.in +1 -0
  152. rbx/testdata/box1/tle-and-incorrect.sol.cpp +33 -0
  153. rbx/testdata/box1/tle.sol.cpp +35 -0
  154. rbx/testdata/box1/validator.cpp +11 -0
  155. rbx/testdata/box1/wa.sol.cpp +22 -0
  156. rbx/testdata/caching/executable.py +1 -0
  157. rbx/testdata/compatible +0 -0
  158. rbx/testing_utils.py +65 -0
  159. rbx/utils.py +162 -0
  160. rbx_cp-0.5.0.dist-info/LICENSE +201 -0
  161. rbx_cp-0.5.0.dist-info/METADATA +89 -0
  162. rbx_cp-0.5.0.dist-info/RECORD +164 -0
  163. rbx_cp-0.5.0.dist-info/WHEEL +4 -0
  164. rbx_cp-0.5.0.dist-info/entry_points.txt +4 -0
rbx/main.py ADDED
@@ -0,0 +1,122 @@
1
+ # flake8: noqa
2
+ from gevent import monkey
3
+
4
+ monkey.patch_all()
5
+
6
+ import typer
7
+ from typing_extensions import Annotated
8
+
9
+ from rbx import annotations, checker, config, testcase
10
+ from rbx import clone as clone_pkg
11
+ from rbx import create as create_pkg
12
+ from rbx import edit as edit_pkg
13
+ from rbx import run as run_pkg
14
+ from rbx import submit as submit_pkg
15
+ from rbx import test as test_pkg
16
+ from rbx.box import main
17
+
18
+ app = typer.Typer(no_args_is_help=True, cls=annotations.AliasGroup)
19
+ app.add_typer(main.app, name='box', cls=annotations.AliasGroup)
20
+ app.add_typer(
21
+ config.app,
22
+ name='config, cfg',
23
+ cls=annotations.AliasGroup,
24
+ help='Manage the configuration of the tool.',
25
+ )
26
+ app.add_typer(
27
+ testcase.app,
28
+ name='testcase, tc',
29
+ cls=annotations.AliasGroup,
30
+ help='Commands to manage the testcases of a problem.',
31
+ )
32
+ app.add_typer(
33
+ checker.app,
34
+ name='checker, check',
35
+ cls=annotations.AliasGroup,
36
+ help='Commands to manage the checker of a problem.',
37
+ )
38
+
39
+
40
+ @app.command('clone, c')
41
+ def clone(lang: annotations.Language):
42
+ """
43
+ Clones by waiting for a set of problems to be sent through Competitive Companion.
44
+ """
45
+ clone_pkg.main(lang=lang)
46
+
47
+
48
+ @app.command('new, n')
49
+ def new(
50
+ name: str,
51
+ language: annotations.Language,
52
+ timelimit: annotations.Timelimit = 1000,
53
+ memorylimit: annotations.Memorylimit = 256,
54
+ multitest: annotations.Multitest = False,
55
+ ):
56
+ """
57
+ Create a new problem from scratch.
58
+ """
59
+ create_pkg.main(name, language, timelimit, memorylimit, multitest)
60
+
61
+
62
+ @app.command('edit, e')
63
+ def edit(
64
+ problem: annotations.Problem, language: annotations.LanguageWithDefault = None
65
+ ):
66
+ """
67
+ Edit the code of a problem using the provided language.
68
+ """
69
+ edit_pkg.main(problem, language)
70
+
71
+
72
+ @app.command('test, t')
73
+ def test(
74
+ problem: annotations.Problem,
75
+ language: annotations.LanguageWithDefault = None,
76
+ keep_sandbox: bool = False,
77
+ index: annotations.TestcaseIndex = None,
78
+ interactive: Annotated[bool, typer.Option('--interactive', '--int')] = False,
79
+ ):
80
+ """
81
+ Test a problem using the provided language.
82
+ """
83
+ test_pkg.main(
84
+ problem,
85
+ language,
86
+ keep_sandbox=keep_sandbox,
87
+ index=index,
88
+ interactive=interactive,
89
+ )
90
+
91
+
92
+ @app.command('run, r')
93
+ def run(
94
+ problem: annotations.Problem,
95
+ language: annotations.LanguageWithDefault = None,
96
+ keep_sandbox: bool = False,
97
+ ):
98
+ """
99
+ Run a problem using the provided language.
100
+ """
101
+ run_pkg.main(
102
+ problem,
103
+ language,
104
+ keep_sandbox=keep_sandbox,
105
+ )
106
+
107
+
108
+ @app.command('submit, s')
109
+ def submit(
110
+ problem: annotations.Problem,
111
+ language: annotations.LanguageWithDefault = None,
112
+ keep_sandbox: bool = False,
113
+ ):
114
+ """
115
+ Submit a problem using the provided language.
116
+ """
117
+ submit_pkg.main(problem, language, keep_sandbox=keep_sandbox)
118
+
119
+
120
+ @app.callback()
121
+ def callback():
122
+ pass
rbx/metadata.py ADDED
@@ -0,0 +1,105 @@
1
+ import pathlib
2
+ from typing import List, Optional, Tuple
3
+
4
+ from rbx.schema import DumpedProblem
5
+
6
+
7
+ def _normalize_alias(alias: str) -> str:
8
+ return alias.lower()
9
+
10
+
11
+ def _find_alias(alias: str, haystack: List[str]) -> Optional[int]:
12
+ normalized_alias = _normalize_alias(alias)
13
+ for i, candidate in enumerate(haystack):
14
+ if _normalize_alias(candidate) == normalized_alias:
15
+ return i
16
+ return None
17
+
18
+
19
+ def _get_best_alias_from_candidates(
20
+ alias: str, candidates: List[Tuple[pathlib.Path, DumpedProblem]]
21
+ ) -> Optional[Tuple[pathlib.Path, DumpedProblem]]:
22
+ best_priority = 1e9
23
+ best_candidates = []
24
+ for path, problem in candidates:
25
+ index = _find_alias(alias, problem.aliases)
26
+ if index is None:
27
+ continue
28
+ if index < best_priority:
29
+ best_priority = index
30
+ best_candidates = [(path, problem)]
31
+ elif index == best_priority:
32
+ best_candidates.append((path, problem))
33
+
34
+ if len(best_candidates) != 1:
35
+ # TODO
36
+ return None
37
+
38
+ return best_candidates[0]
39
+
40
+
41
+ def find_problem_path_by_code(
42
+ code: str, root: Optional[pathlib.Path] = None
43
+ ) -> Optional[pathlib.Path]:
44
+ if not root:
45
+ root = pathlib.Path()
46
+
47
+ metadata_path = root / f'{code}.rbx.json'
48
+ if not metadata_path.is_file():
49
+ return None
50
+ return metadata_path
51
+
52
+
53
+ def find_problem_path_by_alias(
54
+ alias: str, root: Optional[pathlib.Path] = None
55
+ ) -> Optional[pathlib.Path]:
56
+ if not root:
57
+ root = pathlib.Path()
58
+
59
+ candidates: List[Tuple[pathlib.Path, DumpedProblem]] = []
60
+ for metadata_path in root.glob('*.rbx.json'):
61
+ problem = DumpedProblem.model_validate_json(metadata_path.read_text())
62
+ if _find_alias(alias, problem.aliases) is not None:
63
+ candidates.append((metadata_path, problem))
64
+
65
+ picked_candidate = _get_best_alias_from_candidates(alias, candidates)
66
+ if not picked_candidate:
67
+ return None
68
+ return picked_candidate[0]
69
+
70
+
71
+ def find_problem_by_alias(
72
+ alias: str, root: Optional[pathlib.Path] = None
73
+ ) -> Optional[DumpedProblem]:
74
+ metadata_path = find_problem_path_by_alias(alias, root)
75
+ if not metadata_path:
76
+ return None
77
+ return DumpedProblem.model_validate_json(metadata_path.read_text())
78
+
79
+
80
+ def find_problem_by_code(
81
+ code: str, root: Optional[pathlib.Path] = None
82
+ ) -> Optional[DumpedProblem]:
83
+ metadata_path = find_problem_path_by_code(code, root)
84
+ if not metadata_path:
85
+ return None
86
+ return DumpedProblem.model_validate_json(metadata_path.read_text())
87
+
88
+
89
+ def find_problem_by_anything(
90
+ anything: str, root: Optional[pathlib.Path] = None
91
+ ) -> Optional[DumpedProblem]:
92
+ problem = find_problem_by_code(anything, root)
93
+ if problem:
94
+ return problem
95
+ return find_problem_by_alias(anything, root)
96
+
97
+
98
+ def find_problems(root: Optional[pathlib.Path] = None) -> List[DumpedProblem]:
99
+ if not root:
100
+ root = pathlib.Path()
101
+
102
+ problems = []
103
+ for metadata_path in root.glob('*.rbx.json'):
104
+ problems.append(DumpedProblem.model_validate_json(metadata_path.read_text()))
105
+ return problems
@@ -0,0 +1,43 @@
1
+ from typing import List
2
+
3
+ from rbx.providers.codeforces import CodeforcesProvider
4
+ from rbx.providers.provider import ProviderInterface
5
+ from rbx.schema import Problem
6
+
7
+ ALL_PROVIDERS: List[ProviderInterface] = [
8
+ CodeforcesProvider(),
9
+ ]
10
+
11
+
12
+ def is_contest(problems: List[Problem]) -> bool:
13
+ for provider in ALL_PROVIDERS:
14
+ handle_all = all(provider.should_handle(problem.url) for problem in problems)
15
+ if handle_all:
16
+ return provider.is_contest(problems)
17
+ return False
18
+
19
+
20
+ def should_simplify_contest_problems(problems: List[Problem]) -> bool:
21
+ if not is_contest(problems):
22
+ return False
23
+ for provider in ALL_PROVIDERS:
24
+ handle_all = all(provider.should_handle(problem.url) for problem in problems)
25
+ if handle_all:
26
+ return provider.should_simplify_contest_problems()
27
+ return False
28
+
29
+
30
+ def get_code(problem: Problem, simplify: bool = False) -> str:
31
+ for provider in ALL_PROVIDERS:
32
+ if provider.should_handle(problem.url):
33
+ if simplify:
34
+ return provider.get_problem_code_within_contest(problem)
35
+ return provider.get_code(problem)
36
+ return problem.get_normalized_name()
37
+
38
+
39
+ def get_aliases(problem: Problem) -> List[str]:
40
+ for provider in ALL_PROVIDERS:
41
+ if provider.should_handle(problem.url):
42
+ return provider.get_aliases(problem)
43
+ return []
@@ -0,0 +1,73 @@
1
+ import re
2
+ from typing import List, Optional
3
+
4
+ from rbx.providers.provider import ProviderInterface
5
+ from rbx.schema import Problem
6
+
7
+
8
+ def _add_underscores(matches: List[str]) -> List[str]:
9
+ if len(matches) <= 2:
10
+ return matches
11
+ return [f'{x}_' for x in matches[:-2]] + matches[-2:]
12
+
13
+
14
+ _PATTERNS = [
15
+ r'https?://(?:.*\.)?codeforces.(?:com|ml|es)/(?:contest|gym)/(\d+)/problem/([^/]+)',
16
+ r'https?://(?:.*\.)?codeforces.(?:com|ml|es)/problemset/problem/(\d+)/([^/]+)',
17
+ (
18
+ r'https?://(?:.*\.)?codeforces.(?:com|ml|es)/group/([^/]+)/contest/(\d+)/problem/([^/]+)',
19
+ _add_underscores,
20
+ ),
21
+ r'https?://(?:.*\.)?codeforces.(?:com|ml|es)/problemset/(gym)Problem/([^/]+)',
22
+ r'https?://(?:.*\.)?codeforces.(?:com|ml|es)/problemsets/(acm)sguru/problem/(?:\d+)/([^/]+)',
23
+ # TODO: add EDU
24
+ ]
25
+
26
+
27
+ def _compiled_pattern(pattern):
28
+ if isinstance(pattern, tuple):
29
+ return (re.compile(pattern[0]), pattern[1])
30
+ return re.compile(pattern)
31
+
32
+
33
+ _COMPILED_PATTERNS = [_compiled_pattern(pattern) for pattern in _PATTERNS]
34
+
35
+
36
+ def get_code_tuple(url: str) -> Optional[List[str]]:
37
+ for pattern_obj in _COMPILED_PATTERNS:
38
+ if isinstance(pattern_obj, tuple):
39
+ pattern, extract = pattern_obj
40
+ else:
41
+ pattern = pattern_obj
42
+ extract = lambda x: x # noqa: E731
43
+
44
+ if match := pattern.match(url):
45
+ return extract(list(match.groups()))
46
+ return None
47
+
48
+
49
+ class CodeforcesProvider(ProviderInterface):
50
+ def should_handle(self, url: str) -> bool:
51
+ return 'codeforces.com/' in url
52
+
53
+ def should_simplify_contest_problems(self) -> bool:
54
+ return True
55
+
56
+ def get_problem_code_within_contest(self, problem: Problem) -> str:
57
+ return self.get_aliases(problem)[-1]
58
+
59
+ def get_code(self, problem: Problem) -> str:
60
+ code_tuple = get_code_tuple(problem.url)
61
+ if not code_tuple:
62
+ return super().get_code(problem)
63
+ return ''.join(code_tuple)
64
+
65
+ def get_aliases(self, problem: Problem) -> List[str]:
66
+ code_tuple = get_code_tuple(problem.url)
67
+ if not code_tuple:
68
+ return super().get_aliases(problem)
69
+
70
+ aliases = []
71
+ for i in range(len(code_tuple)):
72
+ aliases.append(''.join(code_tuple[i:]))
73
+ return aliases
@@ -0,0 +1,26 @@
1
+ import abc
2
+ from typing import List
3
+
4
+ from rbx.schema import Problem
5
+
6
+
7
+ class ProviderInterface(abc.ABC):
8
+ @abc.abstractmethod
9
+ def should_handle(self, url: str) -> bool:
10
+ pass
11
+
12
+ def is_contest(self, problems: List[Problem]) -> bool:
13
+ batches = set(problem.batch.id for problem in problems)
14
+ return len(batches) == 1
15
+
16
+ def should_simplify_contest_problems(self) -> bool:
17
+ return False
18
+
19
+ def get_problem_code_within_contest(self, problem: Problem) -> str:
20
+ return self.get_code(problem)
21
+
22
+ def get_code(self, problem: Problem) -> str:
23
+ return problem.name
24
+
25
+ def get_aliases(self, problem: Problem) -> List[str]:
26
+ return []
@@ -0,0 +1,20 @@
1
+ #include "testlib.h"
2
+
3
+ using namespace std;
4
+
5
+ int main(int argc, char *argv[]) {
6
+ setName("custom checker");
7
+ registerTestlibCmd(argc, argv);
8
+
9
+ quitf(_wa, "wrong answer");
10
+ quitf(_pe, "presentation error");
11
+ quitf(_ok, "ok");
12
+
13
+ inf, ouf, ans;
14
+
15
+ inf.readInt();
16
+ inf.readInts(5);
17
+ inf.readWord();
18
+ inf.readDouble();
19
+ inf.readLong();
20
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "defaultLanguage": "exinc",
3
+ "editor": "vim",
4
+ "languages": {
5
+ "c++17": {
6
+ "template": "template.cpp",
7
+ "file": "%{problem-code}.cpp",
8
+ "preprocess": [
9
+ "g++ \"%{file}\" -std=c++17 -fdiagnostics-color=always"
10
+ ],
11
+ "exec": "./a.out",
12
+ "artifacts": {
13
+ "a.out": {
14
+ "executable": true
15
+ }
16
+ },
17
+ "submitor": "c++17"
18
+ },
19
+ "exinc": {
20
+ "template": "template.cpp",
21
+ "file": "%{problem-code}.cpp",
22
+ "submitFile": "%{problem-code}.pre.cpp",
23
+ "preprocess": [
24
+ "exinc -i \"%{file}\" -o \"%{submit-file}\" -c"
25
+ ],
26
+ "exec": "./a.out",
27
+ "artifacts": {
28
+ "a.out": {
29
+ "executable": true
30
+ }
31
+ },
32
+ "submitor": "c++17"
33
+ }
34
+ },
35
+ "submitor": {
36
+ "c++17": {
37
+ "codeforces": {
38
+ "typeid": 54
39
+ }
40
+ }
41
+ },
42
+ "credentials": {
43
+ "codeforces": {
44
+ "handle": "",
45
+ "password": ""
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,37 @@
1
+ ---
2
+ sandbox: "stupid"
3
+ defaultCompilation:
4
+ sandbox:
5
+ maxProcesses: 1000
6
+ timeLimit: 10000 # 10 seconds
7
+ wallTimeLimit: 10000 # 10 seconds
8
+ memoryLimit: 1024 # 1gb
9
+ preserveEnv: true
10
+ mirrorDirs:
11
+ - "/etc"
12
+ - "/usr"
13
+ defaultExecution:
14
+ sandbox:
15
+ # Useful for checkers, validators, etc.
16
+ timeLimit: 10000 # 10 seconds
17
+ wallTimeLimit: 10000 # 10 seconds
18
+ memoryLimit: 1024 # 1gb
19
+ languages:
20
+ - name: "cpp"
21
+ readable_name: "C++17"
22
+ extension: "cpp"
23
+ compilation:
24
+ commands:
25
+ - "g++ -std=c++17 -O2 -o {executable} {compilable}"
26
+ execution:
27
+ command: "./{executable}"
28
+ fileMapping:
29
+ compilable: "compilable.cpp"
30
+ - name: "py"
31
+ readable_name: "Python3"
32
+ extension: "py"
33
+ execution:
34
+ command: "python3 {executable}"
35
+ fileMapping:
36
+ executable: "executable.py"
37
+
@@ -0,0 +1,37 @@
1
+ ---
2
+ sandbox: "isolate"
3
+ defaultCompilation:
4
+ sandbox:
5
+ maxProcesses: null
6
+ timeLimit: null # 10 seconds
7
+ wallTimeLimit: null # 10 seconds
8
+ memoryLimit: null # 1gb
9
+ preserveEnv: true
10
+ mirrorDirs:
11
+ - "/etc"
12
+ - "/usr"
13
+ defaultExecution:
14
+ sandbox:
15
+ # Useful for checkers, validators, etc.
16
+ timeLimit: 10000 # 10 seconds
17
+ wallTimeLimit: 10000 # 10 seconds
18
+ memoryLimit: 1024 # 1gb
19
+ languages:
20
+ - name: "cpp"
21
+ readable_name: "C++17"
22
+ extension: "cpp"
23
+ compilation:
24
+ commands:
25
+ - "/usr/bin/g++ -std=c++17 -O2 -o {executable} {compilable}"
26
+ execution:
27
+ command: "./{executable}"
28
+ fileMapping:
29
+ compilable: "compilable.cpp"
30
+ - name: "py"
31
+ readable_name: "Python3"
32
+ extension: "py"
33
+ execution:
34
+ command: "/usr/bin/python3 {executable}"
35
+ fileMapping:
36
+ executable: "executable.py"
37
+
@@ -0,0 +1,43 @@
1
+ ### START OF CHECKER COMPILATION
2
+ CHECKER_PATH="checker.cpp"
3
+ CHECKER_OUT="../checker.exe"
4
+
5
+ # find compiler
6
+ cc=`which g++`
7
+ [ -x "$cc" ] || cc=/usr/bin/g++
8
+ if [ ! -x "$cc" ]; then
9
+ echo "$cc not found or it's not executable"
10
+ exit 47
11
+ fi
12
+ read -r -d '' TestlibContent <<"EOF"
13
+ {{testlib_content}}
14
+ EOF
15
+
16
+ read -r -d '' CheckerContent <<"EOF"
17
+ {{checker_content}}
18
+ EOF
19
+
20
+ printf "%s" "${TestlibContent}" > testlib.h
21
+ printf "%s" "${CheckerContent}" > $CHECKER_PATH
22
+
23
+ checker_hash=($(md5sum $CHECKER_PATH))
24
+ checker_cache="/tmp/boca-chk-${checker_hash}"
25
+
26
+ echo "Polygon checker hash: $checker_hash"
27
+ if [ -f "$checker_cache" ]; then
28
+ echo "Recovering polygon checker from cache: $checker_cache"
29
+ cp "$checker_cache" $CHECKER_OUT -f
30
+ else
31
+ echo "Compiling polygon checker: $CHECKER_PATH"
32
+ $cc {{stdcpp}} -static -O2 -lm $CHECKER_PATH -o $CHECKER_OUT
33
+
34
+ if [ $? -ne 0 ]; then
35
+ echo "Checker could not be compiled"
36
+ exit 47
37
+ fi
38
+
39
+ cp $CHECKER_OUT "$checker_cache" -f
40
+ fi
41
+
42
+ chmod 0755 $CHECKER_OUT
43
+ ### END OF CHECKER COMPILATION
@@ -0,0 +1,53 @@
1
+ #!/bin/bash
2
+ # ////////////////////////////////////////////////////////////////////////////////
3
+ # //BOCA Online Contest Administrator
4
+ # // Copyright (C) 2003-2012 by BOCA Development Team (bocasystem@gmail.com)
5
+ # //
6
+ # // This program is free software: you can redistribute it and/or modify
7
+ # // it under the terms of the GNU General Public License as published by
8
+ # // the Free Software Foundation, either version 3 of the License, or
9
+ # // (at your option) any later version.
10
+ # //
11
+ # // This program is distributed in the hope that it will be useful,
12
+ # // but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # // GNU General Public License for more details.
15
+ # // You should have received a copy of the GNU General Public License
16
+ # // along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ # ////////////////////////////////////////////////////////////////////////////////
18
+ # // Last modified 21/jul/2012 by cassio@ime.usp.br
19
+ #
20
+ # This script receives:
21
+ # $1 team_output
22
+ # $2 sol_output
23
+ # $3 problem_input (might be used by some specific checkers, here it is not)
24
+ #
25
+ # BOCA reads the last line of the standard output
26
+ # and pass it to judges
27
+ #
28
+ if [ ! -r "$1" -o ! -r "$2" ]; then
29
+ echo "Parameter problem"
30
+ exit 43
31
+ fi
32
+
33
+ # Next lines of this script just compares team_output and sol_output,
34
+ # although it is possible to change them to more complex evaluations.
35
+ output=`../checker.exe $3 $1 $2 2>&1 >/dev/null`
36
+ EC=$?
37
+
38
+ echo "checker exitcode = $EC"
39
+ echo "$output"
40
+
41
+ if [ $EC -eq 0 ]; then
42
+ echo "checker found no differences"
43
+ exit 4
44
+ elif [ $EC -eq 1 ]; then
45
+ echo "checker found differences"
46
+ exit 6
47
+ elif [ $EC -eq 2 ]; then
48
+ echo "checker failed"
49
+ exit 5
50
+ elif [ $EC -ne 3 ]; then
51
+ echo "unkown compare error $EC"
52
+ exit 43
53
+ fi