diff --git a/generate_test.py b/generate_test.py index 49747224a..a0701db34 100755 --- a/generate_test.py +++ b/generate_test.py @@ -196,6 +196,13 @@ def test_call_from_outside(self): chdir(str(cwd)) +class TestAllowRE(unittest.TestCase): + def test_allow_re(self): + with create_test_dir('allow_re') as test_dir: + proc = run( + ['./generate.py', str(Path(test_dir) / 'allow_re/info.toml'), '--test']) + self.assertEqual(proc.returncode, 0) + class TestAllowTLE(unittest.TestCase): def test_allow_tle(self): with create_test_dir('allow_tle') as test_dir: diff --git a/problem.py b/problem.py index 358856f3f..80347a003 100644 --- a/problem.py +++ b/problem.py @@ -395,17 +395,22 @@ def judge(self, src: Path, config: dict): logging_result(result, start, end, '{} : {}'.format(case, checker_output.decode('utf-8'))) + allow_status = set() + allow_status.add('AC') + if config.get('wrong', False): + allow_status.update(['WA', 'RE', 'TLE']) + if config.get('allow_tle', False): + allow_status.add('TLE') + if config.get('allow_re', False): + allow_status.add('RE') + + if len(results - allow_status) != 0: + logger.error('unexpected status was appeared: {} (allowed {})'.format(results, allow_status)) + if config.get('wrong', False): if results == {'AC'}: logger.error('wrong solution got accept: {}'.format(src)) exit(1) - else: - if 'WA' in results or 'RE' in results: - logger.error('correct solution got wa/re: {}'.format(src)) - exit(1) - if not config.get('allow_tle', False) and 'TLE' in results: - logger.error('fast solution got tle: {}'.format(src)) - exit(1) def calc_hashes(self) -> MutableMapping[str, str]: hashes: MutableMapping[str, str] = dict() diff --git a/test/allow_re/checker.cpp b/test/allow_re/checker.cpp new file mode 100644 index 000000000..6a66d5330 --- /dev/null +++ b/test/allow_re/checker.cpp @@ -0,0 +1,62 @@ +// https://github.com/MikeMirzayanov/testlib/blob/master/checkers/wcmp.cpp + +// The MIT License (MIT) + +// Copyright (c) 2015 Mike Mirzayanov + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include "testlib.h" + +using namespace std; + +int main(int argc, char * argv[]) +{ + setName("compare sequences of tokens"); + registerTestlibCmd(argc, argv); + + int n = 0; + string j, p; + + while (!ans.seekEof() && !ouf.seekEof()) + { + n++; + + ans.readWordTo(j); + ouf.readWordTo(p); + + if (j != p) + quitf(_wa, "%d%s words differ - expected: '%s', found: '%s'", n, englishEnding(n).c_str(), compress(j).c_str(), compress(p).c_str()); + } + + if (ans.seekEof() && ouf.seekEof()) + { + if (n == 1) + quitf(_ok, "\"%s\"", compress(j).c_str()); + else + quitf(_ok, "%d tokens", n); + } + else + { + if (ans.seekEof()) + quitf(_wa, "Participant output contains extra tokens"); + else + quitf(_wa, "Unexpected EOF in the participants output"); + } +} diff --git a/test/allow_re/gen/example_00.in b/test/allow_re/gen/example_00.in new file mode 100644 index 000000000..fbba5e53e --- /dev/null +++ b/test/allow_re/gen/example_00.in @@ -0,0 +1 @@ +1234 5678 diff --git a/test/allow_re/gen/example_01.in b/test/allow_re/gen/example_01.in new file mode 100644 index 000000000..caf89741f --- /dev/null +++ b/test/allow_re/gen/example_01.in @@ -0,0 +1 @@ +1000000000 1000000000 diff --git a/test/allow_re/hash.json b/test/allow_re/hash.json new file mode 100644 index 000000000..ffb838113 --- /dev/null +++ b/test/allow_re/hash.json @@ -0,0 +1,6 @@ +{ + "example_00.in": "346a847f5875beb74d494de0680a81fc2ff840b12f79de30dc7ef3a798d23c28", + "example_00.out": "d6e0da7b83d84fac4d6a6bd11ad0b0e6ea72351748b4f6a277b9762d9d0eb159", + "example_01.in": "0073cf03577a737756752129cc3abcb9f5a4069c705321ee2115574cc31c59f9", + "example_01.out": "6f2264250160ee91b20af64f30128e3787fcf641f1c504f7ac752597e7d2cc09" +} \ No newline at end of file diff --git a/test/allow_re/info.toml b/test/allow_re/info.toml new file mode 100644 index 000000000..b54be325a --- /dev/null +++ b/test/allow_re/info.toml @@ -0,0 +1,10 @@ +title = 'Simple AplusB' +timelimit = 2.0 + +[[tests]] + name = "example.in" + number = 2 + +[[solutions]] + name = "naive.cpp" + allow_re = true \ No newline at end of file diff --git a/test/allow_re/sol/correct.cpp b/test/allow_re/sol/correct.cpp new file mode 100644 index 000000000..897b424f1 --- /dev/null +++ b/test/allow_re/sol/correct.cpp @@ -0,0 +1,18 @@ +#include +#include + +using namespace std; +using uint = unsigned int; +using ll = long long; +using ull = unsigned long long; +constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); } +template using V = vector; +template using VV = V>; + +int main() { + + int a, b; + scanf("%d %d", &a, &b); + printf("%d\n", a + b); + return 0; +} diff --git a/test/allow_re/sol/naive.cpp b/test/allow_re/sol/naive.cpp new file mode 100644 index 000000000..cfc2230de --- /dev/null +++ b/test/allow_re/sol/naive.cpp @@ -0,0 +1,19 @@ +#include +#include +#include + +using namespace std; +using uint = unsigned int; +using ll = long long; +using ull = unsigned long long; +constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); } +template using V = vector; +template using VV = V>; + +int main() { + int a, b; + scanf("%d %d", &a, &b); + assert(a <= 1000 && b <= 1000); + printf("%d\n", a + b); + return 0; +} diff --git a/test/allow_re/task.md b/test/allow_re/task.md new file mode 100644 index 000000000..366165f4e --- /dev/null +++ b/test/allow_re/task.md @@ -0,0 +1,25 @@ +## @{keyword.statement} +整数 $a, b$ が与えられます。 $a + b$ を出力してください。 + +## @{keyword.constraints} + +- $0 \leq a, b \leq 10^9$ + + +## @{keyword.input} + +``` +$A$ $B$ +``` + +## @{keyword.output} + +``` +$A + B$ +``` + +## @{keyword.sample} + +@{example.example_00} + +@{example.example_01} diff --git a/test/allow_re/verifier.cpp b/test/allow_re/verifier.cpp new file mode 100644 index 000000000..09e8cb5e4 --- /dev/null +++ b/test/allow_re/verifier.cpp @@ -0,0 +1,12 @@ +#include "testlib.h" + +int main() { + registerValidation(); + + inf.readInt(0, 1'000'000'000); // a + inf.readSpace(); + inf.readInt(0, 1'000'000'000); // b + inf.readChar('\n'); + inf.readEof(); + return 0; +}