Блог пользователя Erop

Автор Erop, 12 лет назад, По-русски

Доброго времени суток.

Важной частью процесса подготовки задачи является написание валидатора — специальной программы, которая проверяет, что каждый тест в точности соответствует всем описанным в условии ограничениям. Проблема написания валидатора сравнима с проблемой написания чекера: при написании их с нуля возникает куча сложностей о которых уже писал MikeMirzayanov.

Однако чекер и валидатор выполняют разные функции, и использовать одну библиотеку для написания обеих программ не всегда удобно. Поэтому представляю вашему вниманию библиотеку strict.h — библиотеку, специализированную на валидаторах. Последнюю версию можно скачать по адресу http://acm.timus.ru/stricth/.

Во многих задачах формат входных данных имеет более-менее стандартный вид. Для таких задач хочется, чтобы валидатор был предельно прост, но, с другой стороны, он должен оставаться валидатором и строго проверять корректность тестов.

Всё это позволяет делать библиотека strict.h, которая уже используется при подготовке уральских контестов, а также на Тимусе.

Пример валидатора

Валидатор для задачи 1393. Average Common Prefix с Тимуса:

#include "strict.h"
using namespace std;

const int MAXLEN = 250000;
const int MINLEN = 2;

int main()
{
    Input in;

    int n = in.readInt(MINLEN, MAXLEN);
    in.readEoln();
    in.readToken(n, n, "A-Z");
    in.readEoln();
    in.readEof();

    return 0;
}
  • Проголосовать: нравится
  • 0
  • Проголосовать: не нравится

»
12 лет назад, # |
  Проголосовать: нравится +31 Проголосовать: не нравится

А в чём преимущества использования strict.h перед использованием testlib.h? Единственный «аргумент», который я вижу в посте, такой:

Однако чекер и валидатор выполняют разные функции, и использовать одну библиотеку для написания обеих программ не всегда удобно.

Вообще-то, наоборот, удобно знать и применять одну библиотеку, а не две. Чтобы при чтении чекера и чтении валидатора хотя бы названия функций были одинаковые. Проще и быстрее прочитать их и проверить.

Ну ладно, идём на сайт, там приведено три аргумента:

(1) специализация на написании валидаторов

Не поспоришь. Но пока мало всего и это выглядит очень по-домашнему. Например, есть какие-то частные проверки типа isConnected и isPrime, причём в первом случае нужно ещё догадаться, что в графе обязательно нумеровать вершины с единицы, а во втором проверка работает только для int32 — а если уж хочется это проверять библиотекой, можно бы реализовать хотя бы для int64.

(2) простота использования и надежность проверки

Сломал за пять минут:

in.readDouble(0.15, 0.15, 2);

Вводим 0.15, естественно. И вердикт...

Line 1, pos 5: number 0.15 is out of bounds [0.15, 0.15]

Да ещё и пробел в конце вместо перевода строки.

Ну ожидаемо, в общем. Что-то надо с этим делать. И ещё, обычно числа типа 1. и .1 (а особенно 0. и .0) во входных файлах тоже не стоит считать валидными.

(3) небольшой и полностью покрытый тестами исходный код

Сами тесты почему-то нигде в открытом доступе не лежат...


В общем, моя позиция такая: такая библиотека может стать полезной, но, чтобы ей кто-то стал пользоваться, у неё должны быть серьёзные конкурентные преимущества перед существующими аналогами (руки, testlib.h, ...). Например, действительная и более серьёзная реализация пунктов, перечисленных на сайте.

По самой библиотеке ещё навскидку:

  • Метод Input::readToken всегда делает как минимум 256 операций зануления. Это может быть весьма медленно, если из файла необходимо прочитать, например, несколько миллионов букв, разделённых пробелами, а каждая из букв от 'a' до 'z'.

  • Некоторые фразы, например, "Utility for automated checking correctness of tests" и "character '%c' is not match pattern '%s'", написаны не по-английски.

  • »
    »
    12 лет назад, # ^ |
      Проголосовать: нравится +5 Проголосовать: не нравится

    Историческая справка.

    Данная библиотека на самом деле является новым поколением моей старой библиотеки 2005 года correct.h, которая в какой-то момент оказалась слишком перегруженной, и была переделана и упрощена. Из-за отсутствия обратной совместимости пришлось поменять и название. Заодно методы чтения были переименованы в стиле тестлиба.

    В 2010 году мы пробовали перейти в написании валидаторов на тестлиб, и этот опыт показал такой недостаток "одной библиотеки": для написания валидаторов нам нужна была самая свежая версия тестлиба, а для написания чекеров — другая версия: та, которую поддерживает Тимус. Так что по сути это все равно были две разные библиотеки, только путаницы было значительно больше.

    Конечно, мы пробовали обновить тестлиб на Тимусе, но из-за отсутствия обратной совместимости это было не так просто (нужно было переписывать чекеры у порядка 20 задач). Более того, в процессе миграции в тестибе обнаружились баги, заставившие нас вообще отказаться от идеи обновления. Было проще переписать чекеры готовившегося контеста под старый тестлиб.

    И последним аргументом в пользу возврата к своей библиотеке для валидаторов для нас стал тот факт, что ввод данных в тестлибе был сделан через scanf, что означало менее строгую проверку ввода, чем нам хотелось.

»
12 лет назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится

Кстати, раз уж в библиотеке есть распознавание и поддержка линуксовых переводов строк — протестируйте её не только под виндой! Сейчас перечислено четыре компилятора, на которых библиотека протестирована, и все они виндовые.