This commit is contained in:
Eric Mertens 2022-11-10 11:28:03 -08:00
parent 262c339920
commit 5f080c1903

View File

@ -12,6 +12,7 @@
#include <bitset> #include <bitset>
#include <deque> #include <deque>
#include <cctype> #include <cctype>
#include <queue>
#include <map> #include <map>
#include <aocpp/Startup.hpp> #include <aocpp/Startup.hpp>
@ -110,19 +111,33 @@ auto SetKey(Doors doors, char key) {
return doors.set(std::toupper(key) - 'A'); return doors.set(std::toupper(key) - 'A');
} }
auto SolveMaze(Distances const& distances, std::set<char> const initial_locations) -> std::int64_t { template <class Elt, class Compare>
auto MakePQueue(Compare const& compare)
-> std::priority_queue<Elt, std::vector<Elt>, Compare>
{
return {compare};
}
auto SolveMaze(
Distances const& distances,
std::set<char> const initial_locations
) -> std::int64_t
{
// Track current positions and current set of keys in easy to compare form // Track current positions and current set of keys in easy to compare form
using Visited = std::pair<std::set<char>, unsigned long long>; using Visited = std::pair<std::set<char>, unsigned long long>;
std::set<Visited> seen; std::set<Visited> seen;
std::multimap<std::int64_t, std::pair<std::set<char>, Doors>> todo auto todo = MakePQueue<std::tuple<std::int64_t, std::set<char>, Doors>>(
{{0, {initial_locations, Doors()}}}; [](auto const& x, auto const& y) {
return std::get<0>(x) > std::get<0>(y);
}
);
todo.emplace(0, initial_locations, Doors());
while (!todo.empty()) { while (!todo.empty()) {
auto it = todo.begin(); auto [steps, locations, keys] = todo.top();
auto [steps, ld] = *it; todo.pop();
auto& [locations,keys] = ld;
todo.erase(it);
if (keys.all()) { return steps; } if (keys.all()) { return steps; }
@ -134,7 +149,7 @@ auto SolveMaze(Distances const& distances, std::set<char> const initial_location
auto [cost, need] = costneed; auto [cost, need] = costneed;
if ((need & ~keys).none()) { if ((need & ~keys).none()) {
auto locations2 = locations1; locations2.insert(next); auto locations2 = locations1; locations2.insert(next);
todo.insert({steps + cost, {locations2, SetKey(keys, next)}}); todo.emplace(steps + cost, locations2, SetKey(keys, next));
} }
} }
} }