From 8b47a9d0f8a573d9de79f7283655c5f4c43e9cbe Mon Sep 17 00:00:00 2001 From: eriedaberrie Date: Mon, 16 Dec 2024 01:18:23 -0800 Subject: [PATCH] 2024 day 16 --- 2024/16/main-1.cpp | 71 +++++++++++++++++++++++++++++ 2024/16/main-2.cpp | 111 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 2024/16/main-1.cpp create mode 100644 2024/16/main-2.cpp diff --git a/2024/16/main-1.cpp b/2024/16/main-1.cpp new file mode 100644 index 0000000..09fa37b --- /dev/null +++ b/2024/16/main-1.cpp @@ -0,0 +1,71 @@ +#include +#include "../../include/aoc.hpp" +using namespace std; + +unordered_map, unordered_map> m; + +inline Coord posdir(int p) { + switch (p) { + case 0: + return {0, 1}; + case 1: + return {1, 0}; + case 2: + return {0, -1}; + case 3: + return {-1, 0}; + default: + return {}; + } +} + +void rec(Coord pos, int dir, int score) { + if (!m.contains(pos)) { + return; + } + + auto &mp = m[pos]; + if (mp.contains(dir) && mp[dir] <= score) { + return; + } + + mp[dir] = score; + rec(pos + posdir(dir), dir, score + 1); + rec(pos, (dir + 1) & 3, score + 1000); + rec(pos, (dir - 1) & 3, score + 1000); +} + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + Coord pos, s, e; + string line; + while (getline(cin, line) && !line.empty()) { + for (pos.y = 0; pos.y < line.size(); pos.y++) { + switch (line[pos.y]) { + case '#': + continue; + case 'S': + s = pos; + break; + case 'E': + e = pos; + break; + } + m[pos]; + } + pos.x++; + } + + rec(s, 0, 0); + + int minscore = -1; + for (auto [dir, score] : m[e]) { + if (minscore == -1 || score < minscore) { + minscore = score; + } + } + + cout << minscore << '\n'; +} diff --git a/2024/16/main-2.cpp b/2024/16/main-2.cpp new file mode 100644 index 0000000..db02443 --- /dev/null +++ b/2024/16/main-2.cpp @@ -0,0 +1,111 @@ +#include +#include "../../include/aoc.hpp" +using namespace std; + +unordered_map, unordered_map>>> m; + +inline Coord posdir(int p) { + switch (p) { + case 0: + return {0, 1}; + case 1: + return {1, 0}; + case 2: + return {0, -1}; + case 3: + return {-1, 0}; + default: + return {}; + } +} + +void rec(Coord pos, int dir, int score, int follow) { + if (!m.contains(pos)) { + return; + } + + auto &mp = m[pos]; + + if (mp.contains(dir)) { + auto &[s, f] = mp[dir]; + if (s < score) { + return; + } + + if (s > score) { + f.clear(); + } + f.insert(follow); + if (s == score) { + return; + } + + s = score; + } else { + mp[dir] = {score, {follow}}; + } + + mp[dir].second.insert(follow); + + rec(pos + posdir(dir), dir, score + 1, dir); + rec(pos, (dir + 1) & 3, score + 1000, follow); + rec(pos, (dir - 1) & 3, score + 1000, follow); +} + +void rec2(unordered_set> &mm, Coord pos, int dir) { + mm.insert(pos); + auto &[s, f] = m[pos][dir]; + for (auto follow : f) { + if (follow == -1) { + continue; + } + + rec2(mm, pos + posdir((follow + 2) & 3), follow); + } +} + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + Coord pos, s, e; + string line; + while (getline(cin, line) && !line.empty()) { + for (pos.y = 0; pos.y < line.size(); pos.y++) { + switch (line[pos.y]) { + case '#': + continue; + case 'S': + s = pos; + break; + case 'E': + e = pos; + break; + } + m[pos]; + } + pos.x++; + } + + rec(s, 0, 0, -1); + + int minscore = -1; + vector dirs; + for (auto &[dir, sf] : m[e]) { + auto &[s, f] = sf; + if (minscore == -1 || s < minscore) { + minscore = s; + dirs.clear(); + } else if (s > minscore) { + continue; + } + dirs.push_back(dir); + } + + unordered_set> mm; + for (auto dir : dirs) { + rec2(mm, e, dir); + } + + cout << mm.size() << '\n'; +}