mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-26 21:30:31 +01:00
Optimize day 18 a bit.
This commit is contained in:
@@ -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,14 +214,13 @@ 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user