General
This page introduces some common states/objects/functions, usage, and precautions for Testlib checker/interactor/validator. Please read this page completely before reading other pages.
Common States
| Result | Testlib Alias | Meaning |
|---|---|---|
| Ok | _ok |
Correct answer. |
| Wrong Answer | _wa |
Wrong answer. |
| Presentation Error | _pe |
Presentation error. Note that many OJs, including Codeforces, do not distinguish between PE and WA. |
| Partially Correct | _pc(score) |
Partially correct. Only for test cases with partial scores, where score is a positive integer from \(0\) (no points) to \(100\) (maximum possible score). (quitf+_pc is only for compatibility with old pascal-testlib; if you want to output partial scores, it is recommended to use quitp1) |
| Fail | _fail |
In validator: indicates the input is invalid and fails validation. In checker: indicates an internal program error, incorrect standard output, or contestant output being better than the standard output, requiring attention from judges/problem setters (i.e., a problem bug). |
Usually, the program's return value indicates the result, but there are other methods: creating an output XML file, outputting information to stdout, or other locations... These are all done via the quitf function in the function table below.
Common Objects
| Object | Meaning |
|---|---|
inf |
Input file stream |
ouf |
Contestant output stream |
ans |
Reference output stream |
Common Functions
Non-member functions:
| Call | Meaning |
|---|---|
void registerTestlibCmd(int argc, char* argv[]) |
Register the program as a checker |
void registerInteraction(int argc, char* argv[]) |
Register the program as an interactor |
void registerValidation()/void registerValidation(int argc, char* argv[]) |
Register the program as a validator |
void registerGen(int argc, char* argv[], int randomGeneratorVersion) |
Register the program as a generatorrandomGeneratorVersion is recommended to be 1 |
void quit(TResult verdict, string message)/void quitf(TResult verdict, string message, ...) |
End the program, return verdict, and output message |
void quitif(bool condition, TResult verdict, string message, ...) |
If condition is true, call quitf(verdict, message, ...) |
void quitp(F points, string message, ...) |
End the program and return partial scores. For most OJs (e.g., Luogu, UOJ), points requires a real number in \([0,1]\), representing the score percentage. Some OJs (e.g., Lyrio) require points to be a real number in \([0,100]\) (the OJ automatically discards the decimal part), representing the score out of 100 for the test case. |
Stream member functions:
| Call | Meaning |
|---|---|
char readChar() |
Read a character |
char readChar(char c) |
Read a character, must be c |
char readSpace() |
Equivalent to readChar(' ') |
string readToken()/string readWord() |
Read a string until a whitespace character (space, tab, EOLN, etc.) |
string readToken(string regex)/string readWord(string regex) |
Read a string, must match regex |
long long readLong() |
Read a 64-bit integer |
long long readLong(long long L, long long R) |
Read a 64-bit integer, must be in \([L,R]\) |
vector<long long> readLongs(int n, long long L, long long R) |
Read \(N\) 64-bit integers, all must be in \([L,R]\) |
int readInt()/int readInteger() |
Read a 32-bit integer |
int readInt(int L, int R)/int readInteger(L, R) |
Read a 32-bit integer, must be in \([L,R]\) |
vector<int> readInts(int n, int L, int R)/vector<int> readIntegers(int n, int L, int R) |
Read \(N\) 32-bit integers, all must be in \([L,R]\) |
double readReal()/double readDouble() |
Read a double-precision floating-point number |
double readReal(double L, double R)/double readDouble(double L, double R) |
Read a double-precision floating-point number, must be in \([L,R]\) |
double readStrictReal(double L, double R, int minPrecision, int maxPrecision)/double readStrictDouble(double L, double R, int minPrecision, int maxPrecision) |
Read a double-precision floating-point number, must be in \([L,R]\), decimal places must be in \([minPrecision,maxPrecision]\), and must not use non-standard formats like exponential notation |
string readString()/string readLine() |
Read a line (including the newline character) and move the stream pointer to the beginning of the next line |
string readString(string regex)/string readLine(string regex) |
Read a line, must match regex |
void readEoln() |
Read EOLN (reads LF on Linux, CR LF on Windows) |
void readEof() |
Read EOF |
void quit(TResult verdict, string message)/void quitf(TResult verdict, string message, ...) |
End the program; if Stream is ouf, return verdict, otherwise return _fail; output message |
void quitif(bool condition, TResult verdict, string message, ...) |
If condition is true, call quitf(verdict, message, ...) |
To be continued...
Minimal Regular Expressions
Some of the input functions above allow the use of "minimal regular expressions," as shown below:
- Character sets. For example,
[a-z]represents all lowercase English letters,[^a-z]represents any character except lowercase English letters. - Ranges. For example,
[a-z]{1,5}represents a string of length between \([1,5]\) containing only lowercase English letters. - "Or" identifier. For example,
mike|johnrepresents eithermikeorjohn. - "Optional" identifier. For example,
-?[1-9][0-9]{0,3}represents non-zero integers in the range \([-9999,9999]\) (note the optional minus sign). - "Repeat" identifier. For example,
[0-9]*represents zero or more digits,[0-9]+represents one or more digits. - Note that the regular expressions here are "greedy" ("repeat" will match as much as possible). For example,
[0-9]?1will not match1(because[0-9]?matches the1, leaving the remaining1in the template unmatched).
Include testlib.h First
Make sure testlib.h is the first header you include. Testlib will rewrite/disable (via name conflicts) some random-related functions (e.g., random()), ensuring that random results are environment-independent. This is very important for generators, as explained in detail on the generator page.
Use Item Aliases
It is recommended to add an extra string parameter as the alias for the currently read item to the constrained calls of readInt/readInteger/readLong/readDouble/readWord/readToken/readString/readLine, etc., to make error messages more readable. For example, use inf.readInt(1, 100, "n") instead of inf.readInt(1, 100). The error message will then be FAIL Integer parameter [name=n] equals to 0, violates the range [1, 100].
Use ensuref/ensure()
These two functions are used to check whether a condition holds (similar to assert()). For example, to check \(x_i \neq y_i\), we can use
1 | |
You can also use C-style placeholders, such as
1 2 3 | |
There is a simplified version ensure(). You can directly use ensure(x > y) without adding explanatory content (and it does not support adding explanatory content). If the condition is not met, the error will be FAIL Condition failed: "x > y". In many cases, such errors without additional explanation are not user-friendly, so we usually use ensuref() with explanatory content instead of ensure().
Warning
Note the difference between global and member ensuref/ensure().
The global functions ::ensuref/ensure() are mostly used in generators and validators. If the check fails, they uniformly return _fail.
The member functions InStream::ensuref/ensure() are generally used to check whether contestant and reference outputs are valid. When InStream is ouf, they return _wa; when it is inf (generally, input data should not be checked in the checker; this should be done in the validator) or ans, they return _fail. For details, see Checker - Writing the readAns function.
This article is mainly translated and synthesized from the Testlib - Codeforces series. The GitHub repository for testlib.h is MikeMirzayanov/testlib.
本页面最近更新:,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:OI-wiki
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用