66 lines
1.5 KiB
C++
66 lines
1.5 KiB
C++
|
#include <iterator>
|
||
|
#include <iostream>
|
||
|
#include <utility>
|
||
|
#include <tuple>
|
||
|
#include <map>
|
||
|
#include <deque>
|
||
|
|
||
|
#include <intcode.hpp>
|
||
|
using namespace intcode;
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
using Coord = std::pair<ValueType, ValueType>;
|
||
|
|
||
|
auto Compute(Machine machine) -> std::pair<int,int> {
|
||
|
int part1 = 0;
|
||
|
int part2 = 0;
|
||
|
|
||
|
Coord here {0,0};
|
||
|
std::map<Coord, ValueType> world;
|
||
|
|
||
|
std::deque<std::tuple<int, Coord, Machine>> todo {{0, {0,0}, std::move(machine)}};
|
||
|
|
||
|
auto action = [&world, &todo](Machine m, int steps, ValueType cmd, Coord coord) {
|
||
|
if (!world.contains(coord)) {
|
||
|
std::get<Input>(m.Step()).pos = cmd;
|
||
|
auto o = std::get<Output>(m.Step()).val;
|
||
|
world[coord] = o;
|
||
|
if (o) {
|
||
|
todo.emplace_back(steps + 1, coord, std::move(m));
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
while (!todo.empty()) {
|
||
|
auto [steps, here, machine] = todo.front();
|
||
|
auto [x,y] = here;
|
||
|
todo.pop_front();
|
||
|
|
||
|
if (2 == world[here]) {
|
||
|
part1 = steps;
|
||
|
todo.clear();
|
||
|
world.clear();
|
||
|
world[here] = 2;
|
||
|
steps = 0;
|
||
|
part2 = 0;
|
||
|
}
|
||
|
part2 = std::max(part2, steps);
|
||
|
|
||
|
action(machine, steps, 1, {x,y-1});
|
||
|
action(machine, steps, 2, {x,y+1});
|
||
|
action(machine, steps, 3, {x-1,y});
|
||
|
action(std::move(machine), steps, 4, {x+1,y});
|
||
|
}
|
||
|
return {part1,part2};
|
||
|
}
|
||
|
|
||
|
} // 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;
|
||
|
}
|