aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2023-12-10 13:55:47 +0100
committerThomas Schmucker <ts@its1.de>2023-12-10 13:55:47 +0100
commit28819cfd9284f820e528c61855639134a0f06343 (patch)
treefdf2e2de72a26f2341ce0d09679f083f37911d86
parent1165d51cc10b5795e1ec78f3eb5c9b56bfb31d18 (diff)
downloadadvent-of-code-28819cfd9284f820e528c61855639134a0f06343.tar.gz
advent-of-code-28819cfd9284f820e528c61855639134a0f06343.tar.bz2
advent-of-code-28819cfd9284f820e528c61855639134a0f06343.zip
Lösung für Tag 10, Teil 2
-rw-r--r--src/day10.cpp163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/day10.cpp b/src/day10.cpp
index b9d6355..6b0b28e 100644
--- a/src/day10.cpp
+++ b/src/day10.cpp
@@ -1,3 +1,4 @@
1#include <algorithm>
1#include <fstream> 2#include <fstream>
2#include <iostream> 3#include <iostream>
3#include <sstream> 4#include <sstream>
@@ -137,8 +138,170 @@ part1()
137 cout << max_steps / 2 << endl; 138 cout << max_steps / 2 << endl;
138} 139}
139 140
141void
142part2()
143{
144 typedef tuple<size_t, size_t> pos_t;
145
146 const auto puzzle = read_file("data/day10.txt");
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
163 if ( direction == 'S' ) {
164 ++y;
165 if ( y >= puzzle.size() ) {
166 return false;
167 }
168 auto tile = puzzle[y][x];
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;
230 }
231
232 current = { x, y };
233 return true;
234 };
235
236 vector<string> puzzle_copy(puzzle.size(), string(puzzle[0].size(), ' '));
237
238 const auto start_pos = find_start_pos();
239
240 for ( const auto direction: { 'N', 'S', 'E', 'W' } ) {
241 auto current_direction = direction;
242 auto current_pos = start_pos;
243
244 for ( ;; ) {
245 auto x = get<0>(current_pos); // NOLINT
246 auto y = get<1>(current_pos); // NOLINT
247
248 puzzle_copy[y][x] = puzzle[y][x];
249
250 if ( !predict_direction(current_pos, current_direction) ) {
251 break;
252 }
253 }
254 }
255
256 function<bool(vector<string>&, pos_t)> flood_fill = [&](vector<string>& puzzle, pos_t position) -> bool {
257 auto x = get<0>(position); // NOLINT
258 auto y = get<1>(position); // NOLINT
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
281 if ( flood_fill(test_puzzle, { x, y }) ) {
282 puzzle_copy = test_puzzle;
283 }
284 }
285 }
286
287 int sum = 0;
288 for ( auto& line: puzzle_copy ) {
289 auto pipes = 0U;
290 for ( char chr: line ) {
291 if ( chr == '|' || chr == 'L' || chr == 'J' ) {
292 ++pipes;
293 }
294 if ( chr == 'o' && (pipes & 1U) == 1U ) {
295 ++sum;
296 }
297 }
298 }
299 cout << sum << endl;
300}
301
140int 302int
141main() 303main()
142{ 304{
143 part1(); 305 part1();
306 part2();
144} 307}