@@ -14,16 +14,30 @@ struct Vec2 {
14
14
Vec2<T> operator +(const Vec2<T> &rhs) const {
15
15
return {x + rhs.x , y + rhs.y };
16
16
}
17
+
18
+ Vec2<T> operator -(const Vec2<T> &rhs) const {
19
+ return {x - rhs.x , y - rhs.y };
20
+ }
21
+
22
+ void operator +=(const Vec2<T> &rhs) {
23
+ x += rhs.x ;
24
+ y += rhs.y ;
25
+ }
26
+
27
+ void operator -=(const Vec2<T> &rhs) {
28
+ x -= rhs.x ;
29
+ y -= rhs.y ;
30
+ }
17
31
};
18
32
19
- enum class Inst : char {
33
+ enum class Dir : char {
20
34
Left = ' <' ,
21
35
Up = ' ^' ,
22
36
Right = ' >' ,
23
37
Down = ' v' ,
24
38
};
25
39
26
- std::ostream &operator <<(std::ostream &os, Inst inst) {
40
+ std::ostream &operator <<(std::ostream &os, Dir inst) {
27
41
os << char (inst);
28
42
return os;
29
43
}
@@ -53,26 +67,48 @@ struct Board {
53
67
return rows[pos.y ][pos.x ];
54
68
}
55
69
56
- void perform (Inst inst) {
70
+ bool is_box (Vec2<int > pos, bool include_end = true ) const {
71
+ char cell = (*this )[pos];
72
+ return cell == ' O' || cell == ' [' || (include_end && cell == ' ]' );
73
+ }
74
+
75
+ bool is_space (Vec2<int > pos) const {
76
+ return (*this )[pos] == ' .' ;
77
+ }
78
+
79
+ bool is_wall (Vec2<int > pos) const {
80
+ return (*this )[pos] == ' #' ;
81
+ }
82
+
83
+ void perform (Dir inst) {
57
84
Vec2<int > dir;
58
85
switch (inst) {
59
- case Inst ::Left: dir = {-1 , 0 }; break ;
60
- case Inst ::Up: dir = {0 , -1 }; break ;
61
- case Inst ::Right: dir = {1 , 0 }; break ;
62
- case Inst ::Down: dir = {0 , 1 }; break ;
86
+ case Dir ::Left: dir = {-1 , 0 }; break ;
87
+ case Dir ::Up: dir = {0 , -1 }; break ;
88
+ case Dir ::Right: dir = {1 , 0 }; break ;
89
+ case Dir ::Down: dir = {0 , 1 }; break ;
63
90
}
64
91
65
92
Vec2<int > next = robot + dir;
66
93
Vec2<int > end = next;
67
- while ((* this )[ end] == ' O ' ) {
68
- end = end + dir;
94
+ while (is_box ( end) ) {
95
+ end += dir;
69
96
}
70
97
71
- if ((*this )[end] != ' #' ) {
72
- robot = next;
73
- if ((*this )[next] == ' O' && (*this )[end] == ' .' ) {
74
- std::swap ((*this )[next], (*this )[end]);
98
+ if (!is_wall (end)) {
99
+ if (is_box (next) && is_space (end)) {
100
+ for (Vec2<int > pos = end; pos != robot; pos -= dir) {
101
+ Vec2<int > prev = pos - dir;
102
+ (*this )[pos] = (*this )[prev];
103
+
104
+ Vec2<int > offset = {1 , 0 };
105
+ switch ((*this )[pos]) {
106
+ case ' [' : std::swap ((*this )[pos + offset], (*this )[prev + offset]); break ;
107
+ case ' ]' : std::swap ((*this )[pos - offset], (*this )[prev - offset]); break ;
108
+ }
109
+ }
75
110
}
111
+ robot = next;
76
112
}
77
113
}
78
114
@@ -81,8 +117,7 @@ struct Board {
81
117
82
118
for (int y = 0 ; y < height (); y++) {
83
119
for (int x = 0 ; x < width (); x++) {
84
- char cell = (*this )[{x, y}];
85
- if (cell == ' O' || cell == ' [' ) {
120
+ if (is_box ({x, y}, /* include_end=*/ false )) {
86
121
sum += 100 * y + x;
87
122
}
88
123
}
@@ -109,7 +144,7 @@ std::ostream &operator<<(std::ostream &os, const Board &board) {
109
144
struct State {
110
145
Board board1;
111
146
Board board2;
112
- std::vector<Inst > insts;
147
+ std::vector<Dir > insts;
113
148
114
149
static State parse_from (std::istream &istream) {
115
150
State state;
@@ -147,7 +182,7 @@ struct State {
147
182
}
148
183
} else {
149
184
for (char raw_inst : line) {
150
- state.insts .push_back (Inst (raw_inst));
185
+ state.insts .push_back (Dir (raw_inst));
151
186
}
152
187
}
153
188
}
@@ -156,7 +191,7 @@ struct State {
156
191
}
157
192
158
193
void run () {
159
- for (Inst inst : insts) {
194
+ for (Dir inst : insts) {
160
195
board1.perform (inst);
161
196
board2.perform (inst);
162
197
}
@@ -179,9 +214,13 @@ int main(int argc, char *argv[]) {
179
214
180
215
std::cout << state.board1 ;
181
216
std::cout << state.board2 ;
182
- state.run ();
183
- std::cout << " Part 1: " << state.board1 .sum_box_coords () << std::endl;
184
- std::cout << " Part 2: " << state.board2 .sum_box_coords () << std::endl;
217
+ for (Dir inst : state.insts ) {
218
+ state.board2 .perform (inst);
219
+ std::cout << " After " << inst << " : " << std::endl << state.board2 ;
220
+ }
221
+ // state.run();
222
+ // std::cout << "Part 1: " << state.board1.sum_box_coords() << std::endl;
223
+ // std::cout << "Part 2: " << state.board2.sum_box_coords() << std::endl;
185
224
186
225
return 0 ;
187
226
}
0 commit comments