Optimize day 18 a bit.

This commit is contained in:
2019-12-23 23:36:33 +01:00
parent 2a75d1be4c
commit 8bbd9705a6

View File

@@ -4,7 +4,7 @@
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <bit> #include <bit>
#include <set> #include <map>
#include "days.hpp" #include "days.hpp"
#include "point.hpp" #include "point.hpp"
@@ -108,7 +108,7 @@ void aoc2019::day18_part1(std::istream &input, std::ostream &output) {
auto implied_graph = compute_implied_graph(map); auto implied_graph = compute_implied_graph(map);
std::priority_queue<std::pair<int, state_t>, std::vector<std::pair<int, state_t>>, std::greater<>> todo; std::priority_queue<std::pair<int, state_t>, std::vector<std::pair<int, state_t>>, std::greater<>> todo;
std::set<state_t> visited; std::map<state_t, int> visited;
todo.emplace(0, std::make_pair(0, '@')); todo.emplace(0, std::make_pair(0, '@'));
auto target_size = std::count_if(implied_graph.cbegin(), implied_graph.cend(), auto target_size = std::count_if(implied_graph.cbegin(), implied_graph.cend(),
@@ -118,12 +118,10 @@ void aoc2019::day18_part1(std::istream &input, std::ostream &output) {
const auto[dist, state] = todo.top(); const auto[dist, state] = todo.top();
todo.pop(); todo.pop();
if (visited.count(state)) { if (visited[state] < dist) {
continue; continue;
} }
visited.insert(state);
auto[keys, pos] = state; auto[keys, pos] = state;
if (std::__popcount(keys) == target_size) { if (std::__popcount(keys) == target_size) {
@@ -145,11 +143,11 @@ void aoc2019::day18_part1(std::istream &input, std::ostream &output) {
} }
state_t next_state = {next_keys, edge.first}; state_t next_state = {next_keys, edge.first};
if (visited.count(next_state)) { if (auto it = visited.find(next_state); it == visited.end() || it->second > next_dist) {
continue; visited[next_state] = next_dist;
todo.emplace(next_dist, next_state);
} }
todo.emplace(next_dist, next_state);
} }
} }
@@ -179,22 +177,21 @@ void aoc2019::day18_part2(std::istream &input, std::ostream &output) {
const auto implied_graph = compute_implied_graph(map); const auto implied_graph = compute_implied_graph(map);
std::priority_queue<std::pair<int, state_t>, std::vector<std::pair<int, state_t>>, std::greater<>> todo; std::priority_queue<std::pair<int, state_t>, std::vector<std::pair<int, state_t>>, std::greater<>> todo;
std::set<state_t> visited; std::map<state_t, int> visited;
todo.emplace(0, state_t(0, {'@', '*', '^', '/'})); todo.emplace(0, state_t(0, {'@', '*', '^', '/'}));
auto target_size = std::count_if(implied_graph.cbegin(), implied_graph.cend(), auto target_size = std::count_if(implied_graph.cbegin(), implied_graph.cend(),
[](auto &x) { return std::islower(x.first); }); [](auto &x) { return std::islower(x.first); });
while (!todo.empty()) { while (!todo.empty()) {
const auto[dist, state] = todo.top(); const auto[dist, state] = todo.top();
todo.pop(); todo.pop();
if (visited.count(state)) { if (visited[state] < dist) {
continue; continue;
} }
visited.insert(state);
auto[keys, pos] = state; auto[keys, pos] = state;
if (std::__popcount(keys) == target_size) { if (std::__popcount(keys) == target_size) {
@@ -204,9 +201,7 @@ void aoc2019::day18_part2(std::istream &input, std::ostream &output) {
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
auto next_pos = pos; auto next_pos = pos;
char &subpos = next_pos[i]; for (const auto &edge : implied_graph.at(pos[i])) {
for (const auto &edge : implied_graph.at(subpos)) {
auto next_dist = dist + edge.second; auto next_dist = dist + edge.second;
auto next_keys = keys; auto next_keys = keys;
if (std::islower(edge.first)) { if (std::islower(edge.first)) {
@@ -219,17 +214,16 @@ void aoc2019::day18_part2(std::istream &input, std::ostream &output) {
} }
} }
subpos = edge.first; next_pos[i] = edge.first;
state_t next_state = {next_keys, next_pos}; state_t next_state = {next_keys, next_pos};
if (visited.count(next_state)) { if (auto it = visited.find(next_state); it == visited.end() || it->second > next_dist) {
continue; visited[next_state] = next_dist;
}
todo.emplace(next_dist, next_state); todo.emplace(next_dist, next_state);
} }
} }
} }
}
output << "Not implemented\n"; output << "Not implemented\n";