Files
LiquidCode.Tester/POLYGON_PACKAGE_STRUCTURE.md
2025-10-28 22:03:50 +04:00

580 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Структура пакета 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
<?xml version="1.0" encoding="utf-8"?>
<problem revision="17" short-name="example-problem" url="...">
<names>
<name language="english" value="Problem Title"/>
</names>
<judging>
<testset name="tests">
<time-limit>2000</time-limit> <!-- мс -->
<memory-limit>268435456</memory-limit> <!-- байты = 256 MB -->
<test-count>51</test-count>
<input-path-pattern>tests/%02d</input-path-pattern>
<answer-path-pattern>tests/%02d.a</answer-path-pattern>
<tests>
<test method="manual" sample="true"/> <!-- ручной, в примерах -->
<test cmd="gen 100" method="generated"/> <!-- сгенерированный -->
<test cmd="gen 1000" method="generated"/>
...
</tests>
</testset>
</judging>
<assets>
<checker name="std::ncmp.cpp" type="testlib">
<source path="files/check.cpp" type="cpp.g++17"/>
<binary path="check.exe" type="exe.win32"/>
</checker>
<validators>
<validator>
<source path="files/v.cpp" type="cpp.g++17"/>
<binary path="files/v.exe" type="exe.win32"/>
</validator>
</validators>
<solutions>
<solution tag="main">
<source path="solutions/sol.cpp" type="cpp.g++17"/>
<binary path="solutions/sol.exe" type="exe.win32"/>
</solution>
<solution tag="accepted">
<source path="solutions/sol.py" type="python.3"/>
</solution>
<solution tag="wrong-answer">
<source path="solutions/sol-wa.cpp" type="cpp.g++17"/>
</solution>
</solutions>
</assets>
</problem>
```
---
### 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<int>("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
<tests>
<test method="manual" sample="true"/> <!-- tests/01 - вручную, в примерах -->
<test cmd="gen 10 5" method="generated"/> <!-- tests/02 - сгенерирован -->
<test cmd="gen 100 50" method="generated"/> <!-- tests/03 -->
</tests>
```
---
### 4. **Generator (g.cpp)**
Программа для генерации тестов:
```cpp
#include "testlib.h"
#include <iostream>
int main(int argc, char* argv[]) {
registerGen(argc, argv, 1);
int n = opt<int>(1); // Первый аргумент
int maxVal = opt<int>(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 указано:
<test cmd="gen 1000 10000" method="generated"/>
# 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<int> jans(n);
for (int i = 0; i < n; i++)
jans[i] = ans.readInt();
std::vector<int> 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
<solution tag="main"> <!-- Главное решение (генерирует .a файлы) -->
<solution tag="accepted"> <!-- Дополнительные AC решения -->
<solution tag="wrong-answer"> <!-- WA (для теста checker'а) -->
<solution tag="time-limit-exceeded"> <!-- TL -->
<solution tag="memory-limit-exceeded"> <!-- ML -->
<solution tag="rejected"> <!-- Другие RE/PE -->
```
**Назначение:**
- `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 <iostream>
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 для проверки входных данных