diff options
author | Federico Igne <undyamon@disroot.org> | 2023-12-14 15:51:22 +0100 |
---|---|---|
committer | Federico Igne <undyamon@disroot.org> | 2023-12-14 15:51:22 +0100 |
commit | fd2077171f5b0b1a9f3bb4224865f0d5c84c21ae (patch) | |
tree | 9f6a9f4617dbbbc5e61a382458ae5d6f95776c9d | |
parent | a388690e255427aa28a2fd4364e094a10bde3382 (diff) | |
download | aoc-fd2077171f5b0b1a9f3bb4224865f0d5c84c21ae.tar.gz aoc-fd2077171f5b0b1a9f3bb4224865f0d5c84c21ae.zip |
aoc(2314): Parabolic Reflector Dish
-rw-r--r-- | 2023/14/Makefile | 19 | ||||
-rw-r--r-- | 2023/14/resources/input_small.txt | 10 | ||||
-rw-r--r-- | 2023/14/src/part1.cpp | 41 | ||||
-rw-r--r-- | 2023/14/src/part2.cpp | 167 |
4 files changed, 237 insertions, 0 deletions
diff --git a/2023/14/Makefile b/2023/14/Makefile new file mode 100644 index 0000000..af6a294 --- /dev/null +++ b/2023/14/Makefile | |||
@@ -0,0 +1,19 @@ | |||
1 | CXXFLAGS := -std=c++17 | ||
2 | CPPFLAGS := -I../include | ||
3 | EXE := part1 part2 | ||
4 | |||
5 | .PHONY: all clean configure | ||
6 | |||
7 | all: $(EXE) | ||
8 | |||
9 | configure: | ||
10 | bear -- $(MAKE) all | ||
11 | |||
12 | %.o: %.cpp | ||
13 | $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ | ||
14 | |||
15 | clean: | ||
16 | rm -rf $(EXE) src/*.o compile_commands.json | ||
17 | |||
18 | %: src/%.o | ||
19 | $(CXX) $^ -o $@ | ||
diff --git a/2023/14/resources/input_small.txt b/2023/14/resources/input_small.txt new file mode 100644 index 0000000..5a24dce --- /dev/null +++ b/2023/14/resources/input_small.txt | |||
@@ -0,0 +1,10 @@ | |||
1 | O....#.... | ||
2 | O.OO#....# | ||
3 | .....##... | ||
4 | OO.#O....O | ||
5 | .O.....O#. | ||
6 | O.#..O.#.# | ||
7 | ..O..#O..O | ||
8 | .......O.. | ||
9 | #....###.. | ||
10 | #OO..#.... | ||
diff --git a/2023/14/src/part1.cpp b/2023/14/src/part1.cpp new file mode 100644 index 0000000..c2179b7 --- /dev/null +++ b/2023/14/src/part1.cpp | |||
@@ -0,0 +1,41 @@ | |||
1 | #include <iostream> | ||
2 | #include <fstream> | ||
3 | #include <vector> | ||
4 | |||
5 | std::vector<std::string> parse(const char* file) | ||
6 | { | ||
7 | std::vector<std::string> v; | ||
8 | if (std::ifstream input{ file }; input.is_open()) | ||
9 | { | ||
10 | std::string line; | ||
11 | while (not std::getline(input,line).eof()) | ||
12 | { | ||
13 | v.push_back(std::move(line)); | ||
14 | } | ||
15 | } | ||
16 | return v; | ||
17 | } | ||
18 | |||
19 | int main(int argc, char* argv[]) | ||
20 | { | ||
21 | int answer{}; | ||
22 | |||
23 | auto v = parse(argv[1]); | ||
24 | for (int c = 0; c < v.size(); ++c) | ||
25 | { | ||
26 | int floor = v.size(); | ||
27 | for (int r = 0; r < v.size(); ++r) | ||
28 | { | ||
29 | switch (v[r][c]) | ||
30 | { | ||
31 | case '#': | ||
32 | floor = v.size() - r - 1; | ||
33 | break; | ||
34 | case 'O': | ||
35 | answer += floor--; | ||
36 | } | ||
37 | } | ||
38 | } | ||
39 | std::cout << answer << std::endl; | ||
40 | return 0; | ||
41 | } | ||
diff --git a/2023/14/src/part2.cpp b/2023/14/src/part2.cpp new file mode 100644 index 0000000..7765b3f --- /dev/null +++ b/2023/14/src/part2.cpp | |||
@@ -0,0 +1,167 @@ | |||
1 | #include <iostream> | ||
2 | #include <fstream> | ||
3 | #include <vector> | ||
4 | #include <algorithm> | ||
5 | |||
6 | using Dish = std::vector<std::string>; | ||
7 | using History = std::vector<std::vector<bool>>; | ||
8 | |||
9 | constexpr int CYCLES = 1'000'000'000; | ||
10 | |||
11 | Dish parse(const char* file) | ||
12 | { | ||
13 | Dish v; | ||
14 | |||
15 | if (std::ifstream input{ file }; input.is_open()) | ||
16 | { | ||
17 | std::string line; | ||
18 | while (not std::getline(input,line).eof()) | ||
19 | { | ||
20 | v.push_back(std::move(line)); | ||
21 | } | ||
22 | } | ||
23 | |||
24 | return v; | ||
25 | } | ||
26 | |||
27 | std::vector<bool> encode(const Dish& v) | ||
28 | { | ||
29 | auto len = v.size(); | ||
30 | std::vector<bool> e(len * len, 0); | ||
31 | for (int x = 0; x < len; ++x) | ||
32 | { | ||
33 | for (int y = 0; y < len; ++y) | ||
34 | { | ||
35 | e[x * len + y] = v[x][y] == 'O'; | ||
36 | } | ||
37 | } | ||
38 | return e; | ||
39 | } | ||
40 | |||
41 | Dish& tilt_north(Dish& v) | ||
42 | { | ||
43 | for (int c = 0; c < v.size(); ++c) | ||
44 | { | ||
45 | int floor{}; | ||
46 | for (int r = floor; r < v.size(); ++r) | ||
47 | { | ||
48 | switch (v[r][c]) | ||
49 | { | ||
50 | case '#': | ||
51 | floor = r + 1; | ||
52 | break; | ||
53 | case 'O': | ||
54 | v[r][c] = '.'; | ||
55 | v[floor++][c] = 'O'; | ||
56 | } | ||
57 | } | ||
58 | } | ||
59 | return v; | ||
60 | } | ||
61 | |||
62 | Dish& tilt_south(Dish& v) | ||
63 | { | ||
64 | for (int c = 0; c < v.size(); ++c) | ||
65 | { | ||
66 | int floor{ static_cast<int>(v.size() - 1) }; | ||
67 | for (int r = floor; r >= 0; --r) | ||
68 | { | ||
69 | switch (v[r][c]) | ||
70 | { | ||
71 | case '#': | ||
72 | floor = r - 1; | ||
73 | break; | ||
74 | case 'O': | ||
75 | v[r][c] = '.'; | ||
76 | v[floor--][c] = 'O'; | ||
77 | } | ||
78 | } | ||
79 | } | ||
80 | return v; | ||
81 | } | ||
82 | |||
83 | Dish& tilt_west(Dish& v) | ||
84 | { | ||
85 | for (int r = 0; r < v.size(); ++r) | ||
86 | { | ||
87 | int floor{}; | ||
88 | for (int c = floor; c < v.size(); ++c) | ||
89 | { | ||
90 | switch (v[r][c]) | ||
91 | { | ||
92 | case '#': | ||
93 | floor = c + 1; | ||
94 | break; | ||
95 | case 'O': | ||
96 | v[r][c] = '.'; | ||
97 | v[r][floor++] = 'O'; | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | return v; | ||
102 | } | ||
103 | |||
104 | Dish& tilt_east(Dish& v) | ||
105 | { | ||
106 | for (int r = 0; r < v.size(); ++r) | ||
107 | { | ||
108 | int floor{ static_cast<int>(v.size() - 1) }; | ||
109 | for (int c = floor; c >= 0; --c) | ||
110 | { | ||
111 | switch (v[r][c]) | ||
112 | { | ||
113 | case '#': | ||
114 | floor = c - 1; | ||
115 | break; | ||
116 | case 'O': | ||
117 | v[r][c] = '.'; | ||
118 | v[r][floor--] = 'O'; | ||
119 | } | ||
120 | } | ||
121 | } | ||
122 | return v; | ||
123 | } | ||
124 | |||
125 | Dish& cycle(Dish& v) | ||
126 | { | ||
127 | return tilt_east(tilt_south(tilt_west(tilt_north(v)))); | ||
128 | } | ||
129 | |||
130 | int load(const std::vector<bool>& v, int l) | ||
131 | { | ||
132 | int load{}; | ||
133 | for (int x = 0; x < l; ++x) | ||
134 | { | ||
135 | for (int y = 0; y < l; ++y) | ||
136 | { | ||
137 | load += (l - x) * v[x * l + y]; | ||
138 | } | ||
139 | } | ||
140 | return load; | ||
141 | } | ||
142 | |||
143 | int dup(History& hist, Dish dish) | ||
144 | { | ||
145 | auto h = encode(dish); | ||
146 | if (auto found = std::find(hist.cbegin(), hist.cend(), h); found != hist.cend()) | ||
147 | { | ||
148 | return hist.cend() - found; | ||
149 | } | ||
150 | hist.push_back(std::move(h)); | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | int main(int argc, char* argv[]) | ||
155 | { | ||
156 | auto v = parse(argv[1]); | ||
157 | |||
158 | History history; | ||
159 | history.push_back(encode(v)); | ||
160 | |||
161 | int p, np; | ||
162 | for (p = 0; p == 0; p = dup(history, cycle(v))); | ||
163 | np = history.size() - p; | ||
164 | |||
165 | std::cout << load(history[np + (CYCLES - np) % p], v.size()) << std::endl; | ||
166 | return 0; | ||
167 | } | ||