Skip to content

Validator

This page briefly introduces the concept and usage of validators.

Overview

A validator (Chinese: 校验器) is used to check the validity of generated data. When creating test data for a problem and worrying about potential invalidity (e.g., overflow, graph not connected, not a tree, etc.), problem setters often rely on validators for verification.1

Because Codeforces supports hacking, all problems on Codeforces must include a validator. The same applies to UOJ. Polygon has built-in support for validators.

Usage

Simply run ./val in the command line. Data is input via stdin. To read from a file, use ./val < a.in.

If the data is valid, nothing will be output and the program will return 0; otherwise, an error message will be printed and a non-zero value will be returned.

Tips

  • When writing a validator, do not make any assumptions about the data being validated, as it may contain anything. Therefore, the problem setter must check for various invalid cases (using Testlib greatly simplifies this process).
    • For example, when inputting a tree with \(n\) nodes, the main tasks are to verify that \(n\) is within the allowed range and that the input indeed forms a tree. However, it is crucial not to skip validating the range of edge endpoints after checking \(n\), as this could cause the validator to RE.
    • Even if it doesn't cause RE, skipping validation is not advisable, as it may lead to incorrect error messages. In the above example, without proper validation, the error might be "not a tree," while the correct error should be "edge start/end point not in \([1,n]\)."
  • Do not make any assumptions about how contestants read input. Therefore, it must be ensured that all data passing validation strictly adheres to the input format.
    • For instance, contestants might read numbers character by character, with only one space between numbers. Thus, when writing a validator, every whitespace character (like spaces and newlines) in the data must be explicitly read.
  • Do not forget inf.readEof() at the end.
  • If the problem allows hacking (or the validator's error messages will be visible to others), make the error messages as friendly as possible.
    • Use "item aliases" when reading variables.
    • When the validation expression is not easily understandable, use ensuref instead of ensure.

Example

Below is the validator for CF Gym 100541A - Stock Market:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "testlib.h"

int main(int argc, char* argv[]) {
  registerValidation(argc, argv);
  int testCount = inf.readInt(1, 10, "testCount");
  inf.readEoln();

  for (int i = 0; i < testCount; i++) {
    int n = inf.readInt(1, 100, "n");
    inf.readSpace();
    inf.readInt(1, 1000000, "w");
    inf.readEoln();

    for (int i = 0; i < n; ++i) {
      inf.readInt(1, 1000, "p_i");
      if (i < n - 1) inf.readSpace();
    }
    inf.readEoln();
  }

  inf.readEof();
}

References and Notes