2022-11-03 21:41:06 -07:00
|
|
|
#include <iterator>
|
|
|
|
#include <iostream>
|
|
|
|
#include <utility>
|
|
|
|
#include <tuple>
|
|
|
|
#include <map>
|
|
|
|
#include <deque>
|
2022-11-04 08:29:02 -07:00
|
|
|
#include <vector>
|
2022-11-03 21:41:06 -07:00
|
|
|
|
2022-11-04 09:38:01 -07:00
|
|
|
#include <intcode/intcode.hpp>
|
2022-11-03 21:41:06 -07:00
|
|
|
using namespace intcode;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
using Coord = std::pair<ValueType, ValueType>;
|
|
|
|
|
|
|
|
auto Compute(Machine machine) -> std::pair<int,int> {
|
|
|
|
Coord here {0,0};
|
2022-11-04 08:29:02 -07:00
|
|
|
std::map<Coord, ValueType> world {{{0,0},1}};
|
2022-11-03 21:41:06 -07:00
|
|
|
|
2022-11-04 08:29:02 -07:00
|
|
|
using State = std::tuple<Coord, Machine>;
|
2022-11-03 21:41:06 -07:00
|
|
|
|
2022-11-04 08:29:02 -07:00
|
|
|
std::vector<State> layer {{{0,0}, std::move(machine)}};
|
|
|
|
std::vector<State> next_layer;
|
|
|
|
|
|
|
|
auto action = [&](Machine m, ValueType cmd, Coord coord) {
|
2022-11-03 21:41:06 -07:00
|
|
|
if (!world.contains(coord)) {
|
2022-11-04 08:29:02 -07:00
|
|
|
std::get<Input>(Step(m)).pos = cmd;
|
|
|
|
auto o = std::get<Output>(Step(m)).val;
|
2022-11-03 21:41:06 -07:00
|
|
|
world[coord] = o;
|
|
|
|
if (o) {
|
2022-11-04 08:29:02 -07:00
|
|
|
next_layer.emplace_back(coord, std::move(m));
|
2022-11-03 21:41:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-11-04 08:29:02 -07:00
|
|
|
int part1 = 0;
|
|
|
|
while (!layer.empty()) {
|
|
|
|
for (auto && s : layer) {
|
|
|
|
auto& [loc, m] = s;
|
|
|
|
if (2 == world[loc]) {
|
|
|
|
world.clear();
|
|
|
|
world[loc] = 2;
|
|
|
|
auto start = std::move(m);
|
|
|
|
layer.clear();
|
|
|
|
layer.push_back({loc, std::move(start)});
|
|
|
|
goto loop2;
|
|
|
|
}
|
|
|
|
auto [x,y] = loc;
|
|
|
|
action(m, 1, {x,y-1});
|
|
|
|
action(m, 2, {x,y+1});
|
|
|
|
action(m, 3, {x-1,y});
|
|
|
|
action(std::move(m), 4, {x+1,y});
|
2022-11-03 21:41:06 -07:00
|
|
|
}
|
2022-11-04 08:29:02 -07:00
|
|
|
layer = std::move(next_layer);
|
|
|
|
next_layer.clear();
|
|
|
|
part1++;
|
|
|
|
}
|
2022-11-03 21:41:06 -07:00
|
|
|
|
2022-11-04 08:29:02 -07:00
|
|
|
|
|
|
|
loop2:
|
|
|
|
int part2 = 0;
|
|
|
|
while (!layer.empty()) {
|
|
|
|
for (auto && s : layer) {
|
|
|
|
auto& [loc, m] = s;
|
|
|
|
auto [x,y] = loc;
|
|
|
|
action(m, 1, {x,y-1});
|
|
|
|
action(m, 2, {x,y+1});
|
|
|
|
action(m, 3, {x-1,y});
|
|
|
|
action(std::move(m), 4, {x+1,y});
|
|
|
|
}
|
|
|
|
layer = std::move(next_layer);
|
|
|
|
next_layer.clear();
|
|
|
|
part2++;
|
2022-11-03 21:41:06 -07:00
|
|
|
}
|
2022-11-04 08:29:02 -07:00
|
|
|
return {part1, part2-1};
|
2022-11-03 21:41:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
auto main() -> int {
|
|
|
|
auto machine = Machine{ParseStream(std::cin)};
|
|
|
|
auto [part1, part2] = Compute(machine);
|
|
|
|
std::cout << "Part 1: " << part1 << std::endl;
|
|
|
|
std::cout << "Part 2: " << part2 << std::endl;
|
|
|
|
}
|