aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--2024/15/Makefile24
-rw-r--r--2024/15/day15a.cpp141
-rw-r--r--2024/15/day15b.cpp202
3 files changed, 367 insertions, 0 deletions
diff --git a/2024/15/Makefile b/2024/15/Makefile
new file mode 100644
index 0000000..53172b6
--- /dev/null
+++ b/2024/15/Makefile
@@ -0,0 +1,24 @@
1CC=g++ -std=c++20 -g -Wall
2
3a:
4 ${CC} -o a.out day15a.cpp
5
6b:
7 ${CC} -o b.out day15b.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/15/day15a.cpp b/2024/15/day15a.cpp
new file mode 100644
index 0000000..90b271a
--- /dev/null
+++ b/2024/15/day15a.cpp
@@ -0,0 +1,141 @@
1#include <iostream>
2#include <cstdint>
3#include <algorithm>
4#include <string>
5#include <string_view>
6#include <vector>
7#include <set>
8using namespace std;
9
10class Direction {
11public:
12 const int U, R;
13
14 Direction(char c) :
15 U{c == 'v' ? 1 : (c == '^' ? -1 : 0)},
16 R{c == '>' ? 1 : (c == '<' ? -1 : 0)} {}
17
18 Direction(const int i, const int j) : U{i}, R{j} {}
19
20 Direction turnright() const {
21 return turn(-1, 0);
22 }
23
24 Direction turnleft() const {
25 return turn(1, 0);
26 }
27
28 bool operator<(const Direction& d) const { // For set<Direction>
29 return this->U < d.U || (this->U == d.U && this->R < d.R);
30 }
31private:
32 Direction turn(int64_t sin, int64_t cos) const {
33 return Direction(cos * U - sin * R, sin * U + cos * R);
34 }
35};
36
37class Position {
38public:
39 int64_t i, j;
40
41 Position() : Position(0, 0) {}
42
43 Position(int64_t a, int64_t b) : i{a}, j{b} {}
44
45 Position step(const Direction d) const {
46 return Position(i+d.U, j+d.R);
47 }
48};
49
50const Direction all_directions[] = {
51 Direction(1, 0), Direction(-1, 0), Direction(0, 1), Direction(0, -1)
52};
53
54class Board {
55public:
56 int64_t N, M;
57 Position robot;
58
59 Board(const vector<string>& lines) :
60 N{static_cast<int64_t>(lines.size())},
61 M{static_cast<int64_t>(lines[0].size())},
62 cells(M*N)
63 {
64 for (int64_t i = 0; i < N; i++) {
65 for (int64_t j = 0; j < M; j++) {
66 cells[N*i+j] = lines[i][j];
67 if (lines[i][j] == '@')
68 robot = Position(i, j);
69 }
70 }
71 }
72
73 char& operator[](const Position p) {
74 if (const auto c = coord(p); c == -1)
75 return out_of_bound;
76 else
77 return cells[c];
78 }
79
80 void move_robot(const Direction d) {
81 if (move(robot, d))
82 robot = robot.step(d);
83 }
84
85 int64_t gps() {
86 int64_t tot = 0;
87 for (Position p(0, 0); p.i < N; p.i++)
88 for (p.j = 0; p.j < M; p.j++)
89 if ((*this)[p] == 'O')
90 tot += 100*p.i + p.j;
91 return tot;
92 }
93
94 void print() {
95 for (Position p(0, 0); p.i < N; p.i++) {
96 for (p.j = 0; p.j < M; p.j++)
97 cout << (*this)[p];
98 cout << endl;
99 }
100 }
101private:
102 char out_of_bound = '$';
103
104 vector<char> cells;
105
106 int64_t coord(const Position p) const {
107 auto [i, j] = p;
108 return i >= N || i < 0 || j >= M || j < 0 ? -1 : N * i + j;
109 }
110
111 bool move(Position p, Direction d) {
112 auto q = p.step(d);
113 switch ((*this)[q]) {
114 case '.':
115 (*this)[q] = (*this)[p];
116 (*this)[p] = '.';
117 return true;
118 case 'O':
119 return move(q, d) ? move(p, d) : false;
120 default:
121 return false;
122 }
123 }
124};
125
126int main() {
127 string line;
128 vector<string> lines;
129
130 for (getline(cin, line); line.size() > 0; getline(cin, line))
131 lines.push_back(line);
132 Board board(lines);
133
134 while (getline(cin, line))
135 for (const auto& c : line)
136 board.move_robot(Direction(c));
137
138 cout << board.gps() << endl;
139
140 return 0;
141}
diff --git a/2024/15/day15b.cpp b/2024/15/day15b.cpp
new file mode 100644
index 0000000..deb7473
--- /dev/null
+++ b/2024/15/day15b.cpp
@@ -0,0 +1,202 @@
1/*
2The code here is not great, but I don't feel like cleaning it up
3*/
4
5#include <iostream>
6#include <cstdint>
7#include <algorithm>
8#include <string>
9#include <string_view>
10#include <vector>
11#include <set>
12using namespace std;
13
14class Direction {
15public:
16 const int U, R;
17
18 Direction(char c) :
19 U{c == 'v' ? 1 : (c == '^' ? -1 : 0)},
20 R{c == '>' ? 1 : (c == '<' ? -1 : 0)} {}
21
22 Direction(const int i, const int j) : U{i}, R{j} {}
23
24 Direction turnright() const {
25 return turn(-1, 0);
26 }
27
28 Direction turnleft() const {
29 return turn(1, 0);
30 }
31
32 bool operator<(const Direction& d) const { // For set<Direction>
33 return this->U < d.U || (this->U == d.U && this->R < d.R);
34 }
35private:
36 Direction turn(int64_t sin, int64_t cos) const {
37 return Direction(cos * U - sin * R, sin * U + cos * R);
38 }
39};
40
41class Position {
42public:
43 int64_t i, j;
44
45 Position() : Position(0, 0) {}
46
47 Position(int64_t a, int64_t b) : i{a}, j{b} {}
48
49 Position step(const Direction d) const {
50 return Position(i+d.U, j+d.R);
51 }
52};
53
54const Direction all_directions[] = {
55 Direction(1, 0), Direction(-1, 0), Direction(0, 1), Direction(0, -1)
56};
57
58class Board {
59public:
60 int64_t N, M;
61 Position robot;
62
63 Board(const vector<string>& lines) :
64 N{static_cast<int64_t>(lines.size())},
65 M{static_cast<int64_t>(lines[0].size())},
66 cells(M*N)
67 {
68 for (int64_t i = 0; i < N; i++) {
69 for (int64_t j = 0; j < M; j++) {
70 cells[M*i+j] = lines[i][j];
71 if (lines[i][j] == '@')
72 robot = Position(i, j);
73 }
74 }
75 }
76
77 char& operator[](const Position p) {
78 if (const auto c = coord(p); c == -1)
79 return out_of_bound;
80 else
81 return cells[c];
82 }
83
84 void move_robot(const Direction d) {
85 if (move(robot, d))
86 robot = robot.step(d);
87 }
88
89 int64_t gps() {
90 int64_t tot = 0;
91 for (Position p(0, 0); p.i < N; p.i++)
92 for (p.j = 0; p.j < M; p.j++)
93 if ((*this)[p] == '[')
94 tot += 100*p.i + p.j;
95 return tot;
96 }
97
98 void print() {
99 for (Position p(0, 0); p.i < N; p.i++) {
100 for (p.j = 0; p.j < M; p.j++)
101 cout << (*this)[p];
102 cout << endl;
103 }
104 }
105private:
106 char out_of_bound = '$';
107
108 vector<char> cells;
109
110 int64_t coord(const Position p) const {
111 auto [i, j] = p;
112 return i >= N || i < 0 || j >= M || j < 0 ? -1 : M * i + j;
113 }
114
115 bool move(Position p, Direction d) {
116 return d.U == 0 ? move_h(p, d) : move_v(p, d);
117 }
118
119 bool move_h(Position p, Direction d) {
120 auto q = p.step(d);
121 switch ((*this)[q]) {
122 case '.':
123 (*this)[q] = (*this)[p];
124 (*this)[p] = '.';
125 return true;
126 case '[':
127 case ']':
128 return move(q, d) ? move(p, d) : false;
129 default:
130 return false;
131 }
132 }
133
134 bool move_v(Position p, Direction d) {
135 if (!isfree_v(p, d))
136 return false;
137
138 auto q = p.step(d);
139 if ((*this)[q] == '[') {
140 move_v(q, d);
141 move_v(q.step(Direction('>')), d);
142 }
143 if ((*this)[q] == ']') {
144 move_v(q, d);
145 move_v(q.step(Direction('<')), d);
146 }
147 (*this)[q] = (*this)[p];
148 (*this)[p] = '.';
149 return true;
150 }
151
152 bool isfree_v(Position p, Direction d) {
153 auto q = p.step(d);
154 switch ((*this)[q]) {
155 case '.':
156 return true;
157 case ']':
158 return isfree_v(q, d) &&
159 isfree_v(q.step(Direction('<')), d);
160 case '[':
161 return isfree_v(q, d) &&
162 isfree_v(q.step(Direction('>')), d);
163 default:
164 return false;
165 }
166 if ((*this)[q] == '.')
167 return true;
168 }
169};
170
171int main() {
172 string line;
173 vector<string> lines;
174
175 for (getline(cin, line); line.size() > 0; getline(cin, line)) {
176 string wideline = "";
177 for (const auto& c : line) {
178 switch (c) {
179 case 'O':
180 wideline += "[]";
181 break;
182 case '@':
183 wideline += "@.";
184 break;
185 default:
186 wideline += c;
187 wideline += c;
188 break;
189 }
190 }
191 lines.push_back(wideline);
192 }
193 Board board(lines);
194
195 while (getline(cin, line))
196 for (const auto& c : line)
197 board.move_robot(Direction(c));
198
199 cout << board.gps() << endl;
200
201 return 0;
202}

Generated with cgit - Back to sebastiano.tronto.net