2022-11-03 12:53:10 -07:00
|
|
|
#include <algorithm>
|
|
|
|
#include <concepts>
|
2022-11-03 08:15:17 -07:00
|
|
|
#include <iostream>
|
2022-11-03 12:53:10 -07:00
|
|
|
#include <optional>
|
2022-11-03 08:15:17 -07:00
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
|
|
|
|
2022-11-06 21:12:30 -08:00
|
|
|
#include <aocpp/Startup.hpp>
|
2022-11-04 09:38:01 -07:00
|
|
|
#include <intcode/intcode.hpp>
|
2022-11-03 12:53:10 -07:00
|
|
|
using namespace intcode;
|
2022-11-03 08:15:17 -07:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2022-11-03 14:43:47 -07:00
|
|
|
template <class R> auto Controller(Machine machine, R const ¶ms) {
|
2022-11-06 21:12:30 -08:00
|
|
|
auto& i = std::get<Input>(Step(machine)).input;
|
2022-11-03 12:53:10 -07:00
|
|
|
std::vector<Machine> amps;
|
2022-11-06 21:12:30 -08:00
|
|
|
amps.reserve(params.size());
|
2022-11-03 12:53:10 -07:00
|
|
|
for (auto p : params) {
|
2022-11-06 21:12:30 -08:00
|
|
|
i = p;
|
2022-11-05 15:06:54 -07:00
|
|
|
amps.push_back(machine);
|
2022-11-03 12:53:10 -07:00
|
|
|
}
|
|
|
|
return amps;
|
2022-11-03 08:15:17 -07:00
|
|
|
}
|
|
|
|
|
2022-11-03 12:53:10 -07:00
|
|
|
template <class R>
|
2022-11-03 14:43:47 -07:00
|
|
|
auto Feed(R &&s, ValueType start) -> std::optional<ValueType> {
|
2022-11-03 12:53:10 -07:00
|
|
|
for (auto &m : amps) {
|
2022-11-05 21:48:52 -07:00
|
|
|
auto e = Step(m);
|
|
|
|
if (auto i = std::get_if<Input>(&e)) {
|
2022-11-06 19:46:43 -08:00
|
|
|
i->input = start;
|
2022-11-05 15:06:54 -07:00
|
|
|
start = StepOutput(m);
|
2022-11-03 12:53:10 -07:00
|
|
|
} else {
|
|
|
|
return {};
|
2022-11-03 08:15:17 -07:00
|
|
|
}
|
2022-11-03 12:53:10 -07:00
|
|
|
}
|
|
|
|
return {start};
|
|
|
|
}
|
2022-11-03 08:15:17 -07:00
|
|
|
|
2022-11-03 14:43:47 -07:00
|
|
|
auto compute1(Machine machine, std::vector<ValueType> const ¶ms)
|
|
|
|
-> ValueType {
|
|
|
|
return *Feed(Controller(std::move(machine), params), 0);
|
2022-11-03 08:15:17 -07:00
|
|
|
}
|
2022-11-03 14:43:47 -07:00
|
|
|
auto compute2(Machine machine, std::vector<ValueType> const ¶ms)
|
|
|
|
-> ValueType {
|
|
|
|
auto amps = Controller(std::move(machine), params);
|
|
|
|
ValueType last = 0;
|
|
|
|
while (auto next = Feed(amps, last)) {
|
2022-11-03 12:53:10 -07:00
|
|
|
last = *next;
|
|
|
|
}
|
|
|
|
return last;
|
|
|
|
}
|
|
|
|
|
2022-11-03 14:43:47 -07:00
|
|
|
template <std::invocable<Machine, std::vector<ValueType> const &> F>
|
|
|
|
auto optimize(Machine machine, std::vector<ValueType> params, F f) {
|
|
|
|
ValueType best = 0;
|
2022-11-03 12:53:10 -07:00
|
|
|
do {
|
|
|
|
best = std::max(best, f(machine, params));
|
|
|
|
} while (std::next_permutation(params.begin(), params.end()));
|
|
|
|
return best;
|
2022-11-03 08:15:17 -07:00
|
|
|
}
|
|
|
|
|
2022-11-03 12:53:10 -07:00
|
|
|
} // namespace
|
|
|
|
|
2022-11-06 11:33:20 -08:00
|
|
|
auto main(int argc, char** argv) -> int {
|
2022-11-07 21:00:14 -08:00
|
|
|
auto machine = Machine{ParseStream(aocpp::Startup(argc, argv))};
|
2022-11-03 12:53:10 -07:00
|
|
|
std::cout << "Part 1: " << optimize(machine, {0, 1, 2, 3, 4}, compute1) << std::endl;
|
|
|
|
std::cout << "Part 2: " << optimize(std::move(machine), {5, 6, 7, 8, 9}, compute2) << std::endl;
|
|
|
|
}
|