From f74a1558f1f4234bf120616b22045f2fb6c02484 Mon Sep 17 00:00:00 2001 From: Naomi Amethyst Date: Sat, 21 Dec 2024 06:22:38 +0000 Subject: [PATCH] +day06 part2 --- 2024/day06/part2.cc | 130 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 2024/day06/part2.cc diff --git a/2024/day06/part2.cc b/2024/day06/part2.cc new file mode 100644 index 0000000..8dd6fd6 --- /dev/null +++ b/2024/day06/part2.cc @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include + +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; + auto operator<=>(const vec&) const = default; +}; + +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 obstacles; + std::vector visited_pos; + std::set> visited; +public: + grid(int width, int height); + bool visit(const vec& v, const vec& dir); + void obstacle(const vec& v); + bool is_obstacle(const vec& v) const; + bool is_valid(const vec& v) const; + bool is_visited(const vec& v) const; +}; + +grid::grid(int width, int height) + : width(width), height(height) { + obstacles.resize(width * height); + visited_pos.resize(width * height); +} + +bool grid::visit(const vec& v, const vec& dir) { + visited_pos[v.index(width)] = true; + return visited.emplace(v, dir).second; +} + +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; +} + +bool grid::is_visited(const vec& v) const { + return visited_pos.at(v.index(width)); +} + +bool is_loop(grid& g, vec pos, vec dir) { + for (;; pos = pos + dir) { + if (!g.is_valid(pos + dir)) { + return false; + } + while (g.is_obstacle(pos + dir)) { + dir = dir.right(); + } + if (!g.visit(pos, dir)) { + return true; + } + } +} + +int main() { + int width = 0, height = 0, count = 0; + std::string line; + std::vector obstacles; + std::set counted; + 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); + } + grid tmp{width, height}; + for (;; pos = pos + dir) { + if (!g.is_valid(pos + dir)) { + break; + } + while (g.is_obstacle(pos + dir)) { + dir = dir.right(); + } + if (!g.is_visited(pos + dir)) { + tmp = g; + tmp.obstacle(pos + dir); + if (is_loop(tmp, pos, dir)) { + if (counted.emplace(pos + dir).second) { + count++; + } + } + } + g.visit(pos, dir); + } + std::cout << count << std::endl; + return EXIT_SUCCESS; +}