# Структура пакета Polygon ## 📦 Типичная структура Polygon пакета ``` problem-name.zip │ ├── problem.xml ← Главный дескриптор задачи │ ├── tests/ ← Тесты для проверки решений │ ├── 01 ← Входные данные (без расширения!) │ ├── 01.a ← Ответы (могут отсутствовать) │ ├── 02 │ ├── 02.a │ └── ... │ ├── files/ ← Вспомогательные файлы │ ├── testlib.h ← Библиотека для checker/validator/generator │ ├── olymp.sty ← LaTeX стиль для statements │ ├── problem.tex ← Шаблон условия │ ├── statements.ftl ← FreeMarker шаблон │ │ │ ├── tests/ ← Тесты для checker/validator │ │ ├── checker-tests/ │ │ │ ├── 01 │ │ │ ├── 01.a │ │ │ └── 01.o ← Ожидаемый output │ │ │ │ │ └── validator-tests/ │ │ ├── 01 │ │ ├── 02 │ │ └── ... │ │ │ ├── g.cpp ← Generator (генератор тестов) │ ├── g.exe │ ├── v.cpp ← Validator (валидатор входных данных) │ ├── v.exe │ ├── check.cpp ← Checker (проверка ответа) │ ├── check.exe │ ├── interactor.cpp ← Interactor (для интерактивных задач) │ ├── interactor.exe │ │ │ └── [resource files] ← Дополнительные ресурсы для решений │ ├── aplusb.h ← Header для grader-задач │ ├── grader.cpp ← Grader для компиляции с решением │ └── main.py ← Python wrapper для grader │ ├── solutions/ ← Эталонные решения │ ├── sol.cpp ← Главное (main) решение │ ├── sol.exe │ ├── sol.py │ ├── sol.java │ │ │ ├── sol-accepted-1.cpp ← Дополнительные AC решения │ ├── sol-wa.cpp ← Wrong Answer решения (для теста) │ ├── sol-tl.cpp ← Time Limit решения │ ├── sol-ml.cpp ← Memory Limit решения │ └── ... │ ├── statements/ ← Условия задачи │ ├── english/ │ │ ├── problem.tex ← Исходник условия (LaTeX) │ │ ├── problem-properties.json │ │ ├── tutorial.tex ← Разбор задачи │ │ ├── example.01 ← Примеры из условия (input) │ │ └── example.01.a ← Примеры из условия (output) │ │ │ ├── russian/ │ │ └── ... │ │ │ ├── .html/ ← Сгенерированные HTML │ │ ├── english/ │ │ │ ├── problem.html │ │ │ ├── tutorial.html │ │ │ └── problem-statement.css │ │ └── russian/ │ │ │ └── .pdf/ ← Сгенерированные PDF │ ├── english/ │ │ ├── problem.pdf │ │ └── tutorial.pdf │ └── russian/ │ ├── statement-sections/ ← Секции условия (модульно) │ ├── english/ │ │ ├── legend.tex │ │ ├── input.tex │ │ ├── output.tex │ │ ├── notes.tex │ │ ├── scoring.tex │ │ └── examples/ │ └── russian/ │ ├── materials/ ← Материалы для участников │ ├── grader-cpp.zip ← Grader для C++ │ ├── grader-py.zip ← Grader для Python │ └── ... │ ├── scripts/ ← Скрипты для работы с пакетом │ ├── gen-answer.sh │ ├── gen-input-via-files.sh │ ├── run-validator-tests.sh │ └── ... │ ├── check.cpp ← Checker в корне (копия) ├── check.exe ├── doall.sh ← Скрипт сборки всего ├── doall.bat ├── wipe.sh ← Скрипт очистки ├── wipe.bat └── tags ← Теги задачи (metadata) ``` --- ## 📄 Основные файлы и их назначение ### 1. **problem.xml** (обязательный) Центральный дескриптор задачи: ```xml 2000 268435456 51 tests/%02d tests/%02d.a ... ``` --- ### 2. **testlib.h** (стандартная библиотека) Библиотека от MikeMirzayanov для написания: - **Checkers** - проверка правильности ответа - **Validators** - проверка корректности входных данных - **Generators** - генерация тестов - **Interactors** - интерактивное взаимодействие **Основные функции:** ```cpp #include "testlib.h" // Checker int main(int argc, char* argv[]) { registerTestlibCmd(argc, argv); int jans = ans.readInt(); // Правильный ответ int pans = ouf.readInt(); // Ответ участника if (jans == pans) quitf(_ok, "Correct"); else quitf(_wa, "Wrong answer: %d instead of %d", pans, jans); } // Validator int main(int argc, char* argv[]) { registerValidation(argc, argv); int n = inf.readInt(1, 100000, "n"); inf.readEoln(); inf.readEof(); } // Generator int main(int argc, char* argv[]) { registerGen(argc, argv, 1); int n = opt("n"); println(n); for (int i = 0; i < n; i++) println(rnd.next(1, 1000000)); } ``` --- ### 3. **Тесты (tests/)** **Формат:** ``` tests/01 ← Входные данные (plain text, без расширения) tests/01.a ← Ответ (answer file) ``` **Пример:** ``` # tests/01 (input) 2 3 # tests/01.a (answer) 5 ``` **Метаданные из problem.xml:** ```xml ``` --- ### 4. **Generator (g.cpp)** Программа для генерации тестов: ```cpp #include "testlib.h" #include int main(int argc, char* argv[]) { registerGen(argc, argv, 1); int n = opt(1); // Первый аргумент int maxVal = opt(2); // Второй аргумент std::cout << n << std::endl; for (int i = 0; i < n; i++) { std::cout << rnd.next(1, maxVal); if (i + 1 < n) std::cout << " "; } std::cout << std::endl; return 0; } ``` **Использование:** ```bash # В problem.xml указано: # Polygon запускает: g.exe 1000 10000 > tests/05 ``` --- ### 5. **Checker (check.cpp)** Программа для проверки корректности ответа. **Типы checkers:** #### **A. Стандартные (встроенные в testlib.h):** ```cpp std::ncmp.cpp // Сравнение одного целого числа std::fcmp.cpp // Сравнение одного float с точностью std::wcmp.cpp // Сравнение по словам (tokens) std::lcmp.cpp // Построчное сравнение std::nyesno.cpp // Проверка YES/NO ``` #### **B. Custom checker:** ```cpp #include "testlib.h" int main(int argc, char* argv[]) { registerTestlibCmd(argc, argv); // inf - входной файл (input) // ouf - output участника (output user file) // ans - правильный ответ (answer) int n = inf.readInt(); std::vector jans(n); for (int i = 0; i < n; i++) jans[i] = ans.readInt(); std::vector pans(n); for (int i = 0; i < n; i++) pans[i] = ouf.readInt(); // Проверка: порядок не важен (множества равны) std::sort(jans.begin(), jans.end()); std::sort(pans.begin(), pans.end()); if (jans == pans) quitf(_ok, "Correct"); else quitf(_wa, "Wrong answer"); } ``` **Exit codes:** - `0` - OK (правильный ответ) ✅ - `1` - WA (неправильный ответ) ❌ - `2` - PE (presentation error) - `3` - FAIL (ошибка в самом чекере) - `7` - Partial (частичный балл, для IOI-style) --- ### 6. **Validator (v.cpp)** Проверяет корректность входных данных: ```cpp #include "testlib.h" int main(int argc, char* argv[]) { registerValidation(argc, argv); // Проверка формата входных данных int n = inf.readInt(1, 100000, "n"); // 1 ≤ n ≤ 100000 inf.readEoln(); // Конец строки for (int i = 0; i < n; i++) { inf.readInt(1, 1000000000, "a[i]"); if (i + 1 < n) inf.readSpace(); else inf.readEoln(); } inf.readEof(); // Конец файла return 0; } ``` **Назначение:** - Проверка ограничений (1 ≤ n ≤ 10⁶) - Проверка формата (пробелы, переводы строк) - Валидация структуры (дерево, граф и т.д.) --- ### 7. **Interactor (для интерактивных задач)** Посредник между решением и тестирующей системой: ```cpp #include "testlib.h" int main(int argc, char* argv[]) { registerInteraction(argc, argv); int n = inf.readInt(); // Загаданное число int queries = 0; while (queries < 20) { int guess = ouf.readInt(1, 1000000); // Запрос участника queries++; if (guess == n) { tout << "YES" << endl; quitf(_ok, "Found in %d queries", queries); } else if (guess < n) { tout << ">" << endl; // Больше } else { tout << "<" << endl; // Меньше } } quitf(_wa, "Too many queries"); } ``` **Streams в interactor:** - `inf` - входной файл (input) - `ouf` - output участника (чтение запросов) - `tout` - передача данных участнику (ответы на запросы) - `ans` - правильный ответ (не используется в интерактивных) --- ### 8. **Solutions (эталонные решения)** **Типы решений:** ```xml ``` **Назначение:** - `main` - используется для генерации answer files - `accepted` - проверка, что задача решаема разными способами - `wrong-answer` - тестирование checker'а - `time-limit-exceeded` - проверка TL --- ### 9. **Grader-задачи (специальный тип)** Участник пишет функцию, а не всю программу. **Структура:** ``` files/ ├── aplusb.h ← Header с сигнатурой функции ├── grader.cpp ← Main + вызов функции участника └── main.py ← Python wrapper solutions/ └── sol.cpp ← Реализация функции (не main!) ``` **Пример:** ```cpp // aplusb.h int sum(int a, int b); // grader.cpp #include "aplusb.h" #include int main() { int a, b; std::cin >> a >> b; std::cout << sum(a, b) << std::endl; return 0; } // sol.cpp (решение участника) #include "aplusb.h" int sum(int a, int b) { return a + b; } ``` --- ## 📊 Статистика по примерам пакетов ### **a-plus-b-graders-7.zip:** ``` Размер: 2.4 MB Файлов: ~50 Структура: ✅ problem.xml ✅ tests/ (8 тестов: 01-08, без .a файлов) ✅ files/testlib.h ✅ files/aplusb.h (grader header) ✅ files/grader.cpp ✅ files/g.cpp, g.exe (generator) ✅ files/v.cpp, v.exe (validator) ✅ check.cpp, check.exe (ncmp - числовой checker) ✅ solutions/sol.cpp (main) ✅ solutions/sol.py (accepted) ✅ statements/english/ (условие) ``` ### **example-interactive-binary-search-26.zip:** ``` Размер: 10.7 MB Файлов: ~100+ Структура: ✅ problem.xml ✅ tests/ (21 тест: 01-21, без .a файлов) ✅ files/testlib.h ✅ files/interactor.cpp, interactor.exe ← ИНТЕРАКТИВНАЯ! ✅ files/gen.cpp, gen.exe ✅ files/val.cpp, val.exe ✅ check.cpp, check.exe ✅ solutions/ (16 решений: main, ac, wa, tl, ml, pe, ...) ✅ statements/english/ + russian/ ``` ### **exam-queue-17.zip:** ``` Размер: 6.6 MB Файлов: ~80 Структура: ✅ problem.xml ✅ tests/ (51 тест: 01-51, без .a файлов) ✅ files/testlib.h ✅ files/gen.cpp, gen.exe ✅ files/val.cpp, val.exe ✅ check.cpp, check.exe ✅ solutions/ (множество решений) ✅ statements/russian/ (только русское условие) ``` --- ## 💡 Ключевые выводы ### **Обязательные компоненты:** 1. ✅ `problem.xml` - дескриптор 2. ✅ `tests/` - тесты 3. ✅ `files/testlib.h` - библиотека 4. ✅ `solutions/` - хотя бы одно main решение ### **Опциональные (но часто присутствуют):** - `check.cpp` - custom checker (иначе используется wcmp) - `v.cpp` - validator - `g.cpp` - generator - `interactor.cpp` - для интерактивных задач - `statements/` - условия на разных языках - `*.a` файлы - ответы (генерируются из main solution) ### **Особенности формата:** - Входные файлы **БЕЗ расширения** (01, 02, не 01.in!) - Ответы с расширением `.a` (01.a, 02.a) - testlib.h - единая библиотека для всего - problem.xml - полное описание всего пакета --- ## 🔗 Полезные ссылки - **Polygon:** https://polygon.codeforces.com/ - **testlib.h GitHub:** https://github.com/MikeMirzayanov/testlib - **Документация testlib:** https://codeforces.com/testlib - **Tutorial по Polygon:** https://codeforces.com/blog/entry/101072 --- ## 🎯 Поддержка в LiquidCode.Tester Наша система **полностью поддерживает**: - ✅ Парсинг problem.xml - ✅ Тесты в формате tests/01, tests/01.a - ✅ Автоматическую генерацию answer файлов из main solution - ✅ Компиляцию и запуск custom checkers (testlib-based) - ✅ Определение лимитов времени/памяти из problem.xml - ✅ Поддержку всех основных языков (C++, Java, Python, C#, Kotlin) **В разработке:** - ⏳ Поддержка interactor для интерактивных задач - ⏳ Поддержка grader-задач - ⏳ Запуск validator для проверки входных данных