#include #include #include using namespace std; void readInput(vector &mappedArea, pair &startingPosition) { string line; for (size_t rowIndex = 0; getline(cin, line); rowIndex++) { for (size_t colIndex = 0; colIndex < line.size(); colIndex++) { if (line[colIndex] == '^') { startingPosition = {rowIndex, colIndex}; } } mappedArea.push_back(line); } } 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, Direction ¤tDirection, set> *distinctPositions = nullptr) { const vector> directions = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; pair nextPosition = {currentPosition.first + directions[currentDirection].first, currentPosition.second + directions[currentDirection].second}; if (isOutOfBounds(mappedArea, nextPosition)) { return false; } if (isObstacle(mappedArea, nextPosition)) { currentDirection = static_cast((currentDirection + 1) % 4); return true; } 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 startingPosition; Direction startingDirection = UP; readInput(mappedArea, startingPosition); pair currentPosition = startingPosition; Direction currentDirection = startingDirection; set> distinctPositions = {currentPosition}; while (takeStep(mappedArea, currentPosition, currentDirection, &distinctPositions)) ; int numberOfDistinctPositions = distinctPositions.size(); int numberOfLoopCausingObstructions = 0; for (const pair &obstructionPosition : distinctPositions) { numberOfLoopCausingObstructions += isLoopCausingObstruction(obstructionPosition, mappedArea, startingPosition, startingDirection); } // Part one cout << "Number of distinct positions visited before leaving: " << numberOfDistinctPositions << endl; // Part two cout << "Number of potential obstructions to create a loop: " << numberOfLoopCausingObstructions << endl; }