aboutsummaryrefslogtreecommitdiff
path: root/src/day16.cpp
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2023-12-16 15:07:56 +0100
committerThomas Schmucker <ts@its1.de>2023-12-16 15:07:56 +0100
commit154fdf1541545d3a5fe94c564941f8092937a504 (patch)
treef98d52d269c40b6e70ef7c27d28708ffa6dbb9ca /src/day16.cpp
parentc57f177c098c64775eba19ae43bf1cb381968784 (diff)
downloadadvent-of-code-154fdf1541545d3a5fe94c564941f8092937a504.tar.gz
advent-of-code-154fdf1541545d3a5fe94c564941f8092937a504.tar.bz2
advent-of-code-154fdf1541545d3a5fe94c564941f8092937a504.zip
Lösungen für Tag 16
Diffstat (limited to 'src/day16.cpp')
-rw-r--r--src/day16.cpp139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/day16.cpp b/src/day16.cpp
new file mode 100644
index 0000000..68defad
--- /dev/null
+++ b/src/day16.cpp
@@ -0,0 +1,139 @@
1#include <array>
2#include <chrono>
3#include <fstream>
4#include <iostream>
5#include <map>
6#include <queue>
7#include <set>
8#include <string>
9#include <vector>
10using namespace std;
11
12vector<string>
13read_file(string_view filename)
14{
15 fstream input{ filename };
16 vector<string> data;
17
18 for ( string line; getline(input, line); ) {
19 data.emplace_back(line);
20 }
21
22 return data;
23}
24
25const unsigned DIR_UP = 0;
26const unsigned DIR_RIGHT = 1;
27const unsigned DIR_DOWN = 2;
28const unsigned DIR_LEFT = 3;
29
30size_t
31solve(const vector<string>& lines, tuple<size_t, size_t, unsigned int> start)
32{
33 static const array<tuple<size_t, size_t>, 4> movement{
34 make_tuple(0, -1),
35 make_tuple(1, 0),
36 make_tuple(0, 1),
37 make_tuple(-1, 0),
38 };
39
40 map<tuple<size_t, size_t, unsigned int>, bool> visited;
41
42 queue<tuple<size_t, size_t, unsigned int>> positions;
43
44 positions.emplace(start);
45
46 while ( !positions.empty() ) {
47 auto row = get<0>(positions.front());
48 auto col = get<1>(positions.front());
49 auto dir = get<2>(positions.front());
50 positions.pop();
51
52 while ( true ) {
53 col += get<0>(movement[dir]); // NOLINT
54 row += get<1>(movement[dir]); // NOLINT
55
56 if ( row >= lines.size() || col >= lines[0].size() ) {
57 break;
58 }
59
60 if ( visited[{ row, col, dir }] ) {
61 break;
62 }
63
64 visited[{ row, col, dir }] = true;
65
66 const auto chr = lines[row][col];
67
68 if ( chr == '|' && (dir == DIR_LEFT || dir == DIR_RIGHT) ) {
69 dir = (dir + 1) % 4;
70 positions.emplace(row, col, (dir + 2) % 4);
71 }
72 else if ( chr == '-' && (dir == DIR_UP || dir == DIR_DOWN) ) {
73 dir = (dir + 1) % 4;
74 positions.emplace(row, col, (dir + 2) % 4);
75 }
76 else if ( chr == '/' && (dir == DIR_LEFT || dir == DIR_RIGHT) ) {
77 dir = (dir + 3) % 4;
78 }
79 else if ( chr == '/' && (dir == DIR_UP || dir == DIR_DOWN) ) {
80 dir = (dir + 1) % 4;
81 }
82 else if ( chr == '\\' && (dir == DIR_LEFT || dir == DIR_RIGHT) ) {
83 dir = (dir + 1) % 4;
84 }
85 else if ( chr == '\\' && (dir == DIR_UP || dir == DIR_DOWN) ) {
86 dir = (dir + 3) % 4;
87 }
88 }
89 }
90
91 set<tuple<size_t, size_t>> foo;
92 for (const auto& bar: visited) {
93 foo.emplace(get<0>(bar.first), get<1>(bar.first));
94 }
95 return foo.size();
96}
97
98void
99part1(const vector<string>& lines)
100{
101 auto start = chrono::steady_clock::now();
102
103 auto sum = solve(lines, { 0, -1, DIR_RIGHT });
104
105 auto duration = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count();
106
107 cout << sum << " (" << duration << "ms)" << endl;
108}
109
110void
111part2(const vector<string>& lines)
112{
113 const auto rows = lines.size();
114 const auto cols = lines[0].size();
115
116 auto start = chrono::steady_clock::now();
117
118 size_t sum = 0;
119 for ( size_t row = 0; row != rows; ++row ) {
120 sum = max(sum, solve(lines, { row, -1, DIR_RIGHT }));
121 sum = max(sum, solve(lines, { row, cols, DIR_LEFT }));
122 }
123 for ( size_t col = 0; col != cols; ++col ) {
124 sum = max(sum, solve(lines, { -1, col, DIR_DOWN }));
125 sum = max(sum, solve(lines, { rows, col, DIR_UP }));
126 }
127
128 auto duration = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count();
129
130 cout << sum << " (" << duration << "ms)" << endl;
131}
132
133int
134main()
135{
136 const auto lines = read_file("data/day16.txt");
137 part1(lines);
138 part2(lines);
139}