nicer fixed step interface

This commit is contained in:
Eric Mertens 2022-11-05 15:06:54 -07:00
parent b8f9152ff6
commit d96eafaa47
6 changed files with 59 additions and 60 deletions

View File

@ -13,9 +13,8 @@ namespace {
template <class R> auto Controller(Machine machine, R const &params) {
std::vector<Machine> amps;
for (auto p : params) {
auto m = machine;
std::get<Input>(Step(m)).pos = p;
amps.push_back(std::move(m));
amps.push_back(machine);
StepInput(amps.back(), p);
}
return amps;
}
@ -26,7 +25,7 @@ auto Feed(R &&amps, ValueType start) -> std::optional<ValueType> {
auto i = Step(m);
if (auto p = std::get_if<Input>(&i)) {
p->pos = start;
start = std::get<Output>(Step(m)).val;
start = StepOutput(m);
} else {
return {};
}

View File

@ -1,4 +1,5 @@
#include <iostream>
#include <stdexcept>
#include <utility>
#include <tuple>
#include <set>
@ -13,17 +14,14 @@ auto Compute1(Machine machine)
-> std::size_t {
std::set<Coord> screen;
for (;;) {
auto effect = Step(machine);
if (std::holds_alternative<Halt>(effect)) {
return screen.size();
}
auto x = std::get<Output>(effect).val;
auto y = std::get<Output>(Step(machine)).val;
auto v = std::get<Output>(Step(machine)).val;
if (2 == v) { screen.insert({x,y}); } else { screen.erase({x,y}); }
}
Run(machine,
[]() -> ValueType { throw std::runtime_error{"unexpected input request"}; },
[&](auto x) {
auto y = StepOutput(machine);
auto v = StepOutput(machine);
if (2 == v) { screen.insert({x,y}); } else { screen.erase({x,y}); }
});
return screen.size();
}
auto Compute2(Machine machine) {
@ -32,17 +30,14 @@ auto Compute2(Machine machine) {
ValueType ballX {0};
machine.At(0) = 2;
for(;;) {
auto effect = Step(machine);
if (std::holds_alternative<Halt>(effect)) {
return score;
} else if (auto i = std::get_if<Input>(&effect)) {
i->pos = paddleX < ballX ? 1
: paddleX > ballX ? -1 : 0;
} else {
auto x = std::get<Output>(effect).val;
auto y = std::get<Output>(Step(machine)).val;
auto v = std::get<Output>(Step(machine)).val;
Run(machine,
[&]() {
return paddleX < ballX ? 1 : paddleX > ballX ? -1 : 0;
},
[&](auto x) {
auto y = StepOutput(machine);
auto v = StepOutput(machine);
if (-1 == x && 0 == y) {
score = v;
@ -56,8 +51,8 @@ auto Compute2(Machine machine) {
break;
}
}
}
}
});
return score;
}
} // namespace

View File

@ -16,8 +16,8 @@ using CoordOp = Coord(Coord);
CoordOp* const moves[4] {Up, Down, Left, Right};
auto Interact(Machine & m, ValueType cmd) -> ValueType {
std::get<Input>(Step(m)).pos = cmd;
return std::get<Output>(Step(m)).val;
StepInput(m, cmd);
return StepOutput(m);
}
auto CounterCommand(ValueType x) -> ValueType {

View File

@ -6,7 +6,6 @@
#include <utility>
#include <variant>
#include <vector>
#include <fstream>
#include <intcode/intcode.hpp>
using namespace intcode;
@ -20,46 +19,40 @@ 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;
StepInput(machines.back(), i);
}
return machines;
}
auto Interact(Ethernet & ethernet, Machine & m, std::optional<Packet> p) -> void {
for(;;) {
auto effect = Step(m);
switch (effect.index()) {
while(std::visit(overloaded{
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;
[&](Input i) {
if (p) {
i.pos = p->first;
StepInput(m, p->second);
p = {};
return true;
}
}
i.pos = -1; // no packet
return false;
},
[&](Output o) {
auto x = StepOutput(m);
auto y = StepOutput(m);
ethernet.push_back({o.val, {x,y}});
return true;
},
[](Halt) -> bool { throw std::runtime_error{"unexpected halt"}; },
}, Step(m))) {}
}
} // 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 main() -> int {
auto machines = BuildNetwork(Machine{ParseStream(std::cin)});
auto ethernet = Ethernet{};
std::optional<ValueType> part1;

View File

@ -17,6 +17,10 @@ ValueType val;
struct Halt {};
auto StepInput(Machine & m, ValueType input) -> void;
auto StepOutput(Machine & m) -> ValueType;
auto Step(Machine & m) -> std::variant<Input, Output, Halt>;
struct BadInstruction : public std::runtime_error {

View File

@ -5,6 +5,14 @@ namespace intcode {
BadInstruction::BadInstruction(char const* what)
: std::runtime_error{what} {}
auto StepInput(Machine & m, ValueType input) -> void {
std::get<Input>(Step(m)).pos = input;
}
auto StepOutput(Machine & m) -> ValueType {
return std::get<Output>(Step(m)).val;
}
auto Step(Machine & m) -> std::variant<Input, Output, Halt> {
for (;;) {
auto instruction = m.Next();