AdventOfCode2024/Aufgabe 6/main.cpp
2024-12-11 20:49:19 +01:00

134 lines
3.8 KiB
C++

#include <iostream>
#include <vector>
#include <fstream>
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<std::string> readTextFromFile(const std::string& fileName) {
std::vector<std::string> 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<std::string>& 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<Point> calcObstaclePositionsFromInput(const std::vector<std::string>& input) {
std::vector<Point> 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<Point>& map) {
for(Point obstacles : map) {
if(obstacles.x == guardPosition.x && obstacles.y == guardPosition.y) {
return true;
}
}
return false;
}
std::vector<Point> calcGuardPositions(Guard& guard, const std::vector<Point>& map, int mapSizeX, int mapSizeY) {
std::vector<Point> 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<Direction>((guard.currentDirection + 1) % 4);
} else {
guard.currentPosition = nextPosition;
}
}
return guardPositions;
}
int main() {
std::vector<std::string> input = readTextFromFile("../input.txt");
Point initialGuardPos = calcGuardPositionFromInput(input);
std::vector<Point> 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;
}