diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2024-12-21 08:53:28 +0100 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2024-12-21 08:53:28 +0100 |
| commit | 6cbc9b03a74bcb295271de36256318d6945a2963 (patch) | |
| tree | df1a62fcad4027059ff38c8e900d5851002bd07f | |
| parent | ecb8bdb0b63536916a3a3d55fd4ebbf7aeb21997 (diff) | |
| download | aoc-6cbc9b03a74bcb295271de36256318d6945a2963.tar.gz aoc-6cbc9b03a74bcb295271de36256318d6945a2963.zip | |
Day 21 2024
| -rw-r--r-- | 2024/21/Makefile | 11 | ||||
| -rw-r--r-- | 2024/21/day21a-debuggable.cpp | 129 | ||||
| -rw-r--r-- | 2024/21/day21a.cpp | 99 | ||||
| -rw-r--r-- | 2024/21/day21b.cpp | 102 |
4 files changed, 341 insertions, 0 deletions
diff --git a/2024/21/Makefile b/2024/21/Makefile new file mode 100644 index 0000000..baf7c67 --- /dev/null +++ b/2024/21/Makefile | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | CC=g++ -std=c++20 -g -Wall | ||
| 2 | |||
| 3 | a: | ||
| 4 | ${CC} -o a.out day21a.cpp | ||
| 5 | ./a.out | ||
| 6 | |||
| 7 | b: | ||
| 8 | ${CC} -o b.out day21b.cpp | ||
| 9 | ./b.out | ||
| 10 | |||
| 11 | .PHONY: a b | ||
diff --git a/2024/21/day21a-debuggable.cpp b/2024/21/day21a-debuggable.cpp new file mode 100644 index 0000000..c7ab5d5 --- /dev/null +++ b/2024/21/day21a-debuggable.cpp | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | #include <algorithm> | ||
| 2 | #include <cstdint> | ||
| 3 | #include <iostream> | ||
| 4 | #include <limits> | ||
| 5 | #include <map> | ||
| 6 | #include <queue> | ||
| 7 | #include <ranges> | ||
| 8 | #include <set> | ||
| 9 | #include <sstream> | ||
| 10 | #include <string> | ||
| 11 | #include <string_view> | ||
| 12 | #include <vector> | ||
| 13 | using namespace std; | ||
| 14 | |||
| 15 | map<char, pair<int, int>> m_num = { | ||
| 16 | {'7', {0,0}}, {'8', {0,1}}, {'9', {0,2}}, | ||
| 17 | {'4', {1,0}}, {'5', {1,1}}, {'6', {1,2}}, | ||
| 18 | {'1', {2,0}}, {'2', {2,1}}, {'3', {2,2}}, | ||
| 19 | {'x', {3,0}}, {'0', {3,1}}, {'A', {3,2}}, | ||
| 20 | }; | ||
| 21 | |||
| 22 | map<char, pair<int, int>> m_dir = { | ||
| 23 | {'x', {0,0}}, {'^', {0,1}}, {'A', {0,2}}, | ||
| 24 | {'<', {1,0}}, {'v', {1,1}}, {'>', {1,2}}, | ||
| 25 | }; | ||
| 26 | |||
| 27 | map<pair<int, int>, char> rev_num; | ||
| 28 | map<pair<int, int>, char> rev_dir; | ||
| 29 | |||
| 30 | map<pair<char, char>, vector<string>> p; | ||
| 31 | |||
| 32 | vector<pair<pair<int, int>, char>> directions = { | ||
| 33 | {{1,0}, 'v'}, {{-1,0}, '^'}, {{0,1}, '>'}, {{0,-1}, '<'} | ||
| 34 | }; | ||
| 35 | |||
| 36 | int distance(int cx, int cy, int dx, int dy) { | ||
| 37 | return abs(cx-dx) + abs(cy-dy); | ||
| 38 | } | ||
| 39 | |||
| 40 | vector<string> paths(char c, char d, | ||
| 41 | map<char, pair<int, int>>& m, map<pair<int, int>, char>& rev) { | ||
| 42 | if (p[make_pair(c, d)].size() != 0) return p[make_pair(c, d)]; | ||
| 43 | if (c == d) return {""}; | ||
| 44 | if (c == 'x') return {}; | ||
| 45 | |||
| 46 | vector<string> v; | ||
| 47 | auto [cx, cy] = m[c]; | ||
| 48 | auto [dx, dy] = m[d]; | ||
| 49 | for (auto [dir, dirc] : directions) { | ||
| 50 | pair i = make_pair(cx+dir.first, cy+dir.second); | ||
| 51 | if (distance(cx, cy, dx, dy) < distance(i.first, i.second, dx, dy)) | ||
| 52 | continue; | ||
| 53 | auto next = paths(rev[i], d, m, rev); | ||
| 54 | for (auto n : next) | ||
| 55 | v.push_back(dirc+n); | ||
| 56 | } | ||
| 57 | |||
| 58 | return p[make_pair(c, d)] = v; | ||
| 59 | } | ||
| 60 | |||
| 61 | string pushes_human(char c, char d) { | ||
| 62 | auto p = paths(c, d, m_dir, rev_dir); | ||
| 63 | auto shortest = numeric_limits<size_t>::max(); | ||
| 64 | string ret; | ||
| 65 | for (auto path : p) { | ||
| 66 | if (path.size() + 1 < shortest) { | ||
| 67 | ret = path + 'A'; | ||
| 68 | shortest = path.size() + 1; | ||
| 69 | } | ||
| 70 | } | ||
| 71 | return ret; | ||
| 72 | } | ||
| 73 | |||
| 74 | string pushes_dir1(char c, char d) { | ||
| 75 | auto p = paths(c, d, m_dir, rev_dir); | ||
| 76 | auto shortest = numeric_limits<size_t>::max(); | ||
| 77 | string ret; | ||
| 78 | for (auto path : p) { | ||
| 79 | path = 'A' + path + 'A'; | ||
| 80 | string pushes = ""; | ||
| 81 | for (unsigned i = 0; i < path.size()-1; i++) | ||
| 82 | pushes += pushes_human(path[i], path[i+1]); | ||
| 83 | if (pushes.size() < shortest) { | ||
| 84 | ret = pushes; | ||
| 85 | shortest = pushes.size(); | ||
| 86 | } | ||
| 87 | } | ||
| 88 | return ret; | ||
| 89 | } | ||
| 90 | |||
| 91 | string pushes_numpad(char c, char d) { | ||
| 92 | auto p = paths(c, d, m_num, rev_num); | ||
| 93 | auto shortest = numeric_limits<size_t>::max(); | ||
| 94 | string ret; | ||
| 95 | for (auto path : p) { | ||
| 96 | path = 'A' + path + 'A'; | ||
| 97 | string pushes = ""; | ||
| 98 | for (unsigned i = 0; i < path.size()-1; i++) | ||
| 99 | pushes += pushes_dir1(path[i], path[i+1]); | ||
| 100 | if (pushes.size() < shortest) { | ||
| 101 | ret = pushes; | ||
| 102 | shortest = pushes.size(); | ||
| 103 | } | ||
| 104 | } | ||
| 105 | return ret; | ||
| 106 | } | ||
| 107 | |||
| 108 | int64_t numeric(const string& code) { | ||
| 109 | return (code[0]-'0')*100 + (code[1]-'0')*10 + (code[2]-'0'); | ||
| 110 | } | ||
| 111 | |||
| 112 | int main() { | ||
| 113 | for (auto [k, v] : m_num) rev_num[v] = k; | ||
| 114 | for (auto [k, v] : m_dir) rev_dir[v] = k; | ||
| 115 | |||
| 116 | string line; | ||
| 117 | int64_t tot = 0; | ||
| 118 | while (getline(cin, line)) { | ||
| 119 | string ppp; | ||
| 120 | int64_t num = numeric(line); | ||
| 121 | line = 'A' + line; | ||
| 122 | for (unsigned i = 0; i < line.size()-1; i++) | ||
| 123 | ppp += pushes_numpad(line[i], line[i+1]); | ||
| 124 | cout << ppp << endl; | ||
| 125 | tot += ppp.size() * num; | ||
| 126 | } | ||
| 127 | cout << tot << endl; | ||
| 128 | return 0; | ||
| 129 | } | ||
diff --git a/2024/21/day21a.cpp b/2024/21/day21a.cpp new file mode 100644 index 0000000..742d9d2 --- /dev/null +++ b/2024/21/day21a.cpp | |||
| @@ -0,0 +1,99 @@ | |||
| 1 | #include <algorithm> | ||
| 2 | #include <cstdint> | ||
| 3 | #include <iostream> | ||
| 4 | #include <limits> | ||
| 5 | #include <map> | ||
| 6 | #include <queue> | ||
| 7 | #include <ranges> | ||
| 8 | #include <set> | ||
| 9 | #include <sstream> | ||
| 10 | #include <string> | ||
| 11 | #include <string_view> | ||
| 12 | #include <vector> | ||
| 13 | using namespace std; | ||
| 14 | |||
| 15 | map<char, pair<int, int>> m_num = { | ||
| 16 | {'7', {0,0}}, {'8', {0,1}}, {'9', {0,2}}, | ||
| 17 | {'4', {1,0}}, {'5', {1,1}}, {'6', {1,2}}, | ||
| 18 | {'1', {2,0}}, {'2', {2,1}}, {'3', {2,2}}, | ||
| 19 | {'x', {3,0}}, {'0', {3,1}}, {'A', {3,2}}, | ||
| 20 | }; | ||
| 21 | |||
| 22 | map<char, pair<int, int>> m_dir = { | ||
| 23 | {'x', {0,0}}, {'^', {0,1}}, {'A', {0,2}}, | ||
| 24 | {'<', {1,0}}, {'v', {1,1}}, {'>', {1,2}}, | ||
| 25 | }; | ||
| 26 | |||
| 27 | map<pair<int, int>, char> rev_num; | ||
| 28 | map<pair<int, int>, char> rev_dir; | ||
| 29 | |||
| 30 | map<pair<char, char>, vector<string>> p; | ||
| 31 | |||
| 32 | vector<pair<pair<int, int>, char>> directions = { | ||
| 33 | {{1,0}, 'v'}, {{-1,0}, '^'}, {{0,1}, '>'}, {{0,-1}, '<'} | ||
| 34 | }; | ||
| 35 | |||
| 36 | int distance(int cx, int cy, int dx, int dy) { | ||
| 37 | return abs(cx-dx) + abs(cy-dy); | ||
| 38 | } | ||
| 39 | |||
| 40 | vector<string> paths(char c, char d, | ||
| 41 | map<char, pair<int, int>>& m, map<pair<int, int>, char>& rev) { | ||
| 42 | if (p[make_pair(c, d)].size() != 0) return p[make_pair(c, d)]; | ||
| 43 | if (c == d) return {""}; | ||
| 44 | if (c == 'x') return {}; | ||
| 45 | |||
| 46 | vector<string> v; | ||
| 47 | auto [cx, cy] = m[c]; | ||
| 48 | auto [dx, dy] = m[d]; | ||
| 49 | for (auto [dir, dirc] : directions) { | ||
| 50 | pair i = make_pair(cx+dir.first, cy+dir.second); | ||
| 51 | if (distance(cx, cy, dx, dy) < distance(i.first, i.second, dx, dy)) | ||
| 52 | continue; | ||
| 53 | auto next = paths(rev[i], d, m, rev); | ||
| 54 | for (auto n : next) | ||
| 55 | v.push_back(dirc+n); | ||
| 56 | } | ||
| 57 | |||
| 58 | return p[make_pair(c, d)] = v; | ||
| 59 | } | ||
| 60 | |||
| 61 | int64_t pushes(char c, char d, map<char, | ||
| 62 | pair<int, int>>& m, map<pair<int, int>, char>& r, int n) { | ||
| 63 | auto p = paths(c, d, m, r); | ||
| 64 | auto ret = numeric_limits<int64_t>::max(); | ||
| 65 | for (auto path : p) { | ||
| 66 | if (n == 0) { | ||
| 67 | ret = min(ret, (int64_t)path.size()+1); | ||
| 68 | } else { | ||
| 69 | path = 'A' + path + 'A'; | ||
| 70 | int64_t u = 0; | ||
| 71 | for (unsigned i = 0; i < path.size()-1; i++) | ||
| 72 | u += pushes(path[i], path[i+1], m_dir, rev_dir, n-1); | ||
| 73 | ret = min(ret, u); | ||
| 74 | } | ||
| 75 | } | ||
| 76 | return ret; | ||
| 77 | } | ||
| 78 | |||
| 79 | int64_t numeric(const string& code) { | ||
| 80 | return (code[0]-'0')*100 + (code[1]-'0')*10 + (code[2]-'0'); | ||
| 81 | } | ||
| 82 | |||
| 83 | int main() { | ||
| 84 | for (auto [k, v] : m_num) rev_num[v] = k; | ||
| 85 | for (auto [k, v] : m_dir) rev_dir[v] = k; | ||
| 86 | |||
| 87 | string line; | ||
| 88 | int64_t tot = 0; | ||
| 89 | while (getline(cin, line)) { | ||
| 90 | int64_t comp = 0; | ||
| 91 | int64_t num = numeric(line); | ||
| 92 | line = 'A' + line; | ||
| 93 | for (unsigned i = 0; i < line.size()-1; i++) | ||
| 94 | comp += pushes(line[i], line[i+1], m_num, rev_num, 2); | ||
| 95 | tot += comp * num; | ||
| 96 | } | ||
| 97 | cout << tot << endl; | ||
| 98 | return 0; | ||
| 99 | } | ||
diff --git a/2024/21/day21b.cpp b/2024/21/day21b.cpp new file mode 100644 index 0000000..dcca14e --- /dev/null +++ b/2024/21/day21b.cpp | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | #include <algorithm> | ||
| 2 | #include <cstdint> | ||
| 3 | #include <iostream> | ||
| 4 | #include <limits> | ||
| 5 | #include <map> | ||
| 6 | #include <queue> | ||
| 7 | #include <ranges> | ||
| 8 | #include <set> | ||
| 9 | #include <sstream> | ||
| 10 | #include <string> | ||
| 11 | #include <string_view> | ||
| 12 | #include <vector> | ||
| 13 | using namespace std; | ||
| 14 | |||
| 15 | map<char, pair<int, int>> m_num = { | ||
| 16 | {'7', {0,0}}, {'8', {0,1}}, {'9', {0,2}}, | ||
| 17 | {'4', {1,0}}, {'5', {1,1}}, {'6', {1,2}}, | ||
| 18 | {'1', {2,0}}, {'2', {2,1}}, {'3', {2,2}}, | ||
| 19 | {'x', {3,0}}, {'0', {3,1}}, {'A', {3,2}}, | ||
| 20 | }; | ||
| 21 | |||
| 22 | map<char, pair<int, int>> m_dir = { | ||
| 23 | {'x', {0,0}}, {'^', {0,1}}, {'A', {0,2}}, | ||
| 24 | {'<', {1,0}}, {'v', {1,1}}, {'>', {1,2}}, | ||
| 25 | }; | ||
| 26 | |||
| 27 | map<pair<int, int>, char> rev_num; | ||
| 28 | map<pair<int, int>, char> rev_dir; | ||
| 29 | |||
| 30 | map<pair<char, char>, vector<string>> p; | ||
| 31 | |||
| 32 | vector<pair<pair<int, int>, char>> directions = { | ||
| 33 | {{1,0}, 'v'}, {{-1,0}, '^'}, {{0,1}, '>'}, {{0,-1}, '<'} | ||
| 34 | }; | ||
| 35 | |||
| 36 | int distance(int cx, int cy, int dx, int dy) { | ||
| 37 | return abs(cx-dx) + abs(cy-dy); | ||
| 38 | } | ||
| 39 | |||
| 40 | vector<string> paths(char c, char d, | ||
| 41 | map<char, pair<int, int>>& m, map<pair<int, int>, char>& rev) { | ||
| 42 | if (p[make_pair(c, d)].size() != 0) return p[make_pair(c, d)]; | ||
| 43 | if (c == d) return {""}; | ||
| 44 | if (c == 'x') return {}; | ||
| 45 | |||
| 46 | vector<string> v; | ||
| 47 | auto [cx, cy] = m[c]; | ||
| 48 | auto [dx, dy] = m[d]; | ||
| 49 | for (auto [dir, dirc] : directions) { | ||
| 50 | pair i = make_pair(cx+dir.first, cy+dir.second); | ||
| 51 | if (distance(cx, cy, dx, dy) < distance(i.first, i.second, dx, dy)) | ||
| 52 | continue; | ||
| 53 | const auto next = paths(rev[i], d, m, rev); | ||
| 54 | for (auto n : next) | ||
| 55 | v.push_back(dirc+n); | ||
| 56 | } | ||
| 57 | |||
| 58 | return p[make_pair(c, d)] = v; | ||
| 59 | } | ||
| 60 | |||
| 61 | map<tuple<char, char, int>, int64_t> t; | ||
| 62 | int64_t pushes(char c, char d, | ||
| 63 | map<char, pair<int, int>>& m, map<pair<int, int>, char>& r, int n) { | ||
| 64 | if (t.count(make_tuple(c, d, n))) | ||
| 65 | return t[make_tuple(c, d, n)]; | ||
| 66 | const auto p = paths(c, d, m, r); | ||
| 67 | auto ret = numeric_limits<int64_t>::max(); | ||
| 68 | for (const auto& path : p) { | ||
| 69 | if (n == 0) { | ||
| 70 | ret = min(ret, (int64_t)path.size()+1); | ||
| 71 | } else { | ||
| 72 | string q = 'A' + path + 'A'; | ||
| 73 | int64_t u = 0; | ||
| 74 | for (unsigned i = 0; i < q.size()-1; i++) | ||
| 75 | u += pushes(q[i], q[i+1], m_dir, rev_dir, n-1); | ||
| 76 | ret = min(ret, u); | ||
| 77 | } | ||
| 78 | } | ||
| 79 | return t[make_tuple(c, d, n)] = ret; | ||
| 80 | } | ||
| 81 | |||
| 82 | int64_t numeric(const string& code) { | ||
| 83 | return (code[0]-'0')*100 + (code[1]-'0')*10 + (code[2]-'0'); | ||
| 84 | } | ||
| 85 | |||
| 86 | int main() { | ||
| 87 | for (auto [k, v] : m_num) rev_num[v] = k; | ||
| 88 | for (auto [k, v] : m_dir) rev_dir[v] = k; | ||
| 89 | |||
| 90 | string line; | ||
| 91 | int64_t tot = 0; | ||
| 92 | while (getline(cin, line)) { | ||
| 93 | int64_t comp = 0; | ||
| 94 | int64_t num = numeric(line); | ||
| 95 | line = 'A' + line; | ||
| 96 | for (unsigned i = 0; i < line.size()-1; i++) | ||
| 97 | comp += pushes(line[i], line[i+1], m_num, rev_num, 25); | ||
| 98 | tot += comp * num; | ||
| 99 | } | ||
| 100 | cout << tot << endl; | ||
| 101 | return 0; | ||
| 102 | } | ||
