aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2023-12-10 21:16:14 +0100
committerThomas Schmucker <ts@its1.de>2023-12-10 21:16:14 +0100
commit0e5defe3603dde4b4b8e2e3a8eeae24046311ebb (patch)
tree3013bf5011d8d4158571b7ecd2131eb824325493
parent28819cfd9284f820e528c61855639134a0f06343 (diff)
downloadadvent-of-code-0e5defe3603dde4b4b8e2e3a8eeae24046311ebb.tar.gz
advent-of-code-0e5defe3603dde4b4b8e2e3a8eeae24046311ebb.tar.bz2
advent-of-code-0e5defe3603dde4b4b8e2e3a8eeae24046311ebb.zip
Code cleanup
-rw-r--r--src/day10.cpp334
1 files changed, 124 insertions, 210 deletions
diff --git a/src/day10.cpp b/src/day10.cpp
index 6b0b28e..5591290 100644
--- a/src/day10.cpp
+++ b/src/day10.cpp
@@ -6,11 +6,14 @@
6#include <vector> 6#include <vector>
7using namespace std; 7using namespace std;
8 8
9vector<string> 9using pos_t = tuple<size_t, size_t>;
10using puzzle_t = vector<string>;
11
12puzzle_t
10read_file(string_view filename) 13read_file(string_view filename)
11{ 14{
12 fstream input{ filename }; 15 fstream input{ filename };
13 vector<string> data; 16 puzzle_t data;
14 17
15 for ( string line; getline(input, line); ) { 18 for ( string line; getline(input, line); ) {
16 data.emplace_back(line); 19 data.emplace_back(line);
@@ -19,102 +22,104 @@ read_file(string_view filename)
19 return data; 22 return data;
20} 23}
21 24
22void 25pos_t
23part1() 26find_start_pos(const puzzle_t& puzzle)
24{ 27{
25 typedef tuple<size_t, size_t> pos_t; 28 for ( size_t y = 0; y != puzzle.size(); ++y ) { // NOLINT
26 29 auto x = puzzle[y].find('S'); // NOLINT
27 const auto puzzle = read_file("data/day10.txt"); 30 if ( x != string::npos ) {
28 31 return { x, y };
29 const auto find_start_pos = [&]() -> pos_t {
30 for ( size_t y = 0; y != puzzle.size(); ++y ) { // NOLINT
31 auto x = puzzle[y].find('S'); // NOLINT
32 if ( x != string::npos ) {
33 return { x, y };
34 }
35 } 32 }
33 }
36 34
37 return { 0, 0 }; 35 return { 0, 0 };
38 }; 36};
39 37
40 const auto predict_direction = [&](pos_t& current, char& direction) -> bool { 38bool
41 auto x = get<0>(current); // NOLINT 39predict_direction(const puzzle_t& puzzle, pos_t& current, char& direction)
42 auto y = get<1>(current); // NOLINT 40{
41 auto x = get<0>(current); // NOLINT
42 auto y = get<1>(current); // NOLINT
43 43
44 if ( direction == 'S' ) { 44 if ( direction == 'S' ) {
45 ++y; 45 ++y;
46 if ( y >= puzzle.size() ) { 46 if ( y >= puzzle.size() ) {
47 return false; 47 return false;
48 }
49 auto tile = puzzle[y][x];
50 if ( tile != 'J' && tile != '|' && tile != 'L' ) {
51 return false;
52 }
53 if ( tile == 'J' ) {
54 direction = 'W';
55 }
56 else if ( tile == 'L' ) {
57 direction = 'E';
58 }
59 } 48 }
60 else if ( direction == 'N' ) { 49 const auto tile = puzzle[y][x];
61 --y; 50 if ( tile != 'J' && tile != '|' && tile != 'L' ) {
62 if ( y >= puzzle.size() ) { 51 return false;
63 return false;
64 }
65 auto tile = puzzle[y][x];
66 if ( tile != '7' && tile != '|' && tile != 'F' ) {
67 return false;
68 }
69 if ( tile == '7' ) {
70 direction = 'W';
71 }
72 else if ( tile == 'F' ) {
73 direction = 'E';
74 }
75 } 52 }
76 else if ( direction == 'E' ) { 53 if ( tile == 'J' ) {
77 ++x; 54 direction = 'W';
78 if ( x >= puzzle[y].size() ) {
79 return false;
80 }
81 auto tile = puzzle[y][x];
82 if ( tile != 'J' && tile != '-' && tile != '7' ) {
83 return false;
84 }
85 if ( tile == 'J' ) {
86 direction = 'N';
87 }
88 else if ( tile == '7' ) {
89 direction = 'S';
90 }
91 } 55 }
92 else if ( direction == 'W' ) { 56 else if ( tile == 'L' ) {
93 --x; 57 direction = 'E';
94 if ( x >= puzzle[y].size() ) { 58 }
95 return false; 59 }
96 } 60 else if ( direction == 'N' ) {
97 auto tile = puzzle[y][x]; 61 --y;
98 if ( tile != 'L' && tile != '-' && tile != 'F' ) { 62 if ( y >= puzzle.size() ) {
99 return false; 63 return false;
100 } 64 }
101 if ( tile == 'L' ) { 65 const auto tile = puzzle[y][x];
102 direction = 'N'; 66 if ( tile != '7' && tile != '|' && tile != 'F' ) {
103 } 67 return false;
104 else if ( tile == 'F' ) { 68 }
105 direction = 'S'; 69 if ( tile == '7' ) {
106 } 70 direction = 'W';
71 }
72 else if ( tile == 'F' ) {
73 direction = 'E';
74 }
75 }
76 else if ( direction == 'E' ) {
77 ++x;
78 if ( x >= puzzle[y].size() ) {
79 return false;
107 } 80 }
108 else { 81 const auto tile = puzzle[y][x];
109 cerr << "invalid direction " << direction << ")!" << endl; 82 if ( tile != 'J' && tile != '-' && tile != '7' ) {
110 return false; 83 return false;
111 } 84 }
85 if ( tile == 'J' ) {
86 direction = 'N';
87 }
88 else if ( tile == '7' ) {
89 direction = 'S';
90 }
91 }
92 else if ( direction == 'W' ) {
93 --x;
94 if ( x >= puzzle[y].size() ) {
95 return false;
96 }
97 const auto tile = puzzle[y][x];
98 if ( tile != 'L' && tile != '-' && tile != 'F' ) {
99 return false;
100 }
101 if ( tile == 'L' ) {
102 direction = 'N';
103 }
104 else if ( tile == 'F' ) {
105 direction = 'S';
106 }
107 }
108 else {
109 cerr << "invalid direction " << direction << ")!" << endl;
110 return false;
111 }
112 112
113 current = { x, y }; 113 current = { x, y };
114 return true; 114 return true;
115 }; 115};
116 116
117 const auto start_pos = find_start_pos(); 117void
118part1()
119{
120 const auto puzzle = read_file("data/day10.txt");
121
122 const auto start_pos = find_start_pos(puzzle);
118 123
119 auto max_steps = 0; 124 auto max_steps = 0;
120 125
@@ -126,11 +131,10 @@ part1()
126 for ( ;; ) { 131 for ( ;; ) {
127 ++steps; 132 ++steps;
128 133
129 if ( !predict_direction(current_pos, current_direction) ) { 134 if ( !predict_direction(puzzle, current_pos, current_direction) ) {
130 break; 135 break;
131 } 136 }
132 } 137 }
133 cout << "Richtung: " << direction << " - Schritte: " << steps << endl;
134 138
135 max_steps = max(max_steps, steps); 139 max_steps = max(max_steps, steps);
136 } 140 }
@@ -138,104 +142,34 @@ part1()
138 cout << max_steps / 2 << endl; 142 cout << max_steps / 2 << endl;
139} 143}
140 144
141void 145bool
142part2() 146flood_fill(puzzle_t& puzzle, size_t x, size_t y)
143{ 147{
144 typedef tuple<size_t, size_t> pos_t; 148 if ( y >= puzzle.size() || x >= puzzle[0].size() ) {
145 149 return false;
146 const auto puzzle = read_file("data/day10.txt"); 150 }
147
148 const auto find_start_pos = [&]() -> pos_t {
149 for ( size_t y = 0; y != puzzle.size(); ++y ) { // NOLINT
150 auto x = puzzle[y].find('S'); // NOLINT
151 if ( x != string::npos ) {
152 return { x, y };
153 }
154 }
155
156 return { 0, 0 };
157 };
158
159 const auto predict_direction = [&](pos_t& current, char& direction) -> bool {
160 auto x = get<0>(current); // NOLINT
161 auto y = get<1>(current); // NOLINT
162 151
163 if ( direction == 'S' ) { 152 if ( puzzle[y][x] == ' ' ) {
164 ++y; 153 puzzle[y][x] = 'o';
165 if ( y >= puzzle.size() ) { 154 if ( !flood_fill(puzzle, x, y + 1) ||
166 return false; 155 !flood_fill(puzzle, x, y - 1) ||
167 } 156 !flood_fill(puzzle, x + 1, y) ||
168 auto tile = puzzle[y][x]; 157 !flood_fill(puzzle, x - 1, y) ) {
169 if ( tile != 'J' && tile != '|' && tile != 'L' ) {
170 return false;
171 }
172 if ( tile == 'J' ) {
173 direction = 'W';
174 }
175 else if ( tile == 'L' ) {
176 direction = 'E';
177 }
178 }
179 else if ( direction == 'N' ) {
180 --y;
181 if ( y >= puzzle.size() ) {
182 return false;
183 }
184 auto tile = puzzle[y][x];
185 if ( tile != '7' && tile != '|' && tile != 'F' ) {
186 return false;
187 }
188 if ( tile == '7' ) {
189 direction = 'W';
190 }
191 else if ( tile == 'F' ) {
192 direction = 'E';
193 }
194 }
195 else if ( direction == 'E' ) {
196 ++x;
197 if ( x >= puzzle[y].size() ) {
198 return false;
199 }
200 auto tile = puzzle[y][x];
201 if ( tile != 'J' && tile != '-' && tile != '7' ) {
202 return false;
203 }
204 if ( tile == 'J' ) {
205 direction = 'N';
206 }
207 else if ( tile == '7' ) {
208 direction = 'S';
209 }
210 }
211 else if ( direction == 'W' ) {
212 --x;
213 if ( x >= puzzle[y].size() ) {
214 return false;
215 }
216 auto tile = puzzle[y][x];
217 if ( tile != 'L' && tile != '-' && tile != 'F' ) {
218 return false;
219 }
220 if ( tile == 'L' ) {
221 direction = 'N';
222 }
223 else if ( tile == 'F' ) {
224 direction = 'S';
225 }
226 }
227 else {
228 cerr << "invalid direction " << direction << ")!" << endl;
229 return false; 158 return false;
230 } 159 }
160 }
161
162 return true;
163};
231 164
232 current = { x, y }; 165void
233 return true; 166part2()
234 }; 167{
168 const auto puzzle_original = read_file("data/day10.txt");
235 169
236 vector<string> puzzle_copy(puzzle.size(), string(puzzle[0].size(), ' ')); 170 puzzle_t puzzle{ puzzle_original.size(), string(puzzle_original[0].size(), ' ') };
237 171
238 const auto start_pos = find_start_pos(); 172 const auto start_pos = find_start_pos(puzzle_original);
239 173
240 for ( const auto direction: { 'N', 'S', 'E', 'W' } ) { 174 for ( const auto direction: { 'N', 'S', 'E', 'W' } ) {
241 auto current_direction = direction; 175 auto current_direction = direction;
@@ -245,49 +179,28 @@ part2()
245 auto x = get<0>(current_pos); // NOLINT 179 auto x = get<0>(current_pos); // NOLINT
246 auto y = get<1>(current_pos); // NOLINT 180 auto y = get<1>(current_pos); // NOLINT
247 181
248 puzzle_copy[y][x] = puzzle[y][x]; 182 puzzle[y][x] = puzzle_original[y][x];
249 183
250 if ( !predict_direction(current_pos, current_direction) ) { 184 if ( !predict_direction(puzzle_original, current_pos, current_direction) ) {
251 break; 185 break;
252 } 186 }
253 } 187 }
254 } 188 }
255 189
256 function<bool(vector<string>&, pos_t)> flood_fill = [&](vector<string>& puzzle, pos_t position) -> bool { 190 for ( size_t y = 0; y != puzzle.size(); ++y ) { // NOLINT
257 auto x = get<0>(position); // NOLINT 191 for ( size_t x = 0; x != puzzle[y].size(); ++x ) { // NOLINT
258 auto y = get<1>(position); // NOLINT 192 auto test_puzzle{ puzzle };
259
260 if ( y >= puzzle.size() || x >= puzzle[0].size() ) {
261 return false;
262 }
263
264 if ( puzzle[y][x] == ' ' ) {
265 puzzle[y][x] = 'o';
266 if ( !flood_fill(puzzle, { x, y + 1 }) ||
267 !flood_fill(puzzle, { x, y - 1 }) ||
268 !flood_fill(puzzle, { x + 1, y }) ||
269 !flood_fill(puzzle, { x - 1, y }) ) {
270 return false;
271 }
272 }
273
274 return true;
275 };
276
277 for ( size_t y = 0; y != puzzle_copy.size(); ++y ) {
278 for ( size_t x = 0; x != puzzle_copy[y].size(); ++x ) {
279 auto test_puzzle = puzzle_copy;
280 193
281 if ( flood_fill(test_puzzle, { x, y }) ) { 194 if ( flood_fill(test_puzzle, x, y) ) {
282 puzzle_copy = test_puzzle; 195 puzzle = test_puzzle;
283 } 196 }
284 } 197 }
285 } 198 }
286 199
287 int sum = 0; 200 auto sum = 0;
288 for ( auto& line: puzzle_copy ) { 201 for ( auto& line: puzzle ) {
289 auto pipes = 0U; 202 auto pipes = 0U;
290 for ( char chr: line ) { 203 for ( auto chr: line ) {
291 if ( chr == '|' || chr == 'L' || chr == 'J' ) { 204 if ( chr == '|' || chr == 'L' || chr == 'J' ) {
292 ++pipes; 205 ++pipes;
293 } 206 }
@@ -296,6 +209,7 @@ part2()
296 } 209 }
297 } 210 }
298 } 211 }
212
299 cout << sum << endl; 213 cout << sum << endl;
300} 214}
301 215