23
This commit is contained in:
parent
a37baee99e
commit
c8470b2056
|
@ -36,3 +36,6 @@ target_link_libraries(day13 intcode)
|
||||||
|
|
||||||
add_executable(day15 day15.cpp)
|
add_executable(day15 day15.cpp)
|
||||||
target_link_libraries(day15 intcode)
|
target_link_libraries(day15 intcode)
|
||||||
|
|
||||||
|
add_executable(day23 day23.cpp)
|
||||||
|
target_link_libraries(day23 intcode)
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace {
|
||||||
using CoordOp = Coord(Coord);
|
using CoordOp = Coord(Coord);
|
||||||
CoordOp* const moves[4] {Up, Down, Left, Right};
|
CoordOp* const moves[4] {Up, Down, Left, Right};
|
||||||
|
|
||||||
auto Interact(Machine & m, ValueType cmd) {
|
auto Interact(Machine & m, ValueType cmd) -> ValueType {
|
||||||
std::get<Input>(Step(m)).pos = cmd;
|
std::get<Input>(Step(m)).pos = cmd;
|
||||||
return std::get<Output>(Step(m)).val;
|
return std::get<Output>(Step(m)).val;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ auto Explore(Machine m) -> std::map<Coord, ValueType> {
|
||||||
|
|
||||||
// Breadth first search of maze finding shortest path to origin
|
// Breadth first search of maze finding shortest path to origin
|
||||||
// and furthest point in the maze from the airsource.
|
// and furthest point in the maze from the airsource.
|
||||||
auto Compute12(std::map<Coord, ValueType> world) -> std::pair<int, int> {
|
auto Compute(std::map<Coord, ValueType> world) -> std::pair<int, int> {
|
||||||
// Find starting coordinate and remove all the walls from the map
|
// Find starting coordinate and remove all the walls from the map
|
||||||
Coord start {};
|
Coord start {};
|
||||||
for (auto it = world.begin(); it != world.end(); ) {
|
for (auto it = world.begin(); it != world.end(); ) {
|
||||||
|
@ -72,7 +72,7 @@ auto Compute12(std::map<Coord, ValueType> world) -> std::pair<int, int> {
|
||||||
!todo.empty();
|
!todo.empty();
|
||||||
todo.pop_front())
|
todo.pop_front())
|
||||||
{
|
{
|
||||||
auto && [steps, here] = todo.front();
|
auto [steps, here] = todo.front();
|
||||||
if (Coord{0,0} == here) part1 = steps;
|
if (Coord{0,0} == here) part1 = steps;
|
||||||
part2 = steps;
|
part2 = steps;
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ auto Compute12(std::map<Coord, ValueType> world) -> std::pair<int, int> {
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
auto main() -> int {
|
auto main() -> int {
|
||||||
auto [p1,p2] = Compute12(Explore(Machine{ParseStream(std::cin)}));
|
auto [p1,p2] = Compute(Explore(Machine{ParseStream(std::cin)}));
|
||||||
std::cout << "Part 1: " << p1 << std::endl;
|
std::cout << "Part 1: " << p1 << std::endl;
|
||||||
std::cout << "Part 2: " << p2 << std::endl;
|
std::cout << "Part 2: " << p2 << std::endl;
|
||||||
}
|
}
|
||||||
|
|
96
day23.cpp
Normal file
96
day23.cpp
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
#include <cstddef>
|
||||||
|
#include <deque>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <tuple>
|
||||||
|
#include <utility>
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#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> {
|
||||||
|
std::vector<Machine> machines;
|
||||||
|
for (int i = 0; i < 50; i++) {
|
||||||
|
machines.push_back(m);
|
||||||
|
std::get<Input>(Step(machines.back())).pos = i;
|
||||||
|
}
|
||||||
|
return machines;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Interact(Ethernet & ethernet, Machine & m, std::optional<Packet> p) -> void {
|
||||||
|
for(;;) {
|
||||||
|
auto effect = Step(m);
|
||||||
|
switch (effect.index()) {
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw std::runtime_error{"unexpected halt"};
|
||||||
|
|
||||||
|
case 0: // Input
|
||||||
|
if (p) {
|
||||||
|
std::get<Input>(effect).pos = p->first;
|
||||||
|
std::get<Input>(Step(m)).pos = p->second;
|
||||||
|
p = {};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::get<Input>(effect).pos = -1; // no packet
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 1: // Output
|
||||||
|
auto d = std::get<Output>(effect).val;
|
||||||
|
auto x = std::get<Output>(Step(m)).val;
|
||||||
|
auto y = std::get<Output>(Step(m)).val;
|
||||||
|
ethernet.push_back({d, {x,y}});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
auto main(int argc, char ** argv) -> int {
|
||||||
|
if (2 != argc) { return 1; }
|
||||||
|
std::ifstream fin {argv[1]};
|
||||||
|
|
||||||
|
auto machines = BuildNetwork(Machine{ParseStream(fin)});
|
||||||
|
auto ethernet = Ethernet{};
|
||||||
|
|
||||||
|
std::optional<ValueType> part1;
|
||||||
|
std::optional<ValueType> part2;
|
||||||
|
std::optional<Packet> nat;
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
if (ethernet.empty()) {
|
||||||
|
if (nat) {
|
||||||
|
if (nat->second == part2) { break; }
|
||||||
|
part2 = nat->second;
|
||||||
|
Interact(ethernet, machines[0], nat);
|
||||||
|
} else {
|
||||||
|
for (auto && m : machines) {
|
||||||
|
Interact(ethernet, m, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto [dest, p] = ethernet.front();
|
||||||
|
ethernet.pop_front();
|
||||||
|
if (dest == 255) {
|
||||||
|
nat = p;
|
||||||
|
if (!part1) { part1 = p.second; }
|
||||||
|
} else if (dest < 50) {
|
||||||
|
Interact(ethernet, machines[dest], p);
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error{"bad destination"};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Part 1: " << *part1 << std::endl;
|
||||||
|
std::cout << "Part 2: " << *part2 << std::endl;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user