Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Что такое ada-judge?

ada-judge – это принципиально новая платформа для проведения соревнований по программированию, написанная на языке Rust. Она не зависит от сторонних сервисов, таких как Codeforces Polygon, и является полностью самостоятельной. Основной функционал ada-judge включает:

  • Создание контестов в формате IOI
  • Создание задач, в том числе интерактивных и с двойным запуском
  • Тестирование посылок на языках Rust, C++, C, Go и Python с изолированным запуском решений
  • Администрирование контестов, задач и пользователей

Развёртывание

Для того, чтобы развернуть ada-judge на своём сервере, необходимы docker и git.

  1. Склонируйте основнойgit-репозиторий ada-judge:
    git clone https://codeberg.org/oneprog/ada-judge
    
    Или зеркало (оно обновляется раз в 8 часов):
    git clone https://github.com/OneProgGit/ada-judge
    
  2. Перейдите в директорию со склонированным репозиторием и создайте там конфигурационный файл .env, заполните его в следующем формате:
    # Данные PostgreSQL
    POSTGRES_USER=
    POSTGRES_PASSWORD=
    POSTGRES_DB=
    # Данные Redis
    REDIS_PASSWORD=
    REDIS_USER=
    REDIS_USER_PASSWORD=
    # Параметры JWT
    JWT_SECRET=
    JWT_EXP_HOURS=
    # Имя контейнера песочницы `submissions-judger`
    SANDBOX_IMAGE=sandbox
    # Количество параллельных инвокеров
    WORKERS_COUNT=
    
  3. Создайте директорию submissions_envs, где будут храниться посылки.
  4. Соберите и запустите ada-judge:
    docker-compose build; docker-compose up -d
    

ada-judge-app

ada-judge-app – это нативное GUI-приложение для ada-judge, доступное для Linux, Mac и Windows. Есть два способа его установки:

  1. Готовые бинарники. Самый простой способ, но обновления поступают реже, а также недоступны некоторые платформы, такие как Windows/Linux ARM.
  2. Через cargo. В этом случае компиляция будет происходить на вашем устройстве. Для этого способа необходим тулчейн Rust версии 1.97.0 и новее. Выполните в терминале команду:
    cargo install ada-judge-app
    

ada-judge-cli

ada-judge-cli – это терминальное приложение, созданное для упрощения создания задач. Для установки необходим тулчейн Rust версии 1.97.0 и новее. Выполните в терминале команду:

cargo install ada-judge-cli

Регистрация

Самый простой способ создать аккаунт ada-judge – использовать ada-judge-app.

  1. Откройте его:

    ada-judge-app
    
  2. Нажмите :

  3. Заполните все поля и снова нажмите :

  4. Чтобы получить права владельца, необходимо, находясь в директории с репозиторием, выполнить:

    > docker-compose exec -t postgres bash
      > psql -U <пользователь PostgreSQL> -d <база данных PostgreSQL>
        > update users set admin_level='owner' where id = <ваш id>;
        UPDATE 1
    

Вход

  1. На приветственной странице нажмите :

2. Заполните все поля и снова нажмите :

Интерфейс домашней страницы

Интерфейс домашней страницы выглядит следующим образом:

Некоторые кнопки доступны только админам.

Интерфейс контестов

Интерфейс контестов выглядит следующим образом:

Некоторые кнопки доступны только админам контеста.

Создание контестов

Для того, чтобы создать контест в ada-judge-app, нужно:

  1. Быть админом

  2. Нажать на кнопку на главной странице:

  3. В появившемся окне заполнить нужные поля, отметить нужные чекбоксы и cнова нажать :

Интерфейс задач

Интерфейс задач выглядит следующим образом:

Создание задач

ada-judge позволяет создавать задачи удобно и быстро, сочетая ada-judge-cli и ada-judge-app.

Шаги с CLI

  1. Перейдите в директорию, где будут лежать ваши задачи
  2. Создайте шаблон задачи:
    ada-judge-cli problem ./<название задачи> prepare
    
  3. Типичная структура задачи такая:
    ├── checker
    ├── config.toml
    └── tests
        ├── <тест>
        │   ├── in # входные данные теста
        │   └── out # выходные данные теста
    
  4. Отредактируйте config.toml в следующем формате:
    name = "<название задачи>"
    type = "<тип задачи>" # default -- обычная задача, interactive -- интерактивная, run_twice -- с двойным запуском, run_twice_interactive -- интерактивная с двойным запуском, run_twice_first_interactive -- с двойным запуском, причём первый из них -- интерактивный, run_twice_second_interactive -- с двойным запуском, причём второй из них -- интерактивный
    merge_subgroups = false # Включить склейку подгрупп?
    contest_id = <id контеста>
    problem_index = <индекс задачи в контеста, начиная с 0>
    time_limit_ms = <лимит по времени, мс>
    memory_limit_mb = <лимит по памяти, МБ>
    checker_path = "<путь до бинарника чекера>"
    tests_path = "<путь до директории с тестами>"
    
    # Подгруппы
    [[subgroups]]
    type = "<тип подгруппы>" # sample -- примеры, main -- основная
    tests = [<тесты подгруппы>]
    score = <баллы за подгруппу>
    # score_per_test = <баллы за каждый тест подгруппы>
    depends_on = [<индексы подгрупп, прохождение которых требуется для тестирование на этой подгруппе, начиная с 0 в порядке их следования в файле конфига>]
    
  5. Можно добавить тесты к задаче:
    ada-judge-cli problem <название задачи> insert-tests <начиная с> <заканчивая на, включительно>
    
  6. Можно протестировать решение на тестах:
    ada-judge-cli problem <название задачи> run <путь к бинарнику решения> <начиная с> <заканчивая на, включительно>
    

Как писать чекеры

Написание кастомного чекера необходимо для многих задач.

Вердикты

  • Если чекер возвращает 0, то считается, что вердикт Ок
  • Если чекер возвращает 1, то считается, что вердикт Неправильный ответ
  • Если чекер возвращает 2, то считается, что вердикт Неправильный формат вывода
  • Если чекер возвращает какой-либо другой код, то считается, что вердикт Некорректная задача

Аргументы командной строки

Чекеру передаются аргументы командной строки в следующем порядке:

Обычные задачи

  • Путь к тесту
  • Путь к ответу участника
  • Путь к ответу жюри

Интерактивные задачи

  • Путь к ответу участника
  • Путь к ответу чекера
  • Путь к тесту

Задачи с двойным запуском

  • Путь к тесту
  • Путь к ответу участника
  • Путь к ответу жюри
  • Стадия

Задачи с двойным запуском с какими-то из них интерактивными

  • Путь к ответу участника
  • Путь к ответу чекера
  • Путь к промежуточному ответу чекера (ответу между стадиями)
  • Путь к тесту
  • Стадия

Стадии

Задачи с двойным запуском

  • Стадия 0 – подготовка теста для первого запуска
  • Стадия 1 – проверка ответа участника на первом запуске и подготовка теста для второго запуска
  • Стадия 2 – проверка ответа участника на втором запуске

Интерактивные задачи с двойным запуском

  • Стадия 0 – первое интерактивное взаимодействие
  • Стадия 1 – второе интерактивное взаимодействие

Задачи с двойным запуском, причём первый из них – интерактивный

  • Стадия 0 – интерактивное взаимодействие
  • Стадия 1 – проверка ответа участника на втором запуске

Интерактивные задачи с двойным запуском

  • Стадия 0 – подготовка теста для интерактивного взаимодействия
  • Стадия 1 – интерактивное взаимодействие

Шаги с GUI

  1. Архивируйте задачу:

    ada-judge-cli problem <название задачи> zip
    
  2. Откройте вкладку :

  3. Нажмите :

  4. Выберите архив задачи

  5. Нажмите

Создание условий и разборов задач

Для создания условий и разборов задач рекомендуется использовать ada-judge-typst-templates. В репозитории находятся 2 шаблона: statements.typ для условий и editorial.typ для разборов. Шаблон использует язык Typst. Для его использования нужно вставить содержимое нужного шаблона в свой скрипт и при необходимости изменить первую строчку на

#let lang = "ru"

для того, чтобы весь текст был на русском.

Использование шаблона для условий

#template([<заголовок>], subtitle: [<подзаголовок>], 
  [ 
    // Условия задач
    #problem(
      "<название>",
      "<лимит по времени>",
      "<лимит по памяти>",
      [
        <легенда>
      ],
      input: 
      [
        <входные данные>
      ],
      output: 
      [
        <выходные данные>
      ],
      interactive_protocol: 
      [
        <протокол взаимодействия для интерактивных задач>
      ],
      first_run: 
      [
        <первый запуск для задач с двойным запуском>
      ],
      second_run: 
      [
        <второй запуск для задач с двойным запуском>
      ],
      (
        // Примеры
        [
          <входные данные>
        ],
        [
          <выходные данные>
        ],
        [
          <входные данные>
        ],
        [
          <выходные данные>
        ],
        // И так далее...
      ),
      comments:
      [
        <комментарии>
      ],
      subgroups_scoring:
      (
        // Подгруппы
        [
          <номер>
        ],
        [
          <ограничения>
        ],
        [
          <баллы>
        ],
        [
          <требуемые подгруппы>
        ]
      ),
      per_test_scoring: 
      [
        <система оценки для задач с потестовой оценкой>
      ]
    )
    // Для переноса условия следующей задачи на следующую страницу необходим #pagebreak()
  ]
)

Использование шаблона для разборов

#template([<заголовок>], subtitle: [<подзаголовок>], 
  [ 
    // Разбор задач
    #problem(
      "<название>",
      "<разбор>"
    )
    // Для переноса разбора следующей задачи на следующую страницу необходим #pagebreak()
  ]
)