Codenrock
ОрганизаторПродвинутый15 мин

Настройка CODING-задач

Полное руководство по созданию и настройке задач на программирование

Содержание

# Настройка CODING-задач CODING — это тип задач для алгоритмических соревнований. Участники пишут код, который автоматически проверяется на наборе тестов. В этом руководстве — всё о создании и настройке таких задач. --- ## Обзор ### Как работает проверка ``` 1. Участник отправляет код 2. Код компилируется (для C++, Java, и т.д.) 3. Программа запускается на каждом тесте 4. Вывод сравнивается с ожидаемым (через чеккер) 5. Результаты возвращаются участнику ``` ### Компоненты CODING-задачи | Компонент | Описание | Обязательно | |-----------|----------|-------------| | **Условие** | Текст задачи с описанием | Да | | **Тесты** | Пары вход/выход | Да | | **Ограничения** | Время и память | Да | | **Языки** | Разрешённые языки программирования | Да | | **Чеккер** | Программа для проверки ответа | Нет (стандартный) | | **Интерактор** | Для интерактивных задач | Нет | --- ## Создание CODING-задачи ### Шаг 1: Создайте задачу 1. Перейдите в **«Треки»** → выберите трек 2. Нажмите **«Управление задачами»** 3. Нажмите **«+ Добавить задачу»** 4. Выберите тип **CODING** ### Шаг 2: Заполните основные поля | Поле | Описание | Пример | |------|----------|--------| | **Название** | Название задачи | «Сумма чисел» | | **Условие** | Описание задачи (Markdown) | Полный текст условия | | **Баллы** | Максимальный балл за задачу | 100 | | **Порядок** | Позиция в треке | 1 | ### Шаг 3: Настройте ограничения | Настройка | Описание | Рекомендации | |-----------|----------|--------------| | **Время (мс)** | Лимит времени на один тест | 1000-5000 мс | | **Память (МБ)** | Лимит памяти | 256-512 МБ | > **Важно**: Ограничения применяются к каждому тесту отдельно. Если тестов 10 и лимит 1 сек, общее время может быть до 10 секунд. ### Шаг 4: Выберите языки 1. В разделе **«Языки программирования»** выберите доступные языки 2. Укажите **язык по умолчанию** (будет выбран при открытии) 3. Опционально: отключите выбор языка (если разрешён только один) ### Шаг 5: Добавьте тесты Подробнее в разделе [Тесты](#тесты) ниже. ### Шаг 6: Сохраните задачу Нажмите **«Создать»** или **«Сохранить»**. --- ## Ограничения по времени и памяти ### Как вычисляются ограничения | Параметр | Описание | |----------|----------| | **Время** | Время CPU, не реальное время. Включает только выполнение кода пользователя | | **Память** | Пиковое использование памяти процессом (heap + stack) | ### Рекомендации по настройке | Тип задачи | Время | Память | Комментарий | |------------|-------|--------|-------------| | Простая | 1 сек | 256 МБ | Линейные алгоритмы | | Средняя | 2-3 сек | 256 МБ | O(N log N) алгоритмы | | Сложная | 5 сек | 512 МБ | Тяжёлые вычисления | | Строки | 2-3 сек | 512 МБ | Работа с большими строками | ### Учёт особенностей языков Разные языки имеют разную скорость выполнения: | Язык | Относительная скорость | Рекомендация | |------|------------------------|--------------| | C/C++ | 1x (базовая) | Эталон для расчёта лимитов | | Java | 2-3x медленнее | Увеличьте лимит в 2-3 раза | | Python | 10-50x медленнее | Увеличьте лимит в 10+ раз | | JavaScript | 3-5x медленнее | Увеличьте лимит в 3-5 раз | > **Совет**: Если задача рассчитана на C++, но разрешён Python, установите более мягкий лимит или используйте разные лимиты для разных языков. --- ## Тесты ### Структура теста Каждый тест состоит из: | Компонент | Описание | |-----------|----------| | **Входные данные (input)** | Что получает программа на stdin | | **Ожидаемый вывод (output)** | Что должна вывести программа | | **Баллы** | Очки за этот тест (опционально) | ### Публичные vs скрытые тесты | Тип | Видны участнику | Назначение | |-----|-----------------|------------| | **Публичные** | Вход и выход | Примеры в условии | | **Скрытые** | Только результат | Основная проверка | ### Добавление тестов #### Вручную 1. В редакторе задачи перейдите в раздел **«Тесты»** 2. Нажмите **«+ Добавить тест»** 3. Заполните: - **Входные данные** — текст или загрузите файл - **Ожидаемый вывод** — текст или загрузите файл - **Публичный** — поставьте галочку для примеров - **Баллы** — если включён режим частичных баллов #### Из файлов Для большого количества тестов: 1. Подготовьте файлы с именами: ``` 01.in, 01.out 02.in, 02.out ... ``` 2. Заархивируйте в ZIP 3. Загрузите через **«Импорт тестов»** ### Рекомендации по тестам | Категория | Описание | Пример | |-----------|----------|--------| | **Граничные случаи** | Минимальные/максимальные значения | N=1, N=10^9 | | **Особые случаи** | Нули, отрицательные, пустые | N=0, arr=[] | | **Случайные** | Средние случайные данные | Сгенерированные | | **Максимальные** | Стресс-тесты на производительность | Максимальный N | ### Генерация тестов Для автоматической генерации используйте скрипт: ```python import random def generate_test(test_num, n_min, n_max): n = random.randint(n_min, n_max) arr = [random.randint(1, 10**9) for _ in range(n)] # Входные данные with open(f'{test_num:02d}.in', 'w') as f: f.write(f'{n}\n') f.write(' '.join(map(str, arr)) + '\n') # Ожидаемый вывод (ваш эталонный алгоритм) result = solve(n, arr) with open(f'{test_num:02d}.out', 'w') as f: f.write(f'{result}\n') # Генерация 20 тестов for i in range(1, 21): generate_test(i, 1, 10**5) ``` --- ## Чеккер (Checker) ### Что такое чеккер **Чеккер** — это программа, которая проверяет правильность ответа участника. Стандартный чеккер просто сравнивает вывод участника с ожидаемым выводом. ### Когда нужен кастомный чеккер | Ситуация | Пример | |----------|--------| | **Несколько правильных ответов** | «Найдите любое решение уравнения» | | **Точность вычислений** | «Ответ с точностью до 10^-6» | | **Порядок не важен** | «Выведите множество чисел» | | **Частичные баллы** | «Чем ближе к оптимуму, тем больше баллов» | ### Стандартный чеккер Если кастомный чеккер не указан, используется стандартный: 1. Разбивает вывод на токены (слова) 2. Сравнивает токены по порядку 3. Игнорирует лишние пробелы и переносы строк 4. Результат: `OK` (всё совпало) или `WA` (не совпало) ### Формат кастомного чеккера Чеккер — это исполняемый файл, который получает: | Аргумент | Описание | |----------|----------| | `argv[1]` | Путь к файлу с входными данными (input) | | `argv[2]` | Путь к файлу с выводом участника (output) | | `argv[3]` | Путь к файлу с ожидаемым ответом (answer) | Чеккер возвращает: | Exit code | Значение | |-----------|----------| | 0 | Accepted (ответ правильный) | | 1 | Wrong Answer (ответ неправильный) | | 2 | Presentation Error (неверный формат) | ### Пример чеккера на C++ ```cpp #include <iostream> #include <fstream> #include <cmath> int main(int argc, char* argv[]) { std::ifstream input(argv[1]); // входные данные std::ifstream output(argv[2]); // ответ участника std::ifstream answer(argv[3]); // ожидаемый ответ double expected, actual; answer >> expected; if (!(output >> actual)) { std::cerr << "Ошибка чтения ответа участника" << std::endl; return 1; // WA } // Проверка с точностью 10^-6 if (std::abs(expected - actual) < 1e-6) { std::cout << "OK" << std::endl; return 0; // AC } else { std::cerr << "Expected: " << expected << ", Got: " << actual << std::endl; return 1; // WA } } ``` ### Пример чеккера на Python ```python #!/usr/bin/env python3 import sys def main(): input_file = sys.argv[1] # входные данные output_file = sys.argv[2] # ответ участника answer_file = sys.argv[3] # ожидаемый ответ with open(answer_file) as f: expected = float(f.read().strip()) try: with open(output_file) as f: actual = float(f.read().strip()) except: print("Ошибка чтения ответа", file=sys.stderr) sys.exit(1) # WA # Проверка с точностью 10^-6 if abs(expected - actual) < 1e-6: print("OK") sys.exit(0) # AC else: print(f"Expected: {expected}, Got: {actual}", file=sys.stderr) sys.exit(1) # WA if __name__ == "__main__": main() ``` ### Чеккер с частичными баллами Для задач, где нужно начислять частичные баллы: 1. Включите опцию **«Score from Checker»** в настройках 2. Чеккер должен выводить score в stdout 3. Выберите метод агрегации (SUM, AVG, MIN, MAX) ```cpp // Чеккер выводит score от 0 до 100 int main(int argc, char* argv[]) { // ... проверка ... double accuracy = calculateAccuracy(expected, actual); int score = static_cast<int>(accuracy * 100); std::cout << score << std::endl; // Выводим score return 0; // Всегда возвращаем 0 } ``` ### Загрузка чеккера 1. В настройках задачи найдите раздел **«Чеккер»** 2. Загрузите скомпилированный бинарный файл или скрипт 3. Убедитесь, что файл исполняемый > **Важно**: Чеккер должен быть скомпилирован для Linux x64 (Alpine/Debian). ### Где взять чеккеры | Источник | Описание | |----------|----------| | **testlib.h** | Библиотека от Codeforces для написания чеккеров | | **Polygon** | Система подготовки задач с готовыми чеккерами | | **GitHub** | Репозитории с примерами чеккеров | Пример с testlib.h: ```cpp #include "testlib.h" int main(int argc, char* argv[]) { registerTestlibCmd(argc, argv); double expected = ans.readDouble(); double actual = ouf.readDouble(); if (std::abs(expected - actual) < 1e-6) { quitf(_ok, "Correct: %.6f", actual); } else { quitf(_wa, "Expected: %.6f, got: %.6f", expected, actual); } } ``` --- ## Интерактор (Interactor) ### Что такое интерактор **Интерактор** — программа для интерактивных задач, где решение участника общается с системой в режиме диалога (вопрос-ответ). ### Когда нужен интерактор | Тип задачи | Пример | |------------|--------| | **Угадывание** | «Угадай число за минимум вопросов» | | **Игры** | «Сыграй оптимально против бота» | | **Запросы** | «Узнай структуру графа через запросы» | ### Как работает интерактор ``` ┌─────────────┐ stdin ┌──────────────┐ │ Интерактор │ ──────────▶ │ Решение │ │ │ ◀────────── │ участника │ └─────────────┘ stdout └──────────────┘ ``` 1. Интерактор отправляет данные на stdin решения 2. Решение читает stdin и отвечает в stdout 3. Интерактор читает stdout решения и отвечает 4. Диалог продолжается до завершения ### Формат интерактора Интерактор получает: | Аргумент | Описание | |----------|----------| | `argv[1]` | Путь к файлу с входными данными (секретные данные) | | `argv[2]` | Путь к файлу с ответом (для записи результата) | | `stdin` | Вывод решения участника | | `stdout` | Ввод для решения участника | ### Пример интерактора Задача: угадать число от 1 до N за минимум вопросов. ```cpp #include <iostream> #include <fstream> int main(int argc, char* argv[]) { std::ifstream input(argv[1]); // секретное число std::ofstream answer(argv[2]); // результат int secret, n; input >> n >> secret; std::cout << n << std::endl; // Сообщаем N участнику std::cout.flush(); int queries = 0; std::string command; int guess; while (std::cin >> command >> guess) { queries++; if (command == "?") { // Вопрос: "число >= guess?" if (guess <= secret) { std::cout << "YES" << std::endl; } else { std::cout << "NO" << std::endl; } std::cout.flush(); } else if (command == "!") { // Ответ if (guess == secret) { answer << "OK " << queries << std::endl; return 0; // AC } else { answer << "WA: expected " << secret << ", got " << guess << std::endl; return 1; // WA } } if (queries > 100) { // Лимит вопросов answer << "WA: too many queries" << std::endl; return 1; } } answer << "WA: unexpected end of output" << std::endl; return 1; } ``` ### Важные моменты 1. **flush**: После каждого вывода делайте `std::cout.flush()` или `std::endl` 2. **Лимиты**: Ограничивайте количество запросов 3. **Протокол**: Чётко опишите протокол в условии задачи ### Загрузка интерактора 1. В настройках задачи найдите раздел **«Интерактор»** 2. Загрузите скомпилированный бинарный файл 3. Создайте тесты с секретными данными --- ## Режимы оценивания ### Стандартный режим Все тесты пройдены = полные баллы, иначе = 0. **Настройка**: По умолчанию, ничего не нужно включать. ### Частичные баллы за тесты Баллы пропорционально пройденным тестам. **Настройка**: 1. Укажите баллы для каждого теста 2. Общий балл = сумма баллов за пройденные тесты ### Score from Checker Баллы определяет чеккер. **Настройка**: 1. Включите **«Score from Checker»** 2. Выберите **метод агрегации**: - **SUM**: Сумма score по всем тестам - **AVG**: Среднее значение - **MIN**: Минимальный score - **MAX**: Максимальный score (по умолчанию) 3. Загрузите чеккер, который выводит score ### Best Score Mode Учитывается лучший результат из всех отправок. **Настройка**: Включите **«Best Score Mode»** **Поведение**: - При Submit сравнивается с текущим сохранённым результатом - Сохраняется только если новый результат лучше - Участник не может ухудшить свой результат --- ## Языки программирования ### Управление языками 1. В настройках задачи перейдите в **«Языки»** 2. Выберите разрешённые языки из списка 3. Укажите язык по умолчанию ### Доступные языки | Язык | Версия | |------|--------| | Python | 3.11 | | C++ | C++17 | | Java | 17 | | JavaScript | Node.js 18 | | Go | 1.21 | | Rust | 1.70 | | C# | .NET 7 | ### Шаблон кода по умолчанию Для каждого языка можно задать шаблон, который будет показан участнику при открытии редактора: ```python # Python шаблон def solve(): n = int(input()) # Ваш код здесь pass if __name__ == "__main__": solve() ``` ### Ограничение на один язык Если задача только на одном языке: 1. Выберите только один язык 2. Отключите **«Разрешить выбор языка»** --- ## Лимиты отправок ### Настройка лимитов | Параметр | Описание | |----------|----------| | **maxSolutionsCount** | Максимальное количество отправок | | **solutionsCountPeriod** | Период: DAILY (в сутки) или ALL_TIME (за всё время) | ### Примеры | Настройка | Описание | |-----------|----------| | 50 / ALL_TIME | 50 отправок на всё соревнование | | 10 / DAILY | 10 отправок в сутки (сбрасывается в полночь) | | null | Без ограничений | ### Когда использовать | Ситуация | Рекомендация | |----------|--------------| | **Обычное соревнование** | Без ограничений или 50-100 за всё время | | **Тест на знания** | 3-5 попыток за всё время | | **ML/оптимизация** | 10-20 в сутки | --- ## Чек-лист создания задачи - [ ] Условие написано понятно - [ ] Формат ввода/вывода описан чётко - [ ] Ограничения указаны (время, память, диапазоны) - [ ] Публичные тесты соответствуют примерам в условии - [ ] Скрытые тесты покрывают граничные случаи - [ ] Ограничения реалистичны для выбранных языков - [ ] Эталонное решение проходит все тесты - [ ] Кастомный чеккер протестирован (если используется) - [ ] Интерактор протестирован (если используется) --- ## Частые вопросы **В: Как добавить задачу с несколькими правильными ответами?** О: Используйте кастомный чеккер, который проверяет, что ответ удовлетворяет условиям, а не сравнивает с эталоном. **В: Как сделать разные лимиты для разных языков?** О: В текущей версии лимиты одинаковые для всех языков. Установите лимит, достаточный для самого медленного языка. **В: Можно ли добавить тесты после публикации?** О: Да, но это может повлиять на уже сданные решения. Рекомендуется добавлять тесты до начала соревнования. **В: Где взять testlib.h?** О: Скачайте с GitHub: https://github.com/MikeMirzayanov/testlib **В: Как протестировать чеккер локально?** О: ```bash ./checker input.txt output.txt answer.txt echo $? # 0 = AC, 1 = WA ``` **В: Почему участники получают TLE на Python, но AC на C++?** О: Python в 10-50 раз медленнее C++. Увеличьте лимит времени или укажите, что задача рассчитана на C++. --- ## Связанные статьи - [Создание задач](/docs/organizer/tracks-tasks/create-tasks) - [Настройки задач](/docs/organizer/tracks-tasks/task-settings) - [Создание треков](/docs/organizer/tracks-tasks/create-tracks) - [CODING для участников](/docs/participant/tasks/coding-tasks)
Последнее обновление: 20.08.2026
К оглавлению