SandPile
Модель песчаной кучи: обвалы по итерациям на растущей сетке и сохранение состояний в 4-битные BMP. Своя динамическая память под сетку и своя запись BMP — без сторонних библиотек и контейнеров.
Дальше мягкие дедлайны: deadline_1 до 16.11 (×0.85), deadline_2 до 23.11 (×0.65), deadline_3 с 24.11 (×0.5).
Войти, чтобы записаться на сдачуЗадание
Консольное приложение, которое моделирует абелеву песчаную кучу: читает начальное состояние из TSV-файла, шаг за шагом обваливает кучи на растущей сетке и сохраняет состояния картинками в BMP. Сетку храните в своей динамической памяти, BMP пишете сами — без сторонних библиотек и стандартных контейнеров.
is-itmo-c-26, репозиторий labwork3-<ваш GitHub-логин>. Каркаса нет — в репозитории только условие, примеры входных данных в input/ и CI. Структуру проекта и сборку на CMake придумываете сами.Аргументы командной строки
| Короткий | Длинный | Что задаёт | По умолчанию |
|---|---|---|---|
-i | --input | TSV-файл с начальным состоянием | обязательный |
-o | --output | папка для картинок; если её нет, программа создаёт её сама | обязательный |
-m | --max-iter | максимум итераций; при 0 итерации не выполняются, начальное состояние сохраняется как итоговое | до стабилизации |
-f | --freq | через сколько итераций сохранять картинку | 0 — только последнее состояние |
--max-iter и --freq — целые неотрицательные числа. На неизвестный аргумент, отсутствие обязательного или некорректное значение программа пишет сообщение об ошибке и завершается с ненулевым кодом.
cmake -B build
cmake --build build
./build/labwork3 --input input/fractal.tsv --output outПуть к бинарнику зависит от вашего CMakeLists.txt, здесь — для примера.
Начальное состояние
Каждая строка TSV — одна непустая ячейка: координата x, координата y и число песчинок, через табуляцию. Координаты помещаются в int16_t и бывают отрицательными, число песчинок — в uint64_t.
0 0 4
-2 -1 16
2 1 12Начальная сетка — минимальный прямоугольник, в который попадают все перечисленные ячейки; остальные ячейки внутри него пустые. Для файла выше это , , то есть 5 × 3.
Правила модели
- Песчинки добавляются только при инициализации.
- За одну итерацию каждая ячейка, в которой в начале итерации было не меньше 4 песчинок, обваливается ровно один раз: теряет 4 песчинки и отдаёт по одной соседям сверху, снизу, слева и справа.
- Состояние после итерации зависит только от состояния в начале итерации. Песчинки, пришедшие от соседей, учитываются только на следующей итерации.
- Если при обвале песчинка выходит за край сетки, сетка расширяется в эту сторону.
- Модель стабильна, когда в каждой ячейке меньше 4 песчинок.
Программа останавливается, когда модель стабильна или выполнено --max-iter итераций.
Самый маленький пример — single-pile.tsv, 4 песчинки в точке (0, 0). За одну итерацию сетка 1 × 1 расширяется во все стороны до 3 × 3 и становится стабильной:
до: 4 после: 0 1 0
1 0 1
0 1 0Сохранение состояний
- Итерации нумеруются с 1. При
freq > 0картинки сохраняются после итерацийfreq,2 · freq,3 · freqи так далее. - Последнее состояние сохраняется всегда, даже если остановка пришлась между сохранениями. Если оно уже сохранено на последней итерации, второй раз его писать не нужно.
- При
freq = 0сохраняется только последнее состояние. - Начальное состояние отдельно не сохраняется. Но если не выполнено ни одной итерации (стабильный вход или
--max-iter 0), оно и есть последнее — его нужно сохранить.
Например, при --max-iter 10 --freq 3 картинки появятся после итераций 3, 6, 9 и 10. Как называть файлы, условие не задаёт: удобно по номеру итерации.
Формат картинки
Одна ячейка — один пиксель, размер картинки равен размеру сетки. Цвет зависит от числа песчинок:
| Песчинок | Цвет |
|---|---|
| 0 | чёрный |
| 1 | зелёный |
| 2 | фиолетовый |
| 3 | жёлтый |
| больше 3 | белый |
На пиксель отводится не больше 4 бит, поэтому подходит BMP с палитрой и глубиной цвета 4 бита.
- Файл: заголовок файла (14 байт, начинается с
BM), информационный заголовокBITMAPINFOHEADER(40 байт), палитра из 16 цветов по 4 байта (синий, зелёный, красный, ноль), затем пиксели. Пиксели начинаются со смещения 14 + 40 + 64 = 118 байт. - Все многобайтовые поля — little-endian. Пишите заголовок по полю, а не
writeвсей структурой: компилятор добавляет в структуры выравнивание, и в памяти они не совпадают с форматом файла. - В одном байте два пикселя: левый — в старших 4 битах.
- Длина каждой строки пикселей в файле дополняется нулями до кратной 4 байтам.
- При положительной высоте в заголовке строки идут снизу вверх: первой в файле записана нижняя строка картинки.
Примеры
Готовые файлы лежат в input/. Маленькие удобно проверять руками:
| Файл | Начальная сетка | Что происходит |
|---|---|---|
stable.tsv | 2 × 2 | уже стабильно, итераций нет — сохраняется начальное состояние |
single-pile.tsv | 1 × 1 | одна итерация, итог 3 × 3 |
multiple-piles.tsv | 5 × 3 | кучи с отрицательными координатами, итог 8 × 6 за 6 итераций |
Крупные рисуют фрактальные узоры, как на иллюстрациях в Википедии. Запускайте их без --max-iter:
| Файл | Начальное состояние | Итоговая сетка | Итераций |
|---|---|---|---|
fractal.tsv | 65 536 песчинок в (0, 0) | 189 × 189 | 62 118 |
twin-piles.tsv | по 32 768 в (-48, 0) и (48, 0) | 233 × 143 | 31 148 |
four-piles.tsv | по 16 384 в углах квадрата | 181 × 181 | 16 460 |
square.tsv | квадрат 65 × 65 от -32 до 32, по 6 песчинок в каждой ячейке | 113 × 113 | 3 165 |
Теормин
- Виртуальное адресное пространство
- Сегменты памяти программы. Стек и куча
- Стек вызовов. Длительность хранения и время жизни объектов
- Динамическая память:
malloc,calloc,realloc,free,new,delete,new[]иdelete[] - Placement new
- Ошибки работы с памятью
- Ссылки и константные ссылки. Отличия от указателей
- Передача аргументов и возврат значений. Время жизни временных объектов
- Перегрузка функций
- Аргументы функций по умолчанию
- Инициализация и присваивание. Виды инициализации
Мягкие дедлайны
| Ветка | Срок | Коэффициент |
|---|---|---|
deadline_0 | до 09.11, 23:59 | 1.0 |
deadline_1 | 10.11 — 16.11, 23:59 | 0.85 |
deadline_2 | 17.11 — 23.11, 23:59 | 0.65 |
deadline_3 | с 24.11 | 0.5 |
Максимум 12 баллов.
Требования
- Только стандартная библиотека C++, сторонние библиотеки запрещены. Чтение аргументов и запись BMP — свои.
- В приложении запрещены стандартные контейнеры (
std::vector,std::deque,std::mapи другие), строки (std::string), умные указатели, аллокаторы,std::pmr, строковые потоки (std::stringstreamи родня) иstd::valarray. - C-функции управления памятью (
malloc,calloc,realloc,free) тоже запрещены: память под сетку выделяйте черезnew[]и освобождайте черезdelete[], расширение — новый блок, копирование и освобождение старого. - Сетка хранится в динамической памяти и растёт по мере надобности. Массив заранее заданного максимального размера не подходит.
std::filesystemразрешён — пригодится, чтобы создать папку для картинок.- В собственных тестах можно GoogleTest и всю стандартную библиотеку.
- Сборка — только CMake.
- CI собирает решение
clang++-21с санитайзерами (-fsanitize=address,undefined), но готовых тестов нет, так что ловят они ошибки только в ваших тестах. Перед сдачей прогоните программу на примерах изinput/с AddressSanitizer, UndefinedBehaviorSanitizer и LeakSanitizer: выход за границы, утечки и чтение неинициализированной памяти всплывут там. - Стиль проверяет clang-tidy: функции, классы и структуры в
CamelCase, переменные вlower_case, поля классов с_на конце, константы и элементы перечислений вkCamelCase.
Как сдавать
- Создайте ветку
deadline_0отmainв своём репозитории. - Решайте в этой ветке, коммитьте небольшими логичными порциями.
- Откройте Pull Request из
deadline_0вmain. - Дождитесь отчёта CI в комментарии к PR: там результат сборки с санитайзерами и проверки стиля.
- Если сдаёте после первого дедлайна, ветка называется по дедлайну (
deadline_1,deadline_2,deadline_3), и балл умножается на его коэффициент.

Комментарии0
Пока никто ничего не написал.
Войдите, чтобы оставить комментарий