Custom checkers


Hướng dẫn viết checker dùng testlib từ anh Phạm Văn Hạnh

Một số bài tập có thể có nhiều output đúng, vì vậy đôi lúc ta cần phải viết checker để kiểm tra xem output có đúng hay chưa.

1. Checker mặc định

VNOJ có hỗ trợ các checker mặc định của DMOJ, các bạn có thể xem ở đây.

2. Custom Checker (C++)

VNOJ cũng hỗ trợ các checker được viết bằng testlib.htestlib_themis_cms.h của anh Phạm Văn Hạnh, về checker này, các bạn xem hướng dẫn ở đầu trang.

Ví dụ

Chương trình sau dùng để chấm bài toán: Cho ~n~ là một số nguyên dương. In ra hai số tự nhiên ~a~, ~b~ sao cho ~a + b = n~.

Nếu in ra ~a + b = n~ và ~a, b \ge 0~ thì được ~100\%~ số điểm, nếu ~a + b = n~ nhưng một trong 2 số ~a, b~ âm thì được ~50\%~ số điểm.

Đây là checker sử dụng testlib.h cho bài toán trên:

#include "testlib.h"

using namespace std;

int main(int argc, char* argv[]) {
    registerTestlibCmd(argc, argv);

    int n = inf.readInt();
    int a = ouf.readInt();
    int b = ouf.readInt();
    ensuref(a + b == n, "%d + %d != %d", a, b, n);
    if (a < 0) {
        quitp(0.5, "a = %d < 0", a);
    }
    if (b < 0) {
        quitp(0.5, "b = %d < 0", b);
    }
    quitf(_ok, "%d + %d = %d", a, b, n);
}

3. Một số lỗi thường gặp

error: ‘gets’ was not declared in this scope; did you mean ‘getw’?

Lỗi này thường xảy ra với các checker Themis cũ có sử dụng hàm gets để đọc đường dẫn đến thư mục test:

gets(TestPath);

Cách khắc phục là đổi sang cin.getline như sau:

cin.getline(TestPath, sizeof(TestPath));
checker exited with Segmentation fault with feedback segmentation fault

Tương tự lỗi trên, lỗi này thường xảy ra với các checker Themis cũ sử dụng đường dẫn tệp tin theo kiểu của Windows:

sprintf(fINP, "%s\\%s", TestPath, inName);

Windows dùng dấu \ để phân tách các thành phần, trong khi Unix dùng dấu /.

Cách khắc phục bỏ hẳn dấu \. VNOJ đảm bảo các đường dẫn thư mục truyền vào checker được kết thúc bằng dấu /:

sprintf(fINP, "%s%s", TestPath, inName);