diff --git a/2024/21/main-1.cpp b/2024/21/main-1.cpp new file mode 100644 index 0000000..5202763 --- /dev/null +++ b/2024/21/main-1.cpp @@ -0,0 +1,108 @@ +#include "../../include/aoc.hpp" +#include +using namespace std; + +const int ml = 2; + +unordered_map npad = { + {'7', {0, 0}}, {'8', {0, 1}}, {'9', {0, 2}}, {'4', {1, 0}}, + {'5', {1, 1}}, {'6', {1, 2}}, {'1', {2, 0}}, {'2', {2, 1}}, + {'3', {2, 2}}, {'0', {3, 1}}, {'A', {3, 2}}, +}; + +unordered_map dpad = { + {'^', {0, 1}}, {'A', {0, 2}}, {'<', {1, 0}}, {'v', {1, 1}}, {'>', {1, 2}}, +}; + +unordered_map dirs = { + {{-1, 0}, '^'}, + {{0, 1}, '>'}, + {{1, 0}, 'v'}, + {{0, -1}, '<'}, +}; + +inline size_t hc(icoord a, icoord b, int level) { + return (a.x) | (a.y << 4) | (b.x << 8) | (b.y << 12) | (level << 16); +} + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + unordered_set npads, dpads; + for (auto &p : npad) { + npads.insert(p.second); + } + for (auto &p : dpad) { + dpads.insert(p.second); + } + + unordered_map mm; + for (icoord start : dpads) { + for (icoord end : dpads) { + auto d = start - end; + mm[hc(start, end, 0)] = abs(d.x) + abs(d.y); + } + } + + for (int level = 1; level <= ml; level++) { + auto &pads = (level == ml) ? npads : dpads; + for (auto start : pads) { + mm[hc(start, start, level)] = 0; + for (auto end : pads) { + if (end == start) { + continue; + } + int best = -1; + icoord d = end - start; + auto xc = dpad[(d.x > 0) ? 'v' : '^']; + auto yc = dpad[(d.y > 0) ? '>' : '<']; + if (d.x == 0) { + best = abs(d.y); + best += mm[hc(dpad['A'], yc, level - 1)]; + best += mm[hc(yc, dpad['A'], level - 1)]; + } else if (d.y == 0) { + best = abs(d.x); + best += mm[hc(dpad['A'], xc, level - 1)]; + best += mm[hc(xc, dpad['A'], level - 1)]; + } else { + for (int i = 0; i < 2; i++) { + icoord mid; + ll score = abs(d.x) + abs(d.y); + if (i == 0) { + mid = icoord(start.x, end.y); + score += mm[hc(dpad['A'], yc, level - 1)]; + score += mm[hc(yc, xc, level - 1)]; + score += mm[hc(xc, dpad['A'], level - 1)]; + } else { + mid = icoord(end.x, start.y); + score += mm[hc(dpad['A'], xc, level - 1)]; + score += mm[hc(xc, yc, level - 1)]; + score += mm[hc(yc, dpad['A'], level - 1)]; + } + if (pads.contains(mid) && + (best == -1 || score < best)) { + best = score; + } + } + } + mm[hc(start, end, level)] = best; + } + } + } + + int tcount = 0; + string line; + while (getline(cin, line)) { + int count = 0; + auto pos = npad['A']; + for (char c : line) { + auto newpos = npad[c]; + count += mm[hc(pos, newpos, ml)] + 1; + pos = newpos; + } + tcount += count * stoi(line.substr(0, 3)); + } + + cout << tcount << '\n'; +} diff --git a/2024/21/main-2.cpp b/2024/21/main-2.cpp new file mode 100644 index 0000000..0f83024 --- /dev/null +++ b/2024/21/main-2.cpp @@ -0,0 +1,108 @@ +#include "../../include/aoc.hpp" +#include +using namespace std; + +const int ml = 25; + +unordered_map npad = { + {'7', {0, 0}}, {'8', {0, 1}}, {'9', {0, 2}}, {'4', {1, 0}}, + {'5', {1, 1}}, {'6', {1, 2}}, {'1', {2, 0}}, {'2', {2, 1}}, + {'3', {2, 2}}, {'0', {3, 1}}, {'A', {3, 2}}, +}; + +unordered_map dpad = { + {'^', {0, 1}}, {'A', {0, 2}}, {'<', {1, 0}}, {'v', {1, 1}}, {'>', {1, 2}}, +}; + +unordered_map dirs = { + {{-1, 0}, '^'}, + {{0, 1}, '>'}, + {{1, 0}, 'v'}, + {{0, -1}, '<'}, +}; + +inline size_t hc(icoord a, icoord b, int level) { + return (a.x) | (a.y << 4) | (b.x << 8) | (b.y << 12) | (level << 16); +} + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + unordered_set npads, dpads; + for (auto &p : npad) { + npads.insert(p.second); + } + for (auto &p : dpad) { + dpads.insert(p.second); + } + + unordered_map mm; + for (icoord start : dpads) { + for (icoord end : dpads) { + auto d = start - end; + mm[hc(start, end, 0)] = abs(d.x) + abs(d.y); + } + } + + for (int level = 1; level <= ml; level++) { + auto &pads = (level == ml) ? npads : dpads; + for (auto start : pads) { + mm[hc(start, start, level)] = 0; + for (auto end : pads) { + if (end == start) { + continue; + } + ll best = -1; + icoord d = end - start; + auto xc = dpad[(d.x > 0) ? 'v' : '^']; + auto yc = dpad[(d.y > 0) ? '>' : '<']; + if (d.x == 0) { + best = abs(d.y); + best += mm[hc(dpad['A'], yc, level - 1)]; + best += mm[hc(yc, dpad['A'], level - 1)]; + } else if (d.y == 0) { + best = abs(d.x); + best += mm[hc(dpad['A'], xc, level - 1)]; + best += mm[hc(xc, dpad['A'], level - 1)]; + } else { + for (int i = 0; i < 2; i++) { + icoord mid; + ll score = abs(d.x) + abs(d.y); + if (i == 0) { + mid = icoord(start.x, end.y); + score += mm[hc(dpad['A'], yc, level - 1)]; + score += mm[hc(yc, xc, level - 1)]; + score += mm[hc(xc, dpad['A'], level - 1)]; + } else { + mid = icoord(end.x, start.y); + score += mm[hc(dpad['A'], xc, level - 1)]; + score += mm[hc(xc, yc, level - 1)]; + score += mm[hc(yc, dpad['A'], level - 1)]; + } + if (pads.contains(mid) && + (best == -1 || score < best)) { + best = score; + } + } + } + mm[hc(start, end, level)] = best; + } + } + } + + ll tcount = 0; + string line; + while (getline(cin, line)) { + ll count = 0; + auto pos = npad['A']; + for (char c : line) { + auto newpos = npad[c]; + count += mm[hc(pos, newpos, ml)] + 1; + pos = newpos; + } + tcount += count * stoi(line.substr(0, 3)); + } + + cout << tcount << '\n'; +}