#include #include #include #include #include #include #include #include #include #include auto Part1(aocpp::Grid const &input) -> std::int64_t { std::unordered_set infected; // Initialize set of infected locations input.each([&infected](auto const pos, auto const cell) { if (cell == '#') { infected.insert(pos); } }); // Start in the middle aocpp::Coord pos; pos.x = input.Cols() / 2; pos.y = input.Rows() / 2; // Start going "up" aocpp::Coord vel{.x = 0, .y = -1}; // Count the number of iterations that cause an infection std::uint64_t infections = 0; for (int i = 0; i < 10'000; ++i) { auto const it = infected.find(pos); if (it == end(infected)) { // was clean vel = CCW(vel); // turn "left" infected.insert(pos); // infect infections++; } else { // was infected vel = CW(vel); // turn "right" infected.erase(it); // clean } pos += vel; // advance } return infections; } auto Part2(aocpp::Grid const &input) -> std::int64_t { std::unordered_map cells; // Initialize set of infected locations input.each([&cells](auto const pos, auto const cell) { if (cell == '#') { cells.try_emplace(pos, '#'); } }); // Start in the middle aocpp::Coord pos; pos.x = input.Cols() / 2; pos.y = input.Rows() / 2; // Start going "up" aocpp::Coord vel{.x = 0, .y = -1}; // Count the number of iterations that cause an infection std::uint64_t infections = 0; for (int i = 0; i < 10'000'000; ++i) { auto const [it, added] = cells.try_emplace(pos, 'W'); // clean becomes weakened if (added) { // already inserted 'W' vel = CCW(vel); // turn "left" } else { switch (it->second) { case 'W': // no turn it->second = '#'; infections++; break; case '#': vel = CW(vel); // turn "right" it->second = 'F'; break; case 'F': vel = Turn180(vel); cells.erase(it); // clean break; default: throw std::logic_error{"unexpected cell in steps"}; } } pos += vel; // advance } return infections; } TEST_SUITE("2017-22 examples") { TEST_CASE("part 1") { } TEST_CASE("part 2") { } } auto Main(std::istream &in, std::ostream &out) -> void { auto const input = aocpp::Grid::Parse(in); out << "Part 1: " << Part1(input) << std::endl; out << "Part 2: " << Part2(input) << std::endl; }