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

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

Добрый день, Codeforces!

Сегодня я расскажу вам о новой функции системы Polygon, в которой готовятся все задачи для раундов Codeforces. Конечно, система открыта для любых пользователей — в ней подготавливается большое количество контестов для других соревнований или сборов.

Двумя ключевыми элементами задачи, помимо авторского решения, тестов и условия, являются две программы: валидатор и чекер.

Валидатор (англ. Validator) — это программа, которая считывает тест и сообщает, соответствует ли он условию задачи или нет. Валидаторы необходимо писать абсолютно формально — валидатор пропускает тест тогда и только тогда, когда он соответствует условию задачи и может быть спокойно добавлен в набор тестов. Валидаторы удобно писать с помощью библиотеки testlib.h. Иногда авторы пренебрегают валидаторами (на соревнованиях Codeforces такого не случается), что ставит под угрозу корректность тестов. Так как в соревнованиях Codeforces присутствуют взломы, важность правильности валидатора значительно возрастает. Естественно, все взломы перед тем, как попасть к решению участника, проходят валидацию. В большинстве задач валидаторы относительно простые, но когда в задаче появляются дополнительные условия (например, что решение для теста существует), то сложность валидатора значительно возрастает.

Чекер (англ. Checker) — это программа, которая на вход получает тест, вывод программы участника и вывод программы жюри и определяет правильность вывода участника. К сожалению, ошибки в чекерах часто приводят к тяжелым последствиям. Далеко не во всех задачах можно просто сравнить ответы на равенство. Например, в задаче 234H - Слияние двух колод в чекере используется декартово дерево. Если по условию задачи требуется сертификат, то чекер лучше всего писать в концепции readAnswer(ans)/readAnswer(ouf). Это концепция и многое другое по теме разработки чекеров описано в древнем посте Чекеры, testlib.h и просто по теме. Чекеры удобно писать с помощью библиотеки testlib.h.

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

В обновленной версии Polygon всё стало значительно лучще! Мы сделали удобные средства для тестирования валидатора и чекера.  

Тесты для валидатора тестов

Такое средство теперь доступно в системе Polygon. Тесты отображаются на странице Validator. Вы легко можете добавить за раз много тестов, разделяя их специальным маркером. Для каждого добавленного теста укажите ожидаемый вердикт валидатора (valid или invalid). Там же можно запустить эти тесты на проверку. Тесты валидатора являются полноценной частью задачи и попадают в пакет задачи. По этой причине обновлен формат problem.xml, вот пример расширенного описания валидатора (элементы binary и testset — опциональны):

<validator>
    <source path="files/v.cpp" type="cpp.g++"/>
    <binary path="files/v.exe" type="exe.win32"/>
    <testset>
        <test-count>2</test-count>
        <input-path-pattern>validator-tests/%02d</input-path-pattern>
        <tests>
            <test verdict="valid"/>
            <test verdict="invalid"/>
        </tests>
    </testset>
</validator>

Если у валидатора нет тестов, то вы получите традиционное полигонное предупреждение.

Тесты для чекера

Здесь всё аналогично. Такие тесты создавать чуть сложнее, так как необходимо ввести не только input, но и output (вроде как вывод участника) и answer (вроде как ответ, вывод авторского решения). Для стандартных чекеров тесты создавать не нужно. Вот пример обновленного описания чекера из problem.xml (элементы binary, copy, testset — опциональны):

<checker name="std::wcmp.cpp" type="testlib">
    <source path="files/check.cpp" type="cpp.g++"/>
    <binary path="check.exe" type="exe.win32"/>
    <copy path="check.cpp" type="cpp.g++"/>
    <testset>
        <test-count>4</test-count>
        <input-path-pattern>checker-tests/%02d</input-path-pattern>
        <output-path-pattern>checker-tests/%02d.o</output-path-pattern>
        <answer-path-pattern>checker-tests/%02d.a</answer-path-pattern>
        <tests>
            <test verdict="ok"/>
            <test verdict="wrong-answer"/>
            <test verdict="wrong-answer"/>
            <test verdict="presentation-error"/>
        </tests>
    </testset>
</checker>

Если у нестандартного чекера нет тестов, то вы получите традиционное полигонное предупреждение.

Напоследок

Как вы видите, все изменения problem.xml обратно совместимы. Проверка тестов встроена в скрипты развертывания задачи doall.bat/doall.sh. При импорте задачи вы вручную или автоматизировано можете проверить прохождение тестов, так как они формально описаны в problem.xml и содержатся в пакете задачи.

Я уверен, что наличие такого инструмента позволит облегчить жизнь авторов задач и уменьшит вероятность ошибок.

С уважением, Иван.

  • Проголосовать: нравится
  • +159
  • Проголосовать: не нравится

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

После твоего появления в штабе улучшения системы участились!)

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

Респект! А теперь...

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

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

Спасибо! Возможности, безусловно, полезные.

Но всё же: правильно ли я понял, что в рамках данного исправления вы всё же игнорили вот эту проблему (с оценивающими чекерами)? Если не игнорили — как её теперь правильно решать?

И ещё — как насчёт хоть какой-то централизованности информации и мест для вопросов о Полигоне? В данной теме (блоге) даже тэга "polygon" нету...

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

    Тег добавил. Спасибо. Этот обновление только добавило тесты для валидатора и чекера. По поводу поддержки testlib.h задач с оценивающими чекерами у меня информации нет.

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

    Эта проблема решена в testlib 0.9.0. Еще заодно в 0.8.8 кажется можно переопределять exit_code, мне это тоже вроде было нужно, для оценивающих чекеров.

  • »
    »
    11 лет назад, # ^ |
    Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

    Кстати, для оценивающих чекеров можно попробовать использовать _quitf(_pc(X), "comment %d", X или quitp(0.239017, "message %.2lf", 0.239017);. Первый завершает программу с кодом PC_BASE_EXIT_CODE + X, где PC_BASE_EXIT_CODE=0 (можно поменять, например, при -DTESTSYS это поменяется на 50), второй выводит printf("%.10f %s", score, message) и выходит с POINTS_EXIT_CODE=7.

    UPD: мне тут сказали, что это не работает в eJudge.

»
11 лет назад, # |
  Проголосовать: нравится -19 Проголосовать: не нравится

Great Work :)

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

I have something to say about Polygon.

In 2011 I was a judge and problem setter in the ACM ICPC Arab regional contest, and we didn't use any specific system to prepare the problems, and it was really painful.

In 2012 I was the chief judge, and we used Polygon, which made our life much easier with more features and safety checks, and I want to thank everyone who worked in this amazing system.

In 2013 I'll be the chief judge again, and definitely I'll use Polygon.

And I have a suggestion also, since Polygon is being used to prepare huge contests, I think some people (like me) might be worried about some security issues, so I think it will be good idea if you can use secure browsing (https).

»
11 лет назад, # |
Rev. 2   Проголосовать: нравится -13 Проголосовать: не нравится

Если хотите сделать что-нибудь полезное, есть три пункта:

  1. Блокировки на уровне svn, чтобы невозможно было создать коллизию правок.

  2. Возможность создать файл с заданным именем на сервере.

  3. Возможность переименовать решения на java.

  • »
    »
    11 лет назад, # ^ |
    Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

    \3. Сначала меняем имя класса в исходнике, потом переименовываем файл. видимо наоборот, сначала переименовать файл, потом поменять имя класса в исходнике.

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

      А, в таком порядке и правда сейчас работает, с большой красной надписью "все плохо".

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

    Раз уж пошли "пожелания общего характера"... То еще три пункта:

    1. Сейчас, чтобы собрать пакет под Linux (или Windows), приходится собирать full package. Возможно, имеет смысл сделать возможность раздельной сборки?

    2. Иногда было бы удобно видеть в "сводной таблице" в invocations не только время на каждом тесте, но и память (сейчас нужно просматривать "страницу" каждого теста отдельно).

    3. (_из разряда ненаучной фантастики, видимо_) Компиляция условий задач по отдельности и компиляция условий в пакете отличаются даже при использовании "стандартного" olymp.sty (например, символ решетки отображается в отдельных задачах, но при компиляции пакета — увы; проблемы возникают при работе с таблицами и т.п.). Конечно, когда стилевой файл исправляется вручную, ожидать компиляции условий отдельных задач не приходится. Но в исправлениях в .sty необходимость всё же возникает редко, а "по умолчанию" хотелось бы одинакового поведения.

    • »
      »
      »
      11 лет назад, # ^ |
      Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

      3th. Замечу, что компиляция условий в html и в pdf делается принципиально разными способами, отсюда все подобные вопросы. Пофиксить это в целом пока нереально.

  • »
    »
    11 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    2th. зачем?

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

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

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

    В разделе "Files" в таблице "Resource Files" это разве не оно?

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

С нетерпением жду возможности добавить валидатор для тестов для валидатора тестов.

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

For a newly created problem it appears that validator tests require the checker to run. To me it seems quite strange, because the validator supposedly only runs on the test inputs.