aocpp/day23.cpp

84 lines
1.9 KiB
C++
Raw Normal View History

2022-11-05 11:19:32 -07:00
#include <cstddef>
#include <deque>
#include <iostream>
#include <stdexcept>
#include <tuple>
#include <utility>
#include <variant>
#include <vector>
2022-11-06 10:07:31 -08:00
#include <fstream>
2022-11-05 11:19:32 -07:00
#include <intcode/intcode.hpp>
using namespace intcode;
namespace {
using Packet = std::pair<ValueType, ValueType>;
using Ethernet = std::deque<std::pair<std::size_t, Packet>>;
auto BuildNetwork(Machine m) -> std::vector<Machine> {
2022-11-05 21:48:52 -07:00
auto& i = std::get<Input>(Step(m)).pos;
2022-11-05 11:19:32 -07:00
std::vector<Machine> machines;
2022-11-05 21:48:52 -07:00
for (i = 0; i < 50; i++) {
2022-11-05 11:19:32 -07:00
machines.push_back(m);
}
return machines;
}
auto Interact(Ethernet & ethernet, Machine & m, std::optional<Packet> p) -> void {
2022-11-06 10:07:31 -08:00
std::visit(overloaded{
[&](Input i) {
2022-11-05 15:06:54 -07:00
if (p) {
2022-11-06 10:07:31 -08:00
i.pos = p->first;
2022-11-05 15:06:54 -07:00
StepInput(m, p->second);
2022-11-06 10:07:31 -08:00
Interact(ethernet, m, {});
2022-11-06 10:11:33 -08:00
} else {
i.pos = -1; // no packet
2022-11-05 15:06:54 -07:00
}
},
2022-11-06 10:07:31 -08:00
[&](Output d) {
2022-11-05 15:06:54 -07:00
auto x = StepOutput(m);
auto y = StepOutput(m);
2022-11-06 10:07:31 -08:00
ethernet.push_back({d.val, {x,y}});
Interact(ethernet, m, p);
2022-11-05 15:06:54 -07:00
},
2022-11-06 10:07:31 -08:00
[](Halt) -> void { throw std::runtime_error{"unexpected halt"}; },
}, Step(m));
2022-11-05 11:19:32 -07:00
}
} // namespace
2022-11-05 15:06:54 -07:00
auto main() -> int {
2022-11-06 10:11:33 -08:00
std::ifstream fin { "/Users/emertens/Source/advent/inputs/2019/23.txt" };
auto machines = BuildNetwork(Machine{ParseStream(fin)});
2022-11-05 11:19:32 -07:00
auto ethernet = Ethernet{};
std::optional<ValueType> part1;
std::optional<ValueType> part2;
std::optional<Packet> nat;
for(;;) {
2022-11-05 21:48:52 -07:00
if (!ethernet.empty()) {
2022-11-05 11:19:32 -07:00
auto [dest, p] = ethernet.front();
ethernet.pop_front();
if (dest == 255) {
nat = p;
if (!part1) { part1 = p.second; }
} else {
2022-11-05 21:48:52 -07:00
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, {});
2022-11-05 11:19:32 -07:00
}
}
}
std::cout << "Part 1: " << *part1 << std::endl;
std::cout << "Part 2: " << *part2 << std::endl;
}