This commit is contained in:
Eric Mertens 2023-04-04 07:23:11 -07:00
parent c95b0b2daa
commit aef729afe4

View File

@ -5,7 +5,8 @@
#include <iostream> #include <iostream>
#include <set> #include <set>
#include <sstream> #include <sstream>
#include <optional> #include <stack>
#include <tuple>
#include <vector> #include <vector>
#include <boost/phoenix.hpp> #include <boost/phoenix.hpp>
@ -16,7 +17,6 @@
#include <aocpp/Startup.hpp> #include <aocpp/Startup.hpp>
#include <aocpp/Coord.hpp> #include <aocpp/Coord.hpp>
#include <aocpp/Generator.hpp>
namespace { namespace {
@ -97,32 +97,33 @@ auto FindBottom(Input const& input) -> std::int64_t
return result; return result;
} }
auto SearchOrder(std::set<aocpp::Coord> & world, aocpp::Coord here) -> aocpp::Generator<aocpp::Coord> enum class Action { Visit, Mark };
{
co_yield aocpp::Down(here);
co_yield aocpp::Left(aocpp::Down(here));
co_yield aocpp::Right(aocpp::Down(here));
world.insert(here);
}
auto Part1(std::int64_t bottom, std::set<aocpp::Coord> world) -> std::size_t auto Part1(std::int64_t bottom, std::set<aocpp::Coord> world) -> std::size_t
{ {
auto const starting_size = world.size(); auto const starting_size = world.size();
auto work = std::stack<std::pair<Action, aocpp::Coord>>{};
work.emplace(Action::Visit, TOP);
auto path = std::vector<aocpp::Generator<aocpp::Coord>>{}; while (!work.empty()) {
path.reserve(bottom - TOP.y); auto const [action, here] = work.top();
path.push_back(SearchOrder(world, TOP)); work.pop();
while (!path.empty()) { switch (action) {
if (auto next = path.back()()) { case Action::Visit:
if (!world.contains(*next)) { if (!world.contains(here)) {
if (next->y == bottom) { if (here.y == bottom) {
return world.size() - starting_size; return world.size() - starting_size;
}
work.emplace(Action::Mark, here);
work.emplace(Action::Visit, aocpp::Right(aocpp::Down(here)));
work.emplace(Action::Visit, aocpp::Left(aocpp::Down(here)));
work.emplace(Action::Visit, aocpp::Down(here));
} }
path.push_back(SearchOrder(world, *next)); break;
} case Action::Mark:
} else { world.insert(here);
path.pop_back(); break;
} }
} }
@ -132,18 +133,25 @@ auto Part1(std::int64_t bottom, std::set<aocpp::Coord> world) -> std::size_t
auto Part2(std::int64_t bottom, std::set<aocpp::Coord> world) -> std::size_t auto Part2(std::int64_t bottom, std::set<aocpp::Coord> world) -> std::size_t
{ {
auto const starting_size = world.size(); auto const starting_size = world.size();
auto work = std::stack<std::pair<Action, aocpp::Coord>>{};
auto path = std::vector<aocpp::Generator<aocpp::Coord>>{}; work.emplace(Action::Visit, TOP);
path.reserve(2 + bottom - TOP.y);
path.push_back(SearchOrder(world, TOP));
while (!path.empty()) { while (!work.empty()) {
if (auto next = path.back()()) { auto const [action, here] = work.top();
if (next->y - 2 != bottom && !world.contains(*next)) { work.pop();
path.push_back(SearchOrder(world, *next));
} switch (action) {
} else { case Action::Visit:
path.pop_back(); if (here.y - 2 != bottom && !world.contains(here)) {
work.emplace(Action::Mark, here);
work.emplace(Action::Visit, aocpp::Right(aocpp::Down(here)));
work.emplace(Action::Visit, aocpp::Left(aocpp::Down(here)));
work.emplace(Action::Visit, aocpp::Down(here));
}
break;
case Action::Mark:
world.insert(here);
break;
} }
} }