diff --git a/day23.cpp b/day23.cpp index f1b484e..4d33971 100644 --- a/day23.cpp +++ b/day23.cpp @@ -13,37 +13,43 @@ using namespace intcode; namespace { -using Packet = std::pair; -using Ethernet = std::deque>; +struct Payload { ValueType x, y; }; +struct Packet { ValueType destination; Payload payload; }; +using Ethernet = std::deque; auto BuildNetwork(Machine m) -> std::vector { - auto& i = std::get(Step(m)).pos; std::vector machines; + auto& i = std::get(Step(m)).pos; for (i = 0; i < 50; i++) { machines.push_back(m); } return machines; } -auto Interact(Ethernet & ethernet, Machine & m, std::optional p) -> void { - std::visit(overloaded{ - [&](Input i) { - if (p) { - i.pos = p->first; - StepInput(m, p->second); - Interact(ethernet, m, {}); - } else { - i.pos = -1; // no packet +auto Interact(Ethernet & ethernet, Machine & m, std::optional p) -> void { + for(;;) { + auto e = Step(m); + switch (e.index()) { + default: throw std::runtime_error{"unexpected halt"}; + case 0: { + auto& i = std::get<0>(e).pos; + if (p) { + i = p->x; + StepInput(m, p->y); + p = {}; + break; + } + i = -1; // no packet + return; + } + case 1: { + auto d = std::get<1>(e).val; + auto x = StepOutput(m); + auto y = StepOutput(m); + ethernet.push_back({d, {x,y}}); + } } - }, - [&](Output d) { - auto x = StepOutput(m); - auto y = StepOutput(m); - ethernet.push_back({d.val, {x,y}}); - Interact(ethernet, m, p); - }, - [](Halt) -> void { throw std::runtime_error{"unexpected halt"}; }, - }, Step(m)); + } } } // namespace @@ -55,24 +61,24 @@ auto main() -> int { std::optional part1; std::optional part2; - std::optional nat; + std::optional nat; for(;;) { if (!ethernet.empty()) { - auto [dest, p] = ethernet.front(); + auto packet = ethernet.front(); ethernet.pop_front(); - if (dest == 255) { - nat = p; - if (!part1) { part1 = p.second; } + if (packet.destination == 255) { + nat = packet.payload; + if (!part1) { part1 = packet.payload.y; } } else { - Interact(ethernet, machines.at(dest), p); + Interact(ethernet, machines.at(packet.destination), packet.payload); } } else if (nat) { - if (nat->second == part2) { break; } - part2 = nat->second; + if (part2 == nat->y) { break; } + part2 = nat->y; Interact(ethernet, machines[0], nat); } else { - for (auto && m : machines) { + for (auto & m : machines) { Interact(ethernet, m, {}); } }