aocpp/day15.cpp

66 lines
1.4 KiB
C++
Raw Normal View History

2022-11-04 17:39:35 -07:00
#include <deque>
2022-11-03 21:41:06 -07:00
#include <iostream>
2022-11-04 17:39:35 -07:00
#include <set>
2022-11-03 21:41:06 -07:00
#include <tuple>
2022-11-04 17:39:35 -07:00
#include <utility>
2022-11-03 21:41:06 -07:00
2022-11-04 09:38:01 -07:00
#include <intcode/intcode.hpp>
2022-11-04 21:27:08 -07:00
#include <intcode/Coord.hpp>
2022-11-03 21:41:06 -07:00
using namespace intcode;
namespace {
2022-11-04 17:39:35 -07:00
std::pair<ValueType, Coord(*)(Coord)> const moves[4]
{{1, Up}, {2, Down}, {3, Left}, {4, Right}};
2022-11-03 21:41:06 -07:00
2022-11-04 17:39:35 -07:00
auto Fork(Machine m, ValueType cmd) {
std::get<Input>(Step(m)).pos = cmd;
auto o = std::get<Output>(Step(m)).val;
return std::make_pair(o, std::move(m));
}
2022-11-03 21:41:06 -07:00
2022-11-04 17:39:35 -07:00
auto Compute(Machine machine) {
Coord const origin {0,0};
std::set<Coord> world {origin};
2022-11-03 21:41:06 -07:00
2022-11-04 17:39:35 -07:00
std::deque<std::tuple<int, Coord, Machine>> todo
{{0, origin, std::move(machine)}};
2022-11-04 11:37:32 -07:00
2022-11-04 17:39:35 -07:00
long part1 = -1;
long part2 = -1;
top:
while (!todo.empty()) {
auto & [steps, loc, m] = todo.front();
part2 = steps;
steps++;
2022-11-03 21:41:06 -07:00
2022-11-04 17:39:35 -07:00
for (auto&& [cmd, fun] : moves) {
auto loc_ = fun(loc);
if (world.insert(loc_).second) {
auto [o,m_] = Fork(m, cmd);
switch (o) {
case 2:
part1 = steps;
world = {origin};
todo = {{0, origin, std::move(m_)}};
goto top;
case 1:
todo.emplace_back(steps, loc_, std::move(m_));
}
2022-11-04 08:29:02 -07:00
}
2022-11-03 21:41:06 -07:00
}
2022-11-04 17:39:35 -07:00
todo.pop_front();
2022-11-04 08:29:02 -07:00
}
2022-11-03 21:41:06 -07:00
2022-11-04 17:39:35 -07:00
return std::make_pair(part1,part2);
2022-11-03 21:41:06 -07:00
}
} // namespace
auto main() -> int {
2022-11-04 17:39:35 -07:00
auto [part1, part2] = Compute(Machine{ParseStream(std::cin)});
2022-11-03 21:41:06 -07:00
std::cout << "Part 1: " << part1 << std::endl;
std::cout << "Part 2: " << part2 << std::endl;
}