#include #include #include #include #include #include #include #include #include struct Position { // NOTE(dev): Could do enum empty/reached/blocked, but I'm not interested. bool blocked = false; bool reached = false; }; enum Direction { UP = 0, RIGHT, DOWN, LEFT }; struct Player { std::pair location; Direction direction = Direction::UP; }; int main() { const std::string filename = "data.txt"; std::ifstream ifs(filename); if(!ifs.is_open()) { std::cerr << "Missing " << filename << "." << std::endl; return -1; } unsigned long total = 0; unsigned long total_pt2 = 0; std::map, Position> level; Player player; int max_x = 0; int max_y = 0; bool first_row = true; int y = 0; auto DebugPrint = [&]() { std::cout << std::endl; for(auto y = 0; y < max_y; ++y) { for(auto x = 0; x < max_x; ++x) { if(player.location.first == x && player.location.second == y) { switch(player.direction) { case Direction::UP: std::cout << "^"; break; case Direction::RIGHT: std::cout << ">"; break; case Direction::DOWN: std::cout << "v"; break; case Direction::LEFT: std::cout << "<"; break; }; } else { const auto &pos = level[{x, y}]; if(pos.reached) std::cout << "X"; else if(pos.blocked) std::cout << "#"; else std::cout << "."; } } std::cout << std::endl; } }; // Parse Input for(std::string line; std::getline(ifs, line); ) { if(line == "") continue; int x = 0; for(const char &value : line) { Position pos; if(value == '#') pos.blocked = true; if(value == '^') // always up? { pos.reached = true; player.location = {x, y}; } level[{x, y}] = pos; ++x; } if(first_row) { max_x = x; first_row = false; } ++y; } max_y = y; // DEBUG: DebugPrint(); std::cout << std::endl; // while(player.location.first >= 0 && player.location.first < max_x && // player.location.second >= 0 && player.location.second < max_y) while(true) { std::pair next_location = player.location; switch(player.direction) { case Direction::UP: --next_location.second; break; case Direction::RIGHT: ++next_location.first; break; case Direction::DOWN: ++next_location.second; break; case Direction::LEFT: --next_location.first; break; }; if(!level.contains(next_location)) { player.location = next_location; break; } if(level[next_location].blocked) player.direction = static_cast(((int(player.direction)) + 1) % 4); else { level[next_location].reached = true; player.location = next_location; // DebugPrint(); // usleep(20000); } } DebugPrint(); for(auto y = 0; y < max_y; ++y) for(auto x = 0; x < max_x; ++x) if(level[{x,y}].reached) ++total; std::cout << std::endl; std::cout << " Total: " << total << std::endl; std::cout << "PT2 Total: " << total_pt2 << std::endl; return 0; }