テストケースバリデーションの書き方
Latest Author mai /Date 2021-06-29 22:25:37 / Views 2198テストケースバリデーションの書き方
テストケースバリデーションとは
入力制約を満たさないテストケースが含まれているかどうか、プログラムを利用して自動的に判定する機能です。
バリデータの書き方
- 競技プログラミング同様、標準入力からテストケースが与えられます。
- スペシャルジャッジの書き方同様、そのテストケースに不備があるならば、0以外の終了コードで終了します。不備がなければ、0の終了コードで終了します。
- 標準エラー出力に情報を出力すると、後で確認出来ます。
- C++の場合、testlib が使えます。testlibを使うことで、余分な半角スペースや改行の不備等を簡単に発見できます。
- コンパイルエラーが表示されないので、オンライン実行を使うと良いです。
実装例
以下のような入力制約を考えます。
$N$ $M_1$ $a_{1,1}$ $\ldots$ $a_{1,M_1}$ $\vdots$ $M_N$ $a_{N,1}$ $\ldots$ $a_{N,M_N}$
$1 \le N \le 4000$
$1 \le M_i \le 4000$
$1 \le a_{i,j} \le 4000$
$\sum_{i=1\ldots N}{M_i} \le 4000$
すべて整数
#include <bits/stdc++.h>
#include "testlib.h"
using namespace std;
using ll = long long;
int main(int argc, char** argv) {
registerValidation(argc, argv);
ll n = inf.readLong(1ll, 4000ll);
inf.readEoln();
ll mtotal = 0;
for (ll i = 0; i < n; ++i) {
ll m = inf.readLong(1ll, 4000ll);
mtotal += m;
for (ll j = 0; j < m; ++j) {
inf.readSpace();
inf.readLong(1ll, 4000ll);
}
inf.readEoln();
}
assert(mtotal <= 4000);
inf.readEof();
return 0;
}
正規表現(Ruby)を使った実装例です
line1 = gets.chomp!
abort "line1" unless line1 =~ /^\d+$/
n = line1.to_i
abort "n" unless 1 <= n && n <= 4000
mtotal = 0
n.times do |i|
linei = gets.chomp!
abort "line#{i}" unless linei =~ /^\d+( \d+)*$/
m, *aa = linei.split.map(&:to_i)
abort "m#{i}" unless 1 <= m && m <= 4000
mtotal += m
aa.each do |a|
abort "a#{i}" unless 1 <= a && a <= 4000
end
abort "aa.size" unless aa.size == m
end
abort "mtotal" unless mtotal <= 4000
abort "too many lines" unless !gets