На четырнадцатый день Advent of Code мы моделируем падающий песок. Я призываю вас сначала попробовать решить ее самостоятельно https://adventofcode.com.

Вход

Сегодняшние входные данные представляют собой серию сканирований, каждое из которых состоит из ряда координат, представляющих соединенные линии. Мы будем интерпретировать каждое сканирование и рисовать соответствующие линии на нашей карте, которую мы сохраняем как std::vector<std::vector<char>>.

Когда мы рисуем линии, мы также будем помнить ограничивающую рамку (минимальные и максимальные нарисованные координаты), которые нам понадобятся для обеих частей.

std::views::iota помогает нам избежать утомительной арифметики индексов.

Бросать песок в пустоту

В первой части мы предполагаем, что наши сканы существуют в пустоте, и нам нужно определить, сколько песчинок застрянет, прежде чем они начнут падать в пустоту.

Поскольку мы запомнили ограничивающую рамку, мы можем использовать ее, чтобы определить, когда кусок песка попал в пустоту. Кроме этого, мы итерируем, перемещая кусок песка в соответствии с правилами и обнаруживая, когда он застревает.

Высыпание песка на пол

Во второй части у нас есть виртуальный пол, который расположен на два ниже максимальной координаты глубины, и мы останавливаемся, как только песчинка застревает в начальной координате (0,500).

Мы можем повторно использовать большую часть решения для первой части, однако вместо того, чтобы определять, когда песок попадает в пустоту, мы определяем, когда он застревает на полу.

Ссылки

Репозиторий с полным решением (включая парсинг ввода) доступен здесь: https://github.com/HappyCerberus/moderncpp-aoc-2022.

Я ежедневно размещаю контент на современном C++ в Twitter, LinkedIn, Mastodon, Medium и Substack.