back to switch :)
This commit is contained in:
parent
cdfff42f45
commit
675a73ddd3
66
day23.cpp
66
day23.cpp
|
@ -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, {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user