Чекеры
Чекер — это программа, которая проверяет вывод кода участника и сообщает результат системе в виде кодов возврата. Чекер помогает автоматизировать проверку задач и избежать лишней работы при выставлении баллов.
Прочтите условия задачи и выделите те, которые необходимо проверить чекером. Часто задачи по программированию предполагают однозначный вывод и не требуют сложных проверок, поэтому их можно проверить стандартными чекерами.
Если вы не нашли стандартный чекер, который подходит вашей задаче, то создайте собственный.
Стандартный чекер
Чтобы добавить стандартный чекер в свою задачу:
1. Откройте задачу и в меню слева выберите Настройки чекера.
2. Выберите тип чекера STANDARD_CHECKER.
3. В поле ID чекера выберите название стандартного чекера.
В Контесте используются стандартные проверяющие программы и собственные:
Стандартные проверяющие программы
- fcmp — сравнивает файлы построчно, игнорирует пробелы на концах строк.
- hcmp — сравнивает два целых числа со знаком любой длины.
- icmp — сравнивает два 32-битных целых числа со знаком.
- lcmp — сравнивает файлы в виде последовательностей токенов в строках.
- ncmp — сравнивает последовательности 32-битных целых чисел со знаком.
- rncmp — сравнивает два вещественных числа с максимальной абсолютной погрешностью 1,5 X 10-5.
- rncmpN — сравнивает два вещественных числа с максимальной абсолютной погрешностью 10-N.
- wcmp — сравнивает файлы, игнорируя лишние пробелы и переносы между словами.
- yesno — сравнивает два ответа
YESилиNOнезависимо от регистра. - cmp_file — построчно сравнивает два файла. Выбран по умолчанию.
- cmp_file_nospace — сравнивает два файла с игнорированием повторяющихся пробелов.
- cmp_bytes — побайтово сравнивает два файла.
- cmp_int — сравнивает два 32-битных целых числа со знаком.
- cmp_int_seq — сравнивает две последовательности 32-битных целых чисел со знаком.
- cmp_long_long — сравнивает два 64-битных целых числа со знаком.
- cmp_long_long_seq — сравнивает две последовательности 64-битных целых чисел со знаком.
- cmp_unsigned_int — сравнивает два 32-битных целых числа без знака.
- cmp_unsigned_int_seq — сравнивает две последовательности 32-битных целых чисел без знака.
- cmp_unsigned_long_long — сравнивает два 64-битных целых числа без знака.
- cmp_unsigned_long_long_seq — сравнивает две последовательности 64-битных целых чисел без знака.
- cmp_huge_int — сравнивает два целых числа произвольного размера.
- cmp_double — сравнивает два вещественных числа двойной точности с заданной максимальной ошибкой.
- сmp_double_seq — сравнивает две последовательности вещественных чисел двойной точности с заданной максимальной ошибкой.
- cmp_long_double — сравнивает два вещественных числа расширенной точности с заданной максимальной ошибкой.
- cmp_long_double_seq — сравнивает две последовательности вещественных чисел расширенной точности с заданной максимальной ошибкой.
- cmp_sexpr — сравнивает два S-выражения в синтаксисе языка Lisp.
- cmp_yesno — сравнивает два ответа
YESилиNOзависимо от регистра. - cmp_range — проверяет наличие ответа в указанном диапазоне с максимальной абсолютной погрешностью 10-8.
Проверяющие программы Контеста
- ok — всегда возвращает
ОК. Полезен для интерактивных и Make-задач. - rangencmp — проверяет наличие ответа в заданном интервале. В качестве правильного ответа принимает файл с двумя вещественными числами — минимальный и максимальный возможный ответ. В качестве ответа участника ожидается файл с одним вещественным числом.
- regexcmp — сравнивает ответ участника с регулярным выражением. В качестве правильного ответа принимается файл с регулярным выражением.
- anycmp — проверяет наличие ответа участника в указанных строках. В качестве правильного ответа принимается файл, в котором каждая строка является правильным вариантом ответа. В качестве ответа участника принимается файл с одной строкой.
4. Настройте чекер.
5. Справа внизу нажмите кнопку Сохранить.
Свой чекер
Чекер можно написать при помощи библиотеки testlib.h для С++ или на любом другом языке.
-
Создайте файл с решением задачи — с ним будет сравниваться ответ участника.
-
Получите содержимое:
- входных данных теста — находятся в переменной
inf; - вывода решения участника — в переменной
ouf; - правильного ответа — в переменной
ans.
Пример
Этот код получает доступ к файлам входных данных, решения и правильного ответа и сохраняет их в переменные:
#include "testlib.h" int main(int argc, char* argv[]) { // Функция инициализирует окружение чекера. registerTestlibCmd(argc, argv); // Функции считывают входные данные чекера, правильный ответ и // результат работы программы участника. int inf = inf.readInt(); int solution = ouf.readInt(); int answer = ans.readInt(); } - входных данных теста — находятся в переменной
-
Добавьте проверку решения.
Пример
// Функция проверяет, что ответ участника не равен правильному ответу. if (answer != solution) // Если ответ неверный, выводит информацию об ошибке quitf(_wa, "expected %d, found %d", answer, solution); -
Выставьте вердикт и баллы.
Чекер сообщает вердикт системе в коде ответа и может выставлять баллы, если включена опция Чекер выставляет баллы. Первое число из первой строки, выведенной чекером, используется как баллы за тест. Баллы выставляются только в случае вердикта
ОК.Воспользуйтесь функцией
quitp(score, message)для выставления баллов, гдеscore— это выставляемые баллы, аmessage— дополнительное сообщение, которое может быть показано участнику и содержать вердикт.Пример
Тест получит вердикт
OKи 10,42 балла:// Функция проверяет, что ответ участника равен правильному ответу. if (answer == solution) { // Если ответ верный, возвращает балл quitp(10.42, "OK"); } else { // Иначе возвращает вердикт WA quitf(_wa, "Expected: %d, found: %d", answer, solution); } -
Протестируйте чекер на каждом из возможных вариантов вывода.
-
Добавьте чекер в систему Контеста:
-
Откройте задачу и в меню слева выберите Настройки чекера.
-
Нажмите кнопку Скомпилировать чекер. В открывшемся окне выберите исходный код из файлов задачи либо загрузите его с устройства.
-
Выберите компилятор. Воспользуйтесь последними версиями GNU GCC для чекеров на C++. Во время компиляции в окружении файла будет доступна встроенная библиотека testlib.h, файл может к ней обращаться.
-
Выберите тип чекера TESTLIB_EXITCODE_CHECKER.
-
Нажмите кнопку Компилировать. Когда компиляция завершится, поля Тип чекера и Окружение заполнятся указанными в окне значениями, а внизу раздела Настройки чекера появится скомпилированный файл.
-
Справа внизу нажмите кнопку Сохранить.
-
Вы можете посмотреть пример чекера, который сравнивает answer и solution, ожидая в каждом из них по одному целому числу:
Пример чекера
#include "testlib.h"
using namespace std;
int main(int argc, char* argv[]) {
// Функция инициализирует окружение чекера.
registerTestlibCmd(argc, argv);
// Функции считывают правильный ответ и результат работы участника.
int answer = ans.readInt();
int solution = ouf.readInt();
// Функция проверяет, что ответ участника равен правильному ответу.
if (answer == solution) {
// Если ответ верный, возвращает балл
quitp(10.42, "OK");
} else {
// Иначе возвращает вердикт WA
quitf(_wa, "Expected: %d, found: %d", answer, solution);
}
}
Подробнее о том, как писать собственные чекеры, читайте в репозитории testlib.h (GitHub) и в блоге Чекеры, testlib.h и просто по теме (Codeforces).
-
Создайте файл с решением задачи — с ним будет сравниваться ответ участника.
-
Получите содержимое:
- файла входных данных теста — путь к нему находится в первом аргументе запуска чекера;
- файла вывода решения участника — во втором аргументе;
- файла с правильным ответом — в третьем аргументе.
Пример на Python
Этот код получает доступ к файлам входных данных, решения и правильного ответа и сохраняет их в переменные:
import sys # Получаем пути к файлам. testFile = sys.argv[1] solutionResultFile = sys.argv[2] answerFile = sys.argv[3] # Открываем файлы для чтения. tFile = open(testFile, mode="r") sFile = open(solutionResultFile, mode="r") aFile = open(answerFile, mode="r") # Преобразуем полученные значения в строки и записываем в переменные. t = tFile.readline().strip() a = aFile.readline().strip() s = sFile.readline().strip() -
Добавьте проверку решения.
Пример на Python
# Проверяем равенство значений переменных и сообщаем вердикт if (a == s): print('OK') else: print('WA') -
Выставьте вердикт и баллы.
Чекер сообщает вердикт системе в коде ответа и может выставлять баллы, если включена опция Чекер выставляет баллы. Первое число из первой строки, выведенной чекером, используется как баллы за тест. Баллы выставляются только в случае вердиктаОК.Коды вердиктов:
- 0 соответствует вердикту
ОК— ответ участника верен; - 1 соответствует вердикту
WA— ответ неверен; - 2 соответствует вердикту
PE— ответ не соответствует формату вывода.
Пример на Python
Тест получит вердикт PE:
sys.exit(2)Если включена опция Чекер выставляет баллы, тест получит 10,42 балла:
print('10.42 Not perfect') - 0 соответствует вердикту
-
Протестируйте чекер на каждом из возможных вариантов вывода.
-
Добавьте чекер в систему Контеста:
-
Откройте задачу и в меню слева выберите Настройки чекера.
-
Нажмите кнопку Скомпилировать чекер. В открывшемся окне выберите исходный код из файлов задачи либо загрузите его с устройства.
-
Выберите компилятор. Воспользуйтесь последними версиями GNU GCC для чекеров на C++. Во время компиляции в окружении файла будет доступна встроенная библиотека testlib.h, файл может к ней обращаться.
-
Выберите тип чекера TESTLIB_EXITCODE_CHECKER.
-
Нажмите кнопку Компилировать. Когда компиляция завершится, поля Тип чекера и Окружение заполнятся указанными в окне значениями, а внизу раздела Настройки чекера появится скомпилированный файл.
-
Справа внизу нажмите кнопку Сохранить.
-
Вы можете посмотреть пример простого чекера, который сравнивает значения во входном и выходном файлах и обрезает в них пробелы и переносы:
Пример чекера на Python
import sys
# Получаем путь к файлам.
solutionResultFile = sys.argv[2]
answerFile = sys.argv[3]
# Открываем файлы для чтения.
sFile = open(solutionResultFile, mode="r")
aFile = open(answerFile, mode="r")
# Преобразуем полученные значения в строки.
a = aFile.readline().strip()
s = sFile.readline().strip()
# Проверяем равенство значений переменных a и s.
if (a == s):
# Если значения равны, возвращаем вердикт OK.
print('1 OK')
sys.exit(0)
else:
# Если значения не равны, возвращаем вердикт WA и текст ошибки.
print('0 WA')
print(f"{s} != {a}")
sys.exit(1)
Настройка чекера
Вы можете изменить следующие параметры:
|
Параметр |
Описание |
|
Тип чекера |
На основе какой системы был загружен чекер. Возможные значения:
|
|
ID чекера |
Только для типа STANDARD_CHECKER. Название встроенного чекера. В Контесте используются стандартные чекеры других систем и собственные: Стандартные проверяющие программы
Проверяющие программы Контеста
|
|
Чекер выставляет баллы |
Только для типов EJUDGE_EXITCODE_CHECKER и TESTLIB_EXITCODE_CHECKER. Добавить чекеру возможность возвращать баллы за тест. |
|
Ограничение по времени |
Максимальное время запуска чекера. После указанного времени решение получит вердикт |
|
Ограничение по времени ожидания |
Максимальное время ожидания при запуске чекера. После указанного времени решение получит вердикт |
|
Ограничение памяти |
Максимальный объем оперативной памяти, который может использоваться при запуске чекера. При превышении значения решение получит вердикт |
|
Ограничение на объем вывода |
Максимальное количество данных в потоке вывода во время работы чекера. При превышении значения решение получит вердикт |
|
Окружение |
Только для типов EJUDGE_EXITCODE_CHECKER, TESTLIB_EXITCODE_CHECKER и TESTLIB_CHECKER. Окружение с выбранным компилятором будет использовано для запуска чекера. Опцию Legacy можно заменить на другую, но после изменения вернуться к ней будет невозможно. После успешной компиляции в этом поле будет указано значение, выбранное в поле Компилятор. |
|
Файлы чекера |
Только для типов EJUDGE_EXITCODE_CHECKER, TESTLIB_EXITCODE_CHECKER и TESTLIB_CHECKER. Добавить файлы, необходимые для корректной работы чекера. Первым добавляйте его скомпилированный исполняемый файл. |
Полезные ссылки
- Блог Чекеры, testlib.h и просто по теме в Codeforces — описание работы чекеров и как их создавать.