diff --git a/2024/6/main.cpp b/2024/6/main.cpp index eb824ed..4841463 100644 --- a/2024/6/main.cpp +++ b/2024/6/main.cpp @@ -8,12 +8,6 @@ #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, @@ -21,6 +15,36 @@ enum Direction { LEFT }; +struct Position { + // NOTE(dev): Could do enum empty/reached/blocked, but I'm not interested. + bool blocked = false; + std::map reached; + + bool Reached() const { + return reached.size(); + } + char ReachedChar() const { + bool up_or_down = false; + bool left_or_right = false; + if(reached.contains(Direction::UP) || reached.contains(Direction::DOWN)) + up_or_down = true; + if(reached.contains(Direction::LEFT) || reached.contains(Direction::RIGHT)) + left_or_right = true; + + if(up_or_down != left_or_right) + { + if(up_or_down) + return '|'; + else + return '-'; + } + else if(up_or_down) + return '+'; + else + return ' '; + }; +}; + struct Player { std::pair location; Direction direction = Direction::UP; @@ -28,7 +52,7 @@ struct Player { int main() { - const std::string filename = "data.txt"; + const std::string filename = "data_test.txt"; std::ifstream ifs(filename); if(!ifs.is_open()) { @@ -75,8 +99,8 @@ int main() else { const auto &pos = level[{x, y}]; - if(pos.reached) - std::cout << "X"; + if(pos.Reached()) + std::cout << pos.ReachedChar(); else if(pos.blocked) std::cout << "#"; else @@ -85,6 +109,9 @@ int main() } std::cout << std::endl; } + + std::cout << std::endl; + std::cout << "PT2 Total: " << total_pt2 << std::endl; }; // Parse Input @@ -101,7 +128,7 @@ int main() pos.blocked = true; if(value == '^') // always up? { - pos.reached = true; + pos.reached[Direction::UP] = true; player.location = {x, y}; } @@ -123,8 +150,6 @@ int main() 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; @@ -150,13 +175,90 @@ int main() break; } if(level[next_location].blocked) + { + // NOTE(dev): Also check if the next potential position is the last space before a turn, + // as then the up/down or left/right flag wouldn't be set, but the + // left/right or up/down flag would be. + level[player.location].reached[player.direction] = true; player.direction = static_cast(((int(player.direction)) + 1) % 4); + level[player.location].reached[player.direction] = true; + } else { - level[next_location].reached = true; + // TODO(dev): Need to handle the scenario where you've yet to explore a section but it + // would result in a loop. + // e.g.: Placing a stopping point at the O + // + // # # + // +->O # + // #| # + // S # # + // # # + // # # + // + // IDEA: Follow turns when exploring a direction like that. Snake your way until + // you fall off the map or you line up with a square you've been in before + std::map could_loop; + // Part 2: If you could loop in this next position, COUNT IT + if(player.direction == Direction::DOWN) + { + // search left of new position to see if you've been in this horizontal bit: + for(int x = next_location.first; x >= 0; --x) + { + std::pair potential_position = { x, next_location.second }; + if(level[potential_position].reached.contains(Direction::LEFT)) + { + could_loop[Direction::LEFT] = true; + break; + } + } + } + else if(player.direction == Direction::UP) + { + // search right of new position to see if you've been in this horizontal bit: + for(int x = next_location.first; x < max_x; ++x) + { + std::pair potential_position = { x, next_location.second }; + if(level[potential_position].reached.contains(Direction::RIGHT)) + { + could_loop[Direction::RIGHT] = true; + break; + } + } + } + else if(player.direction == Direction::LEFT) + { + // search left of new position to see if you've been in this horizontal bit: + for(int y = next_location.second; y >= 0; --y) + { + std::pair potential_position = { next_location.first, y }; + if(level[potential_position].reached.contains(Direction::UP)) + { + could_loop[Direction::UP] = true; + break; + } + } + } + else + { + // search left of new position to see if you've been in this horizontal bit: + for(int y = next_location.second; y < max_y; ++y) + { + std::pair potential_position = { next_location.first, y }; + if(level[potential_position].reached.contains(Direction::DOWN)) + { + could_loop[Direction::DOWN] = true; + break; + } + } + } + total_pt2 += could_loop.size(); + + level[next_location].reached[player.direction] = true; player.location = next_location; - // DebugPrint(); - // usleep(20000); + + DebugPrint(); + usleep(500000); } } @@ -164,7 +266,7 @@ int main() for(auto y = 0; y < max_y; ++y) for(auto x = 0; x < max_x; ++x) - if(level[{x,y}].reached) + if(level[{x,y}].Reached()) ++total; std::cout << std::endl;