nicer fixed step interface
This commit is contained in:
parent
b8f9152ff6
commit
d96eafaa47
|
@ -13,9 +13,8 @@ namespace {
|
||||||
template <class R> auto Controller(Machine machine, R const ¶ms) {
|
template <class R> auto Controller(Machine machine, R const ¶ms) {
|
||||||
std::vector<Machine> amps;
|
std::vector<Machine> amps;
|
||||||
for (auto p : params) {
|
for (auto p : params) {
|
||||||
auto m = machine;
|
amps.push_back(machine);
|
||||||
std::get<Input>(Step(m)).pos = p;
|
StepInput(amps.back(), p);
|
||||||
amps.push_back(std::move(m));
|
|
||||||
}
|
}
|
||||||
return amps;
|
return amps;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +25,7 @@ auto Feed(R &&s, ValueType start) -> std::optional<ValueType> {
|
||||||
auto i = Step(m);
|
auto i = Step(m);
|
||||||
if (auto p = std::get_if<Input>(&i)) {
|
if (auto p = std::get_if<Input>(&i)) {
|
||||||
p->pos = start;
|
p->pos = start;
|
||||||
start = std::get<Output>(Step(m)).val;
|
start = StepOutput(m);
|
||||||
} else {
|
} else {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
41
day13.cpp
41
day13.cpp
|
@ -1,4 +1,5 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -13,17 +14,14 @@ auto Compute1(Machine machine)
|
||||||
-> std::size_t {
|
-> std::size_t {
|
||||||
std::set<Coord> screen;
|
std::set<Coord> screen;
|
||||||
|
|
||||||
for (;;) {
|
Run(machine,
|
||||||
auto effect = Step(machine);
|
[]() -> ValueType { throw std::runtime_error{"unexpected input request"}; },
|
||||||
if (std::holds_alternative<Halt>(effect)) {
|
[&](auto x) {
|
||||||
return screen.size();
|
auto y = StepOutput(machine);
|
||||||
}
|
auto v = StepOutput(machine);
|
||||||
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}); }
|
if (2 == v) { screen.insert({x,y}); } else { screen.erase({x,y}); }
|
||||||
}
|
});
|
||||||
|
return screen.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Compute2(Machine machine) {
|
auto Compute2(Machine machine) {
|
||||||
|
@ -32,17 +30,14 @@ auto Compute2(Machine machine) {
|
||||||
ValueType ballX {0};
|
ValueType ballX {0};
|
||||||
|
|
||||||
machine.At(0) = 2;
|
machine.At(0) = 2;
|
||||||
for(;;) {
|
|
||||||
auto effect = Step(machine);
|
Run(machine,
|
||||||
if (std::holds_alternative<Halt>(effect)) {
|
[&]() {
|
||||||
return score;
|
return paddleX < ballX ? 1 : paddleX > ballX ? -1 : 0;
|
||||||
} else if (auto i = std::get_if<Input>(&effect)) {
|
},
|
||||||
i->pos = paddleX < ballX ? 1
|
[&](auto x) {
|
||||||
: paddleX > ballX ? -1 : 0;
|
auto y = StepOutput(machine);
|
||||||
} else {
|
auto v = StepOutput(machine);
|
||||||
auto x = std::get<Output>(effect).val;
|
|
||||||
auto y = std::get<Output>(Step(machine)).val;
|
|
||||||
auto v = std::get<Output>(Step(machine)).val;
|
|
||||||
|
|
||||||
if (-1 == x && 0 == y) {
|
if (-1 == x && 0 == y) {
|
||||||
score = v;
|
score = v;
|
||||||
|
@ -56,8 +51,8 @@ auto Compute2(Machine machine) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -16,8 +16,8 @@ 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) -> ValueType {
|
auto Interact(Machine & m, ValueType cmd) -> ValueType {
|
||||||
std::get<Input>(Step(m)).pos = cmd;
|
StepInput(m, cmd);
|
||||||
return std::get<Output>(Step(m)).val;
|
return StepOutput(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CounterCommand(ValueType x) -> ValueType {
|
auto CounterCommand(ValueType x) -> ValueType {
|
||||||
|
|
47
day23.cpp
47
day23.cpp
|
@ -6,7 +6,6 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include <intcode/intcode.hpp>
|
#include <intcode/intcode.hpp>
|
||||||
using namespace intcode;
|
using namespace intcode;
|
||||||
|
@ -20,46 +19,40 @@ auto BuildNetwork(Machine m) -> std::vector<Machine> {
|
||||||
std::vector<Machine> machines;
|
std::vector<Machine> machines;
|
||||||
for (int i = 0; i < 50; i++) {
|
for (int i = 0; i < 50; i++) {
|
||||||
machines.push_back(m);
|
machines.push_back(m);
|
||||||
std::get<Input>(Step(machines.back())).pos = i;
|
StepInput(machines.back(), i);
|
||||||
}
|
}
|
||||||
return machines;
|
return machines;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Interact(Ethernet & ethernet, Machine & m, std::optional<Packet> p) -> void {
|
auto Interact(Ethernet & ethernet, Machine & m, std::optional<Packet> p) -> void {
|
||||||
for(;;) {
|
while(std::visit(overloaded{
|
||||||
auto effect = Step(m);
|
|
||||||
switch (effect.index()) {
|
|
||||||
|
|
||||||
default:
|
[&](Input i) {
|
||||||
throw std::runtime_error{"unexpected halt"};
|
|
||||||
|
|
||||||
case 0: // Input
|
|
||||||
if (p) {
|
if (p) {
|
||||||
std::get<Input>(effect).pos = p->first;
|
i.pos = p->first;
|
||||||
std::get<Input>(Step(m)).pos = p->second;
|
StepInput(m, p->second);
|
||||||
p = {};
|
p = {};
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
std::get<Input>(effect).pos = -1; // no packet
|
i.pos = -1; // no packet
|
||||||
return;
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
case 1: // Output
|
[&](Output o) {
|
||||||
auto d = std::get<Output>(effect).val;
|
auto x = StepOutput(m);
|
||||||
auto x = std::get<Output>(Step(m)).val;
|
auto y = StepOutput(m);
|
||||||
auto y = std::get<Output>(Step(m)).val;
|
ethernet.push_back({o.val, {x,y}});
|
||||||
ethernet.push_back({d, {x,y}});
|
return true;
|
||||||
break;
|
},
|
||||||
}
|
|
||||||
}
|
[](Halt) -> bool { throw std::runtime_error{"unexpected halt"}; },
|
||||||
|
}, Step(m))) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
auto main(int argc, char ** argv) -> int {
|
auto main() -> int {
|
||||||
if (2 != argc) { return 1; }
|
auto machines = BuildNetwork(Machine{ParseStream(std::cin)});
|
||||||
std::ifstream fin {argv[1]};
|
|
||||||
|
|
||||||
auto machines = BuildNetwork(Machine{ParseStream(fin)});
|
|
||||||
auto ethernet = Ethernet{};
|
auto ethernet = Ethernet{};
|
||||||
|
|
||||||
std::optional<ValueType> part1;
|
std::optional<ValueType> part1;
|
||||||
|
|
|
@ -17,6 +17,10 @@ ValueType val;
|
||||||
|
|
||||||
struct Halt {};
|
struct Halt {};
|
||||||
|
|
||||||
|
auto StepInput(Machine & m, ValueType input) -> void;
|
||||||
|
|
||||||
|
auto StepOutput(Machine & m) -> ValueType;
|
||||||
|
|
||||||
auto Step(Machine & m) -> std::variant<Input, Output, Halt>;
|
auto Step(Machine & m) -> std::variant<Input, Output, Halt>;
|
||||||
|
|
||||||
struct BadInstruction : public std::runtime_error {
|
struct BadInstruction : public std::runtime_error {
|
||||||
|
|
|
@ -5,6 +5,14 @@ namespace intcode {
|
||||||
BadInstruction::BadInstruction(char const* what)
|
BadInstruction::BadInstruction(char const* what)
|
||||||
: std::runtime_error{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> {
|
auto Step(Machine & m) -> std::variant<Input, Output, Halt> {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto instruction = m.Next();
|
auto instruction = m.Next();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user