diff --git a/Aufgabe 6/CMakeLists.txt b/Aufgabe 6/CMakeLists.txt new file mode 100644 index 0000000..c2425e8 --- /dev/null +++ b/Aufgabe 6/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.31) +project(Aufgabe_6) + +set(CMAKE_CXX_STANDARD 17) + +add_executable(Aufgabe_6 main.cpp) diff --git a/Aufgabe 6/main.cpp b/Aufgabe 6/main.cpp new file mode 100644 index 0000000..00001ae --- /dev/null +++ b/Aufgabe 6/main.cpp @@ -0,0 +1,133 @@ +#include +#include +#include + +struct Point { + int x; + int y; + + Point(int x, int y) : x(x), y(y) {} + + bool isValid(int mapSizeX, int mapSizeY) { + if(x >= 0 && x < mapSizeX && y >= 0 && y < mapSizeY) { + return true; + } + return false; + } +}; + +enum Direction { + NORTH = 0, + EAST = 1, + SOUTH = 2, + WEST = 3 +}; + +struct Guard { + Point currentPosition; + Direction currentDirection; + + Guard(Point currentPosition, Direction currentDirection) : currentPosition(currentPosition), + currentDirection(currentDirection) {} +}; + +std::vector readTextFromFile(const std::string& fileName) { + std::vector lines; + std::ifstream file(fileName); + if (!file) { // Überprüft, ob die Datei geöffnet werden konnte + std::cerr << "Fehler: Datei konnte nicht geöffnet werden: " << fileName << std::endl; + return lines; + } + std::string s; + while(getline(file, s)) { + lines.push_back(s); + } + return lines; +} + +Point calcGuardPositionFromInput(const std::vector& input) { + for(int y =0; y < input.size(); y++) { + for(int x =0; x < input[y].size(); x++) { + if(input[y][x] == '^' || input[y][x] == '<' || input[y][x] == '>' || input[y][x] == 'v') { + return {x, y}; + } + } + } + return {-1,-1}; +} + +std::vector calcObstaclePositionsFromInput(const std::vector& input) { + std::vector obstaclePositions; + for(int y =0; y < input.size(); y++) { + for(int x =0; x < input[y].size(); x++) { + if(input[y][x] == '#') { + obstaclePositions.emplace_back(x, y); + } + } + } + return obstaclePositions; +} + +Point calcUpdatedGuardPosition(Point& currentPosition, Direction direction) { + int x = currentPosition.x; + int y = currentPosition.y; + switch (direction) { + case NORTH: + y--; + break; + case WEST: + x--; + break; + case SOUTH: + y++; + break; + case EAST: + x++; + break; + } + return {x, y}; +} + +bool hasGuardReachedObstacle(Point guardPosition, const std::vector& map) { + for(Point obstacles : map) { + if(obstacles.x == guardPosition.x && obstacles.y == guardPosition.y) { + return true; + } + } + return false; +} + +std::vector calcGuardPositions(Guard& guard, const std::vector& map, int mapSizeX, int mapSizeY) { + std::vector guardPositions; + while(guard.currentPosition.isValid(mapSizeX, mapSizeY)) { + bool duplicated = false; + for(const auto& currentPos : guardPositions) { + if(currentPos.x == guard.currentPosition.x && currentPos.y == guard.currentPosition.y) { + duplicated = true; + } + } + + if(!duplicated) { + guardPositions.push_back(guard.currentPosition); + } + + Point nextPosition = calcUpdatedGuardPosition(guard.currentPosition, guard.currentDirection); + if(hasGuardReachedObstacle(nextPosition, map)) { + guard.currentDirection = static_cast((guard.currentDirection + 1) % 4); + } else { + guard.currentPosition = nextPosition; + } + } + return guardPositions; +} + +int main() { + std::vector input = readTextFromFile("../input.txt"); + Point initialGuardPos = calcGuardPositionFromInput(input); + std::vector obstaclePositions = calcObstaclePositionsFromInput(input); + Guard guard = Guard(initialGuardPos, NORTH); + auto visitedPoints = calcGuardPositions(guard, obstaclePositions, input[0].size(), input.size()); + + std::cout << "The guard visited " << visitedPoints.size() << " points!" << std::endl; + return 0; +}