#include #include #include #include #include #include #include #include #include #include using namespace intcode; namespace { using Packet = std::pair; using Ethernet = std::deque>; auto BuildNetwork(Machine m) -> std::vector { auto& i = std::get(Step(m)).pos; std::vector machines; 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 } }, [&](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 auto main() -> int { std::ifstream fin { "/Users/emertens/Source/advent/inputs/2019/23.txt" }; auto machines = BuildNetwork(Machine{ParseStream(fin)}); auto ethernet = Ethernet{}; std::optional part1; std::optional part2; std::optional nat; for(;;) { if (!ethernet.empty()) { auto [dest, p] = ethernet.front(); ethernet.pop_front(); if (dest == 255) { nat = p; if (!part1) { part1 = p.second; } } else { Interact(ethernet, machines.at(dest), p); } } else if (nat) { if (nat->second == part2) { break; } part2 = nat->second; Interact(ethernet, machines[0], nat); } else { for (auto && m : machines) { Interact(ethernet, m, {}); } } } std::cout << "Part 1: " << *part1 << std::endl; std::cout << "Part 2: " << *part2 << std::endl; }