114 lines
3.0 KiB
C++
114 lines
3.0 KiB
C++
// Solutions to the Advent Of Code 2024.
|
|
// Copyright (C) 2024-2025 Stefan Müller
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify it under
|
|
// the terms of the GNU General Public License as published by the Free Software
|
|
// Foundation, either version 3 of the License, or (at your option) any later
|
|
// version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful, but WITHOUT
|
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License along with
|
|
// this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#include <aoc/HoofIt.hpp>
|
|
|
|
#include <memory>
|
|
#include <queue>
|
|
#include <vector>
|
|
|
|
#include <aoc/Grid.hpp>
|
|
#include <aoc/Point2.hpp>
|
|
|
|
const std::string HoofIt::getPuzzleName() const
|
|
{
|
|
return "Day 10: Hoof It";
|
|
}
|
|
|
|
const std::string HoofIt::getInputFileName() const
|
|
{
|
|
return "hoof_it.txt";
|
|
}
|
|
|
|
void HoofIt::finish()
|
|
{
|
|
std::queue<Point2> queue{};
|
|
Grid<std::vector<Point2>> trailEndsMap{ lines.size(), lines[0].size() };
|
|
Grid<int> trailScoreMap{ lines.size(), lines[0].size() };
|
|
|
|
for (int j = 0; j < lines.size(); j++)
|
|
{
|
|
for (int i = 0; i < lines[j].size(); i++)
|
|
{
|
|
trailScoreMap[j][i] = 0;
|
|
if (lines[j][i] == getTrailTopChar())
|
|
{
|
|
Point2 trailEnd{ i, j };
|
|
trailEndsMap[j][i].push_back(trailEnd);
|
|
trailScoreMap[j][i] = 1;
|
|
queue.push(trailEnd);
|
|
}
|
|
}
|
|
}
|
|
|
|
while (!queue.empty())
|
|
{
|
|
auto trail = queue.front();
|
|
queue.pop();
|
|
if (getCharAt(trail) != getTrailheadChar())
|
|
{
|
|
for (auto direction : Point2::cardinalDirections)
|
|
{
|
|
Point2 p{ trail + direction };
|
|
if (isInBounds(p) && getCharAt(p) + 1 == getCharAt(trail))
|
|
{
|
|
if (trailEndsMap[p.y][p.x].empty())
|
|
{
|
|
queue.push(p);
|
|
}
|
|
addUnique(trailEndsMap.cell(trail), trailEndsMap.cell(p));
|
|
trailScoreMap.cell(p) += trailScoreMap.cell(trail);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
part1 += trailEndsMap.cell(trail).size();
|
|
part2 += trailScoreMap.cell(trail);
|
|
}
|
|
}
|
|
}
|
|
|
|
constexpr char HoofIt::getTrailheadChar()
|
|
{
|
|
return '0';
|
|
}
|
|
|
|
constexpr char HoofIt::getTrailTopChar()
|
|
{
|
|
return '9';
|
|
}
|
|
|
|
void HoofIt::addUnique(const std::vector<Point2>& source, std::vector<Point2>& destination)
|
|
{
|
|
for (auto end : source)
|
|
{
|
|
auto isUnique{ true };
|
|
size_t i{ 0 };
|
|
while (isUnique && i < destination.size())
|
|
{
|
|
if (end == destination[i])
|
|
{
|
|
isUnique = false;
|
|
}
|
|
i++;
|
|
}
|
|
if (isUnique)
|
|
{
|
|
destination.push_back(end);
|
|
}
|
|
}
|
|
}
|