If you have written some tasks, and have prepared test cases, you will probably experience the terrible feeling that some test cases may be invalid (meaning it does not agree with the constraints in problem statement): upper bound can be violated, your graph not satisfied connectivity requirements or is not at tree. It is a reasonable to feel that way. Even experienced problem setters make mistakes sometimes (for example, in the pretigious ACM ICPC World final 2007).
The validator in testlib is a good tool to help you prevent such mistakes. It is very easy to use.
Example
Following is the validator of validator, which I used in a problem I prepared: 100541A - Stock Market:
#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;
int main() {
registerValidation();
int test = inf.readInt(1, 10);
inf.readEoln();
while (test--) {
int n = inf.readInt(1, 100);
inf.readChar(' ');
int w = inf.readInt(1, 1000000);
inf.readEoln();
for(int i = 0; i < n; ++i) {
inf.readInt(1, 1000);
if (i < n-1) inf.readChar(' ');
else inf.readEoln();
}
}
inf.readEof();
return 0;
}
More examples can be found at the Github repo
Available methods:
The first line of your code should be registerValidation()
which does some magic in the background, so that you can use the necessary methods.
Most methods for validators start with prefix "read" and it does the same thing: moves input stream pointer to next suitable place after reading something. It also detect violations (input does not match what you are trying to read), and then throw error.
Note: Validator is strict. It cares about correct placing of spaces. For exmple, when you're trying to read an integer and the next character is a space (and then an integer), the validator will throw error.
Following is full list of methods available:
Method | What it does |
---|---|
registerValidation() | This method must be called at the beginning of your code in order to use validator. |
readChar() | Returns current character and moves pointer one character forward. |
readChar(char c) | Same as readChar() but ensure that the readCharacter is 'c'. |
readSpace() | Same as readChar(' '). |
unreadChar(char c) | Puts back character c to input stream. |
readToken() | Reads a new token. |
readToken(string regex) | Same as readToken() but ensure that it matches given regex. |
readLong() | Read a long (long long in C/C++ and long in Java) |
readLong(int L, int R) | Same as readLong() but ensure that the value is in range [L, R] (inclusively) |
readInt(), readInteger() | Read an integer (int type in both Java and C/C++) |
readInt(int L, int R), readInteger(L, R) | Same as readInt() but ensure that the value is in range [L, R] (inclusively) |
readReal(), readDouble() | Read a real / double. |
readReal(double L, double R), readDouble(double L, double R) | Same as readReal(), readDouble() but ensure that the value is in range [L, R]. |
readStrictReal(double L, double R, int minPrecision, int maxPrecision), readStrictDouble(double L, double R, int minPrecision, int maxPrecision) | Same as readReal(L, R), readDouble(L, R), but additionally ensure that the number of digits after decimal point is between [minPrecision, maxPrecision]. |
readEoln() | Read EOLN or fails. Note that this method magically works on both Windows and Linux. On Windows it reads #13#10 and on Linux it reads #10. |
readEof() | Read EOF or fails. |
[more content to be added]