aboutsummaryrefslogtreecommitdiff
path: root/2024
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-12-06 07:20:50 +0100
committerSebastiano Tronto <sebastiano@tronto.net>2024-12-06 07:20:50 +0100
commitc2b969794f3e981d46852d7070cc64802be99e0d (patch)
treee742c789a282e679757ded8ccbd778ff7e627959 /2024
parenta937350ab20adc0f8172c4d99f4d711e92dfd947 (diff)
downloadaoc-c2b969794f3e981d46852d7070cc64802be99e0d.tar.gz
aoc-c2b969794f3e981d46852d7070cc64802be99e0d.zip
Day 6 2024
Diffstat (limited to '2024')
-rw-r--r--2024/06/Makefile24
-rwxr-xr-x2024/06/b.outbin0 -> 173576 bytes
-rw-r--r--2024/06/day06a.cpp152
-rw-r--r--2024/06/day06b.cpp216
4 files changed, 392 insertions, 0 deletions
diff --git a/2024/06/Makefile b/2024/06/Makefile
new file mode 100644
index 0000000..8a6eea2
--- /dev/null
+++ b/2024/06/Makefile
@@ -0,0 +1,24 @@
1CC=g++ -std=c++20 -g -Wall
2
3a:
4 ${CC} -o a.out day06a.cpp
5
6b:
7 ${CC} -o b.out day06b.cpp
8
9clean:
10 rm -f a b
11
12atest: a
13 ./a.out
14
15btest: b
16 ./b.out
17
18arun: a
19 ./a.out < input
20
21brun: b
22 ./b.out < input
23
24.PHONY: a b clean atest btest arun brun
diff --git a/2024/06/b.out b/2024/06/b.out
new file mode 100755
index 0000000..1455953
--- /dev/null
+++ b/2024/06/b.out
Binary files differ
diff --git a/2024/06/day06a.cpp b/2024/06/day06a.cpp
new file mode 100644
index 0000000..69b9340
--- /dev/null
+++ b/2024/06/day06a.cpp
@@ -0,0 +1,152 @@
1#include <iostream>
2#include <algorithm>
3#include <string>
4#include <string_view>
5#include <vector>
6using namespace std;
7
8enum class Direction { U, D, R, L };
9Direction all_directions[] = {
10 Direction::U, Direction::D, Direction::R, Direction::L,
11};
12
13pair<int, int> step(pair<int, int> p, Direction d) {
14 auto [i, j] = p;
15
16 switch (d) {
17 case Direction::U:
18 return make_pair(i-1, j);
19 case Direction::D:
20 return make_pair(i+1, j);
21 case Direction::R:
22 return make_pair(i, j+1);
23 case Direction::L:
24 return make_pair(i, j-1);
25 }
26
27 return make_pair(-999,-999);
28}
29
30Direction turn(Direction d) {
31 switch (d) {
32 case Direction::U:
33 return Direction::R;
34 case Direction::D:
35 return Direction::L;
36 case Direction::R:
37 return Direction::D;
38 case Direction::L:
39 return Direction::U;
40 }
41
42 return Direction::U;
43}
44
45class Board {
46public:
47 const char out_of_bound = '$';
48 int M, N;
49
50 Board(vector<string> &lines) {
51 N = lines.size();
52 M = 0;
53 for (string l : lines)
54 M = max(M, (int)l.size());
55 cells = new char[M * N];
56 for (int i = 0; i < N; i++)
57 for (int j = 0; j < M; j++)
58 cells[N*i + j] = j < (int)lines[i].size() ?
59 lines[i][j] : out_of_bound;
60 }
61
62 ~Board() {
63 delete []cells;
64 }
65
66 char operator[](pair<int, int> p) {
67 int c = coord(p);
68 return c == -1 ? out_of_bound : cells[c];
69 }
70
71 bool is_obstruction(pair<int, int> p) {
72 return (*this)[p] == '#';
73 }
74
75 bool is_visited(pair<int, int> p) {
76 return (*this)[p] == 'x';
77 }
78
79 void set_visited(pair<int, int> p) {
80 int c = coord(p);
81 cells[c] = 'x';
82 }
83
84private:
85 char *cells;
86
87 int coord(pair<int, int> p) {
88 auto [i, j] = p;
89 return i >= N || i < 0 || j >= M || j < 0 ? -1 : N*i + j;
90 }
91};
92
93Direction guard_direction(char c) {
94 switch (c) {
95 case '^':
96 return Direction::U;
97 case 'v':
98 return Direction::D;
99 case '>':
100 return Direction::R;
101 case '<':
102 return Direction::L;
103 }
104
105 return Direction::U;
106}
107
108pair<pair<int, int>, Direction> find_guard(Board &board) {
109 pair<int, int> p(0, 0);
110 for (p.first = 0; p.first < board.N; p.first++) {
111 for (p.second = 0; p.second < board.M; p.second++) {
112 if (board[p] != '.' && board[p] != '#') {
113 Direction d = guard_direction(board[p]);
114 return make_pair(p, d);
115 }
116 }
117 }
118
119 return make_pair(make_pair(-999, -999), Direction::U);
120}
121
122int main() {
123 string line;
124 vector<string> lines;
125 while (getline(cin, line))
126 lines.push_back(line);
127
128 Board board(lines);
129
130 int tot = 1;
131 auto [p, d] = find_guard(board);
132 board.set_visited(p);
133
134 while (true) {
135 auto q = step(p, d);
136 if (board[q] == board.out_of_bound)
137 break;
138 if (board.is_obstruction(q)) {
139 d = turn(d);
140 } else {
141 p = q;
142 if (!board.is_visited(p)) {
143 board.set_visited(p);
144 tot++;
145 }
146 }
147 }
148
149 cout << tot << endl;
150
151 return 0;
152}
diff --git a/2024/06/day06b.cpp b/2024/06/day06b.cpp
new file mode 100644
index 0000000..2498536
--- /dev/null
+++ b/2024/06/day06b.cpp
@@ -0,0 +1,216 @@
1/*
2This is quite inefficient, but it still gives the right answer in less
3than a minute (25 seconds on my old laptop).
4*/
5
6#include <iostream>
7#include <algorithm>
8#include <string>
9#include <string_view>
10#include <vector>
11using namespace std;
12
13enum Direction { U = 0, D, R, L };
14Direction all_directions[] = {
15 Direction::U, Direction::D, Direction::R, Direction::L,
16};
17
18pair<int, int> step(pair<int, int> p, Direction d) {
19 auto [i, j] = p;
20
21 switch (d) {
22 case Direction::U:
23 return make_pair(i-1, j);
24 case Direction::D:
25 return make_pair(i+1, j);
26 case Direction::R:
27 return make_pair(i, j+1);
28 case Direction::L:
29 return make_pair(i, j-1);
30 }
31
32 return make_pair(-999,-999);
33}
34
35Direction turn(Direction d) {
36 switch (d) {
37 case Direction::U:
38 return Direction::R;
39 case Direction::D:
40 return Direction::L;
41 case Direction::R:
42 return Direction::D;
43 case Direction::L:
44 return Direction::U;
45 }
46
47 return Direction::U;
48}
49
50class Board {
51public:
52 const char out_of_bound = '$';
53 int M, N;
54
55 Board(vector<string> &lines) {
56 N = lines.size();
57 M = 0;
58 for (string l : lines)
59 M = max(M, (int)l.size());
60
61 cells = new char[M * N];
62 visited = new int[M * N];
63 for (int i = 0; i < N; i++) {
64 for (int j = 0; j < M; j++) {
65 cells[N*i + j] = j < (int)lines[i].size() ?
66 lines[i][j] : out_of_bound;
67 visited[N*i + j] = 0;
68 }
69 }
70 }
71
72 ~Board() {
73 delete []cells;
74 delete []visited;
75 }
76
77 char operator[](pair<int, int> p) {
78 int c = coord(p);
79 return c == -1 ? out_of_bound : cells[c];
80 }
81
82 bool is_visited(pair<int, int> p, Direction d) {
83 return get_vmask(p) & (1 << d);
84 }
85
86 void set_visited(pair<int, int> p, Direction d) {
87 toggle_vmask(p, d);
88 }
89
90 void clear_visited() {
91 for (int i = 0; i < N; i++)
92 for (int j = 0; j < M; j++)
93 set_vmask(make_pair(i, j), 0);
94 }
95
96 bool is_obstruction(pair<int, int> p) {
97 return (*this)[p] == '#';
98 }
99
100 void set_obstruction(pair<int, int> p) {
101 set_cell(p, '#');
102 }
103
104 void set_clean(pair<int, int> p) {
105 set_cell(p, '.');
106 }
107
108private:
109 char *cells;
110 int *visited;
111
112 int coord(pair<int, int> p) {
113 auto [i, j] = p;
114 return i >= N || i < 0 || j >= M || j < 0 ? -1 : N*i + j;
115 }
116
117 void set_cell(pair<int, int> p, char c) {
118 int i = coord(p);
119 cells[i] = c;
120 }
121
122 int get_vmask(pair<int, int> p) {
123 int i = coord(p);
124 return visited[i];
125 }
126
127 void set_vmask(pair<int, int> p, int x) {
128 int i = coord(p);
129 visited[i] = x;
130 }
131
132 void toggle_vmask(pair<int, int> p, Direction d) {
133 int i = coord(p);
134 visited[i] ^= 1 << d;
135 }
136};
137
138Direction guard_direction(char c) {
139 switch (c) {
140 case '^':
141 return Direction::U;
142 case 'v':
143 return Direction::D;
144 case '>':
145 return Direction::R;
146 case '<':
147 return Direction::L;
148 }
149
150 return Direction::U;
151}
152
153pair<pair<int, int>, Direction> find_guard(Board &board) {
154 pair<int, int> p(0, 0);
155 for (p.first = 0; p.first < board.N; p.first++) {
156 for (p.second = 0; p.second < board.M; p.second++) {
157 if (board[p] != '.' && board[p] != '#') {
158 Direction d = guard_direction(board[p]);
159 return make_pair(p, d);
160 }
161 }
162 }
163
164 return make_pair(make_pair(-999, -999), Direction::U);
165}
166
167bool isloop(pair<int, int> i, pair<int, int> p, Direction d, Board &board) {
168 bool ret = false;
169
170 board.set_obstruction(i);
171
172 while (true) {
173 auto q = step(p, d);
174 if (board.is_visited(p, d)) {
175 ret = true;
176 break;
177 }
178 board.set_visited(p, d);
179
180 if (board[q] == board.out_of_bound)
181 break;
182
183 if (board.is_obstruction(q)) {
184 d = turn(d);
185 } else {
186 p = q;
187 }
188 }
189
190 board.clear_visited();
191 board.set_clean(i);
192
193 return ret;
194}
195
196int main() {
197 string line;
198 vector<string> lines;
199 while (getline(cin, line))
200 lines.push_back(line);
201
202 Board board(lines);
203
204 int tot = 0;
205 auto [p, d] = find_guard(board);
206
207 pair i(0, 0);
208 for (i.first = 0; i.first < board.N; i.first++)
209 for (i.second = 0; i.second < board.M; i.second++)
210 if (board[i] == '.')
211 tot += isloop(i, p, d, board);
212
213 cout << tot << endl;
214
215 return 0;
216}

Generated with cgit - Back to sebastiano.tronto.net