18
This commit is contained in:
parent
262c339920
commit
5f080c1903
31
2019/18.cpp
31
2019/18.cpp
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user