# Структура пакета 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 для проверки входных данных
