From 38f737d72d044816e37d7ec1d12f2bc62ada8a52 Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Tue, 24 Dec 2024 22:33:21 +0100 Subject: [PATCH] Solve 2024 day 6 part 2 --- 2024/day-06/main.cpp | 114 ++++++++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 38 deletions(-) diff --git a/2024/day-06/main.cpp b/2024/day-06/main.cpp index 19fc854..ed9adf6 100644 --- a/2024/day-06/main.cpp +++ b/2024/day-06/main.cpp @@ -1,4 +1,5 @@ #include +#include #include using namespace std; @@ -16,67 +17,104 @@ void readInput(vector &mappedArea, pair &startingPosition) } } +bool isOutOfBounds(const vector &mappedArea, const pair &position) +{ + return (position.first < 0 || position.first >= mappedArea.size()) + || (position.second < 0 || position.second >= mappedArea[0].size()); +} + +bool isObstacle(const vector &mappedArea, const pair &position) +{ + char cell = mappedArea[position.first][position.second]; + return cell == '#' || cell == 'O'; +} + +enum Direction { UP = 0, RIGHT, DOWN, LEFT }; + bool takeStep(vector &mappedArea, pair ¤tPosition, - int ¤tOrientation, - int &distinctPositionCount) + Direction ¤tDirection, + set> *distinctPositions = nullptr) { - pair nextPosition = currentPosition; + const vector> directions = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; + pair nextPosition = {currentPosition.first + directions[currentDirection].first, + currentPosition.second + directions[currentDirection].second}; - switch (currentOrientation) { - case 0: - nextPosition.first--; - break; - case 1: - nextPosition.second++; - break; - case 2: - nextPosition.first++; - break; - case 3: - nextPosition.second--; - break; - default: - break; - } - - if ((nextPosition.first >= mappedArea.size() || nextPosition.first < 0) - || (nextPosition.second >= mappedArea.front().size() || nextPosition.second < 0)) { - mappedArea[currentPosition.first][currentPosition.second] = '#'; + if (isOutOfBounds(mappedArea, nextPosition)) { return false; } - if (mappedArea[nextPosition.first][nextPosition.second] == '#') { - currentOrientation = ++currentOrientation % 4; - return takeStep(mappedArea, currentPosition, currentOrientation, distinctPositionCount); + if (isObstacle(mappedArea, nextPosition)) { + currentDirection = static_cast((currentDirection + 1) % 4); + return true; } - distinctPositionCount += !(mappedArea[nextPosition.first][nextPosition.second] == 'X'); + if (distinctPositions && mappedArea[nextPosition.first][nextPosition.second] != 'X') { + distinctPositions->insert({nextPosition.first, nextPosition.second}); + } mappedArea[currentPosition.first][currentPosition.second] = 'X'; mappedArea[nextPosition.first][nextPosition.second] = '^'; - currentPosition = nextPosition; return true; } +bool isLoopCausingObstruction(const pair &obstructionPosition, + vector mappedArea, + pair currentPosition, + Direction currentDirection) +{ + if (obstructionPosition == currentPosition) { + return false; + } + + mappedArea[obstructionPosition.first][obstructionPosition.second] = 'O'; + + set> states; + states.insert({currentPosition.first, currentPosition.second, currentDirection}); + + while (takeStep(mappedArea, currentPosition, currentDirection)) { + tuple currentState = {currentPosition.first, + currentPosition.second, + currentDirection}; + + if (states.count(currentState)) { + return true; + } + + states.insert(currentState); + } + + return false; +} + int main() { vector mappedArea; - pair currentPosition; - readInput(mappedArea, currentPosition); + pair startingPosition; + Direction startingDirection = UP; + readInput(mappedArea, startingPosition); - int currentOrientation = 0; - int distinctPositionCount = 1; - while (takeStep(mappedArea, currentPosition, currentOrientation, distinctPositionCount)) + pair currentPosition = startingPosition; + Direction currentDirection = startingDirection; + set> distinctPositions = {currentPosition}; + while (takeStep(mappedArea, currentPosition, currentDirection, &distinctPositions)) ; + int numberOfDistinctPositions = distinctPositions.size(); - for (auto row : mappedArea) { - cout << row << endl; + int numberOfLoopCausingObstructions = 0; + for (const pair &obstructionPosition : distinctPositions) { + numberOfLoopCausingObstructions += isLoopCausingObstruction(obstructionPosition, + mappedArea, + startingPosition, + startingDirection); } - cout << endl; // Part one - cout << "How many distinct positions will the guard visit before leaving the mapped area? " - << distinctPositionCount << endl; + cout << "Number of distinct positions visited before leaving: " << numberOfDistinctPositions + << endl; + + // Part two + cout << "Number of potential obstructions to create a loop: " << numberOfLoopCausingObstructions + << endl; }