advent-of-code/2024/day06/part1.cc
2024-12-21 05:43:19 +00:00

106 lines
2.1 KiB
C++

#include <iostream>
#include <vector>
#include <string>
class vec {
public:
int x;
int y;
vec(int x, int y) : x(x), y(y) {}
vec operator+(const vec& other) const;
int index(int width) const;
vec right() const;
};
vec vec::operator+(const vec& other) const {
return vec{x + other.x, y + other.y};
}
int vec::index(int width) const {
return y * width + x;
}
vec vec::right() const {
return vec{-y, x};
}
class grid {
int width;
int height;
std::vector<bool> obstacles;
std::vector<bool> visited;
int visit_count = 0;
public:
grid(int width, int height);
bool visit(const vec& v);
void obstacle(const vec& v);
bool is_obstacle(const vec& v) const;
bool is_valid(const vec& v) const;
int count() const;
};
grid::grid(int width, int height)
: width(width), height(height) {
obstacles.resize(width * height);
visited.resize(width * height);
}
bool grid::visit(const vec& v) {
if (visited[v.index(width)]) {
return true;
}
visited[v.index(width)] = true;
visit_count++;
return false;
}
void grid::obstacle(const vec& v) {
obstacles[v.index(width)] = true;
}
bool grid::is_obstacle(const vec& v) const {
return obstacles.at(v.index(width));
}
bool grid::is_valid(const vec& v) const {
return v.x >= 0 && v.x < width
&& v.y >= 0 && v.y < height;
}
int grid::count() const {
return visit_count;
}
int main() {
int width = 0, height = 0;
std::string line;
std::vector<vec> obstacles;
vec pos{0, 0};
vec dir{0, -1};
for (int line_num = 0; getline(std::cin, line); line_num++) {
height++;
for (int x = 0; x < line.size(); x++) {
if (line[x] == '#') {
obstacles.emplace_back(x, line_num);
} else if (line[x] == '^') {
pos = vec{x, line_num};
}
}
}
width = line.size();
grid g{width, height};
for (const vec& v : obstacles) {
g.obstacle(v);
}
for (;; pos = pos + dir) {
g.visit(pos);
if (!g.is_valid(pos + dir)) {
break;
}
while (g.is_obstacle(pos + dir)) {
dir = dir.right();
}
}
std::cout << g.count() << std::endl;
return EXIT_SUCCESS;
}