summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--2023/08/Makefile19
-rw-r--r--2023/08/resources/input_small1.txt9
-rw-r--r--2023/08/resources/input_small2.txt5
-rw-r--r--2023/08/resources/input_small3.txt10
-rw-r--r--2023/08/src/part1.cpp70
-rw-r--r--2023/08/src/part2.cpp78
6 files changed, 191 insertions, 0 deletions
diff --git a/2023/08/Makefile b/2023/08/Makefile
new file mode 100644
index 0000000..af6a294
--- /dev/null
+++ b/2023/08/Makefile
@@ -0,0 +1,19 @@
1CXXFLAGS := -std=c++17
2CPPFLAGS := -I../include
3EXE := part1 part2
4
5.PHONY: all clean configure
6
7all: $(EXE)
8
9configure:
10 bear -- $(MAKE) all
11
12%.o: %.cpp
13 $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@
14
15clean:
16 rm -rf $(EXE) src/*.o compile_commands.json
17
18%: src/%.o
19 $(CXX) $^ -o $@
diff --git a/2023/08/resources/input_small1.txt b/2023/08/resources/input_small1.txt
new file mode 100644
index 0000000..9029a1b
--- /dev/null
+++ b/2023/08/resources/input_small1.txt
@@ -0,0 +1,9 @@
1RL
2
3AAA = (BBB, CCC)
4BBB = (DDD, EEE)
5CCC = (ZZZ, GGG)
6DDD = (DDD, DDD)
7EEE = (EEE, EEE)
8GGG = (GGG, GGG)
9ZZZ = (ZZZ, ZZZ)
diff --git a/2023/08/resources/input_small2.txt b/2023/08/resources/input_small2.txt
new file mode 100644
index 0000000..7d1b58d
--- /dev/null
+++ b/2023/08/resources/input_small2.txt
@@ -0,0 +1,5 @@
1LLR
2
3AAA = (BBB, BBB)
4BBB = (AAA, ZZZ)
5ZZZ = (ZZZ, ZZZ)
diff --git a/2023/08/resources/input_small3.txt b/2023/08/resources/input_small3.txt
new file mode 100644
index 0000000..abd2095
--- /dev/null
+++ b/2023/08/resources/input_small3.txt
@@ -0,0 +1,10 @@
1LR
2
3AAA = (AAB, XXX)
4AAB = (XXX, AAZ)
5AAZ = (AAB, XXX)
6BBA = (BBB, XXX)
7BBB = (BBC, BBC)
8BBC = (BBZ, BBZ)
9BBZ = (BBB, BBB)
10XXX = (XXX, XXX)
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