back to switch :)

This commit is contained in:
Eric Mertens 2022-11-06 10:53:26 -08:00
parent cdfff42f45
commit 675a73ddd3

View File

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