summaryrefslogtreecommitdiff
path: root/2023/08/src
diff options
context:
space:
mode:
Diffstat (limited to '2023/08/src')
-rw-r--r--2023/08/src/part1.cpp70
-rw-r--r--2023/08/src/part2.cpp78
2 files changed, 148 insertions, 0 deletions
diff --git a/2023/08/src/part1.cpp b/2023/08/src/part1.cpp
new file mode 100644
index 0000000..9585536
--- /dev/null
+++ b/2023/08/src/part1.cpp
@@ -0,0 +1,70 @@
1#include <iostream>
2#include <fstream>
3#include <sstream>
4#include <unordered_map>
5#include <vector>
6
7#include "util.h"
8
9using Moves = std::vector<bool>;
10using Map = std::unordered_map<int,std::pair<int,int>>;
11
12constexpr char EQUAL[] = "=";
13
14int encode(std::string str)
15{
16 int res{};
17 for (unsigned char c : str)
18 {
19 if ('A' <= c and c <= 'Z')
20 {
21 res *= 1 + 'Z' - 'A';
22 res += c - 'A';
23 }
24 }
25 return res;
26}
27
28std::pair<Moves,Map> parse(const char* path)
29{
30 Map map{};
31 Moves moves{};
32
33 std::ifstream input{ path };
34 if (input.is_open())
35 {
36 std::string line;
37 std::getline(input,line);
38
39 moves.resize(line.size());
40 std::transform(line.cbegin(), line.cend(),
41 moves.begin(), [](unsigned char c) { return c == 'L'; });
42
43 std::string from, tol, tor;
44 while (not std::getline(input,line).eof())
45 {
46 if (line.empty()) continue;
47
48 std::istringstream in{ line };
49 in >> from >> util::skip<EQUAL> >> tol >> tor;
50 map.insert({ encode(from), { encode(tol), encode(tor) } });
51 }
52 }
53 input.close();
54
55 return { std::move(moves), std::move(map) };
56}
57
58int main(int argc, char* argv[])
59{
60 int answer{};
61
62 auto [moves, map] = parse(argv[1]);
63
64 for (int pos = encode("AAA");
65 pos != encode("ZZZ");
66 pos = moves[answer++ % moves.size()] ? map[pos].first : map[pos].second);
67
68 std::cout << answer << std::endl;
69 return 0;
70}
diff --git a/2023/08/src/part2.cpp b/2023/08/src/part2.cpp
new file mode 100644
index 0000000..23b456d
--- /dev/null
+++ b/2023/08/src/part2.cpp
@@ -0,0 +1,78 @@
1#include <fstream>
2#include <iostream>
3#include <sstream>
4#include <unordered_map>
5#include <vector>
6#include <numeric>
7
8#include "util.h"
9
10using Pos = std::string;
11using Moves = std::vector<bool>;
12using Map = std::unordered_map<Pos,std::pair<Pos,Pos>>;
13
14constexpr char EQUAL[] = "=";
15
16std::pair<Moves,Map> parse(const char* path)
17{
18 Map map{};
19 Moves moves{};
20
21 std::ifstream input{ path };
22 if (input.is_open())
23 {
24 std::string line;
25 std::getline(input,line);
26
27 moves.resize(line.size());
28 std::transform(line.cbegin(), line.cend(),
29 moves.begin(), [](unsigned char c) { return c == 'L'; });
30
31 std::string from, tol, tor;
32 while (not std::getline(input,line).eof())
33 {
34 if (line.empty()) continue;
35
36 std::istringstream in{ line };
37 in >> from >> util::skip<EQUAL> >> tol >> tor;
38 tol.erase(0,1); tol.pop_back();
39 tor.pop_back();
40 map.insert({ from, { tol, tor } });
41 }
42 }
43 input.close();
44
45 return { std::move(moves), std::move(map) };
46}
47
48long long compute(const Map& map, const Moves& moves, Pos pos)
49{
50 long long idx{};
51
52 while (pos[2] != 'Z')
53 {
54 bool left = moves[idx++ % moves.size()];
55 pos = left ? map.at(pos).first : map.at(pos).second;
56 }
57
58 return idx;
59}
60
61int main(int argc, char* argv[])
62{
63 long long answer{ 1 };
64
65 auto [moves, map] = parse(argv[1]);
66
67 for (const auto& kv : map)
68 {
69 if (kv.first[2] == 'A')
70 {
71 answer = std::lcm(answer, compute(map, moves, kv.first));
72 }
73 }
74
75 std::cout << answer << std::endl;
76 return 0;
77}
78