#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; }; 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; 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 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; }