15
This commit is contained in:
parent
b7527106ba
commit
a37baee99e
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
||||||
/build
|
/build
|
||||||
/release
|
/release
|
||||||
|
.*.swp
|
||||||
|
|
102
day15.cpp
102
day15.cpp
|
@ -1,8 +1,10 @@
|
||||||
|
#include <algorithm>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <set>
|
#include <map>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <intcode/intcode.hpp>
|
#include <intcode/intcode.hpp>
|
||||||
#include <intcode/Coord.hpp>
|
#include <intcode/Coord.hpp>
|
||||||
|
@ -10,56 +12,84 @@ using namespace intcode;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
std::pair<ValueType, Coord(*)(Coord)> const moves[4]
|
using CoordOp = Coord(Coord);
|
||||||
{{1, Up}, {2, Down}, {3, Left}, {4, Right}};
|
CoordOp* const moves[4] {Up, Down, Left, Right};
|
||||||
|
|
||||||
auto Fork(Machine m, ValueType cmd) {
|
auto Interact(Machine & m, ValueType cmd) {
|
||||||
std::get<Input>(Step(m)).pos = cmd;
|
std::get<Input>(Step(m)).pos = cmd;
|
||||||
auto o = std::get<Output>(Step(m)).val;
|
return std::get<Output>(Step(m)).val;
|
||||||
return std::make_pair(o, std::move(m));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Compute(Machine machine) {
|
auto CounterCommand(ValueType x) -> ValueType {
|
||||||
Coord const origin {0,0};
|
return ((x-1)^1)+1;
|
||||||
std::set<Coord> world {origin};
|
}
|
||||||
|
|
||||||
std::deque<std::tuple<int, Coord, Machine>> todo
|
// Depth first search of the maze
|
||||||
{{0, origin, std::move(machine)}};
|
auto Explore(Machine m) -> std::map<Coord, ValueType> {
|
||||||
|
std::map<Coord, ValueType> world;
|
||||||
|
std::vector<ValueType> path {0};
|
||||||
|
Coord here {};
|
||||||
|
|
||||||
long part1 = -1;
|
for(;;) {
|
||||||
long part2 = -1;
|
while (path.back() < 4) {
|
||||||
|
path.back()++;
|
||||||
|
auto here_ = moves[path.back() - 1](here);
|
||||||
|
auto [it, success] = world.insert({here_,0});
|
||||||
|
if (success && 0 != (it->second = Interact(m, path.back()))) {
|
||||||
|
here = here_;
|
||||||
|
path.push_back(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
top:
|
path.pop_back();
|
||||||
while (!todo.empty()) {
|
if (path.empty()) { break; }
|
||||||
auto & [steps, loc, m] = todo.front();
|
|
||||||
|
auto rev = CounterCommand(path.back());
|
||||||
|
here = moves[rev - 1](here);
|
||||||
|
Interact(m, rev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Breadth first search of maze finding shortest path to origin
|
||||||
|
// and furthest point in the maze from the airsource.
|
||||||
|
auto Compute12(std::map<Coord, ValueType> world) -> std::pair<int, int> {
|
||||||
|
// Find starting coordinate and remove all the walls from the map
|
||||||
|
Coord start {};
|
||||||
|
for (auto it = world.begin(); it != world.end(); ) {
|
||||||
|
switch (it->second) {
|
||||||
|
case 2: start = it->first;
|
||||||
|
case 0: it = world.erase(it); break;
|
||||||
|
default: it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int part1 = -1;
|
||||||
|
int part2 = -1;
|
||||||
|
|
||||||
|
for (std::deque<std::pair<int, Coord>> todo {{0,start}};
|
||||||
|
!todo.empty();
|
||||||
|
todo.pop_front())
|
||||||
|
{
|
||||||
|
auto && [steps, here] = todo.front();
|
||||||
|
if (Coord{0,0} == here) part1 = steps;
|
||||||
part2 = steps;
|
part2 = steps;
|
||||||
steps++;
|
|
||||||
|
|
||||||
for (auto&& [cmd, fun] : moves) {
|
for (auto fn : moves) {
|
||||||
auto loc_ = fun(loc);
|
auto next = fn(here);
|
||||||
if (world.insert(loc_).second) {
|
if (world.erase(next)) {
|
||||||
auto [o,m_] = Fork(m, cmd);
|
todo.emplace_back(steps+1, next);
|
||||||
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_));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
todo.pop_front();
|
return {part1, part2};
|
||||||
}
|
|
||||||
|
|
||||||
return std::make_pair(part1,part2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
auto main() -> int {
|
auto main() -> int {
|
||||||
auto [part1, part2] = Compute(Machine{ParseStream(std::cin)});
|
auto [p1,p2] = Compute12(Explore(Machine{ParseStream(std::cin)}));
|
||||||
std::cout << "Part 1: " << part1 << std::endl;
|
std::cout << "Part 1: " << p1 << std::endl;
|
||||||
std::cout << "Part 2: " << part2 << std::endl;
|
std::cout << "Part 2: " << p2 << std::endl;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user