Moved day 16 graph construction into own method

This commit is contained in:
Stefan Müller 2025-05-05 19:06:51 +02:00
parent 4302a7b2f7
commit 7f0b70c8ef
2 changed files with 35 additions and 30 deletions

View File

@ -36,6 +36,7 @@ class ReindeerMaze
static constexpr char getEndChar(); static constexpr char getEndChar();
static constexpr char getWallChar(); static constexpr char getWallChar();
static constexpr int getTurnCost(); static constexpr int getTurnCost();
void buildPathSegmentGraph(WeightedEdgeGraph& graph, const int entry, const int exit);
void initializeWorkList(std::list<ReindeerMazeCrossing>& crossings, const int entryVertex); void initializeWorkList(std::list<ReindeerMazeCrossing>& crossings, const int entryVertex);
void addCheckedIncidence(std::vector<ReindeerMazePathIncidence>& incidences, const Point2 start, void addCheckedIncidence(std::vector<ReindeerMazePathIncidence>& incidences, const Point2 start,
const Point2 direction); const Point2 direction);

View File

@ -32,11 +32,38 @@ const int ReindeerMaze::getPuzzleDay() const
void ReindeerMaze::finish() void ReindeerMaze::finish()
{ {
// Initializes the graph of path segment incidences.
WeightedEdgeGraph graph{}; WeightedEdgeGraph graph{};
auto entry = graph.addVertex(); auto entry = graph.addVertex();
auto exit = graph.addVertex(); auto exit = graph.addVertex();
buildPathSegmentGraph(graph, entry, exit);
part1 = graph.dijkstra(entry, exit) / 2;
}
constexpr char ReindeerMaze::getStartChar()
{
return 'S';
}
constexpr char ReindeerMaze::getEndChar()
{
return 'E';
}
constexpr char ReindeerMaze::getWallChar()
{
return '#';
}
constexpr int ReindeerMaze::getTurnCost()
{
return 1000;
}
// Constructs the graph of path segment incidences, starting with a graph that already contains the entry and the exit
// vertices.
void ReindeerMaze::buildPathSegmentGraph(WeightedEdgeGraph& graph, const int entry, const int exit)
{
// Uses list for work items to prevent invalidation of iterators on add. // Uses list for work items to prevent invalidation of iterators on add.
std::list<ReindeerMazeCrossing> crossings{}; std::list<ReindeerMazeCrossing> crossings{};
initializeWorkList(crossings, entry); initializeWorkList(crossings, entry);
@ -56,8 +83,8 @@ void ReindeerMaze::finish()
int nNext{ 0 }; int nNext{ 0 };
while (getCharAt(position) != getEndChar() && while (getCharAt(position) != getEndChar() &&
std::find_if(crossings.begin(), crossings.end(), std::find_if(crossings.begin(), crossings.end(),
[position](auto& x) { return x.getPosition() == position; }) == crossings.end()) [position](auto& x) { return x.getPosition() == position; }) == crossings.end())
{ {
nNext = 0; nNext = 0;
Point2 nextPosition, nextDirection; Point2 nextPosition, nextDirection;
@ -143,10 +170,9 @@ void ReindeerMaze::finish()
// Determines the end crossing of the new path segment and its incidence. // Determines the end crossing of the new path segment and its incidence.
std::list<ReindeerMazeCrossing>::iterator endCrossing; std::list<ReindeerMazeCrossing>::iterator endCrossing;
std::vector<ReindeerMazePathIncidence>::iterator endIncidence; std::vector<ReindeerMazePathIncidence>::iterator endIncidence;
endCrossing = nNext == 1 endCrossing = nNext == 1 ? endCrossing = std::find_if(crossings.begin(), crossings.end(),
? endCrossing = std::find_if(crossings.begin(), crossings.end(), [position](auto& x) { return x.getPosition() == position; })
[position](auto& x) { return x.getPosition() == position; }) : --crossings.end();
: --crossings.end();
if (endCrossing != crossings.end()) if (endCrossing != crossings.end())
{ {
// This incidence must exist, no need to check the incidence iterator. // This incidence must exist, no need to check the incidence iterator.
@ -168,7 +194,7 @@ void ReindeerMaze::finish()
} }
// Checks if end crossing is finished. // Checks if end crossing is finished.
//checkFinishedCrossing(crossings, endCrossing); // checkFinishedCrossing(crossings, endCrossing);
if (endCrossing != crossings.end() && endCrossing->isFinished()) if (endCrossing != crossings.end() && endCrossing->isFinished())
{ {
crossings.erase(endCrossing); crossings.erase(endCrossing);
@ -181,28 +207,6 @@ void ReindeerMaze::finish()
crossings.erase(startCrossing); crossings.erase(startCrossing);
} }
} }
part1 = graph.dijkstra(entry, exit) / 2;
}
constexpr char ReindeerMaze::getStartChar()
{
return 'S';
}
constexpr char ReindeerMaze::getEndChar()
{
return 'E';
}
constexpr char ReindeerMaze::getWallChar()
{
return '#';
}
constexpr int ReindeerMaze::getTurnCost()
{
return 1000;
} }
// Initializes the work list of crossing incidences. // Initializes the work list of crossing incidences.