summaryrefslogtreecommitdiff
path: root/2023/08/src/part2.cpp
diff options
context:
space:
mode:
Diffstat (limited to '2023/08/src/part2.cpp')
-rw-r--r--2023/08/src/part2.cpp78
1 files changed, 78 insertions, 0 deletions
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