@@ -72,7 +72,7 @@ func main() {
72
72
for scan .Scan () {
73
73
for _ , b := range scan .Bytes () {
74
74
moveObject (robot .X , robot .Y , b , true )
75
- moveObject2 (robot2 .X , robot2 .Y , b , true )
75
+ moveRobot2 (robot2 .X , robot2 .Y , b )
76
76
77
77
// util.PrintMatrix(grid2)
78
78
}
@@ -127,98 +127,97 @@ func moveObject(x, y int, direction byte, isRobot bool) bool {
127
127
return true
128
128
}
129
129
130
- func moveObject2 (x , y int , direction byte , isRobot bool ) bool {
130
+ func moveRobot2 (x , y int , direction byte ) {
131
131
dx := x + moves [direction ].X
132
132
dy := y + moves [direction ].Y
133
133
134
134
if grid2 [dy ][dx ] == boundry {
135
- return false
135
+ return
136
136
}
137
137
138
138
// Always start from the left box part
139
- bx := dx
140
- if grid2 [dy ][dx ] == boxRight {
141
- bx -= 1
139
+ if grid2 [dy ][dx ] == boxRight || grid2 [dy ][dx ] == boxLeft {
140
+ if ! canBoxMove (dx , dy , direction ) {
141
+ return
142
+ }
143
+
144
+ moveBox (dx , dy , direction )
142
145
}
143
146
144
- if grid2 [dy ][bx ] == boxLeft {
145
- switch direction {
146
- case up :
147
- if (grid2 [dy - 1 ][bx ] == empty && grid2 [dy - 1 ][bx + 1 ] == empty ) || (grid2 [dy - 1 ][bx ] == boxRight && grid2 [dy - 1 ][bx + 1 ] == boxLeft && can2BoxesMove (bx - 1 , y - 1 , direction ) && moveObject2 (bx , dy , direction , false ) && moveObject2 (bx + 1 , dy , direction , false )) || (grid2 [dy - 1 ][bx ] == boxRight && grid2 [dy - 1 ][bx + 1 ] == empty && moveObject2 (bx , dy , direction , false )) || (grid2 [dy - 1 ][bx + 1 ] == left && grid2 [dy - 1 ][bx ] == empty && moveObject2 (bx , dy , direction , false )) {
148
- grid2 [dy ][bx ] = empty
149
- grid2 [dy ][bx + 1 ] = empty
150
- grid2 [dy - 1 ][bx ] = boxLeft
151
- grid2 [dy - 1 ][bx + 1 ] = boxRight
152
- } else {
153
- return false
154
- }
155
- case right :
156
- if grid2 [dy ][bx + 2 ] == empty || (grid2 [dy ][bx + 2 ] == boxLeft && moveObject2 (bx + 1 , dy , direction , false )) {
157
- grid2 [dy ][bx ] = empty
158
- grid2 [dy ][bx + 1 ] = boxLeft
159
- grid2 [dy ][bx + 2 ] = boxRight
160
- } else {
161
- return false
162
- }
163
- case down :
164
- if (grid2 [dy + 1 ][bx ] == empty && grid2 [dy + 1 ][bx + 1 ] == empty ) || (grid2 [dy + 1 ][bx ] == boxLeft && moveObject2 (bx , dy , direction , false )) || (grid2 [dy + 1 ][bx ] == boxRight && grid2 [dy + 1 ][bx + 1 ] == boxLeft && can2BoxesMove (bx - 2 , dy + 1 , direction ) && moveObject2 (bx , dy , direction , false ) && moveObject2 (bx + 1 , dy , direction , false )) || (grid2 [dy + 1 ][bx ] == boxRight && moveObject2 (bx , dy , direction , false ) && grid2 [dy + 1 ][bx + 1 ] == empty ) {
165
- grid2 [dy ][bx ] = empty
166
- grid2 [dy ][bx + 1 ] = empty
167
- grid2 [dy + 1 ][bx ] = boxLeft
168
- grid2 [dy + 1 ][bx + 1 ] = boxRight
169
- } else {
147
+ grid2 [y ][x ] = empty
148
+ robot2 .X = dx
149
+ robot2 .Y = dy
150
+ grid2 [dy ][dx ] = '@'
151
+ }
152
+
153
+ func canBoxMove (x , y int , direction byte ) bool {
154
+ // Always asume the left of the box
155
+ if grid2 [y ][x ] == boxRight {
156
+ x --
157
+ }
158
+
159
+ dx := x + moves [direction ].X
160
+ dy := y + moves [direction ].Y
161
+
162
+ if grid2 [dy ][dx ] == boundry {
163
+ return false
164
+ }
165
+
166
+ if direction == up || direction == down {
167
+ if grid2 [dy ][dx + 1 ] == boundry {
168
+ return false
169
+ }
170
+ if grid2 [dy ][dx ] == boxLeft || grid2 [dy ][dx ] == boxRight {
171
+ if ! canBoxMove (dx , dy , direction ) {
170
172
return false
171
173
}
172
- case left :
173
- if grid2 [dy ][bx - 1 ] == empty || (grid2 [dy ][bx - 1 ] == boxRight && moveObject2 (bx - 1 , dy , direction , false )) {
174
- grid2 [dy ][bx + 1 ] = empty
175
- grid2 [dy ][bx ] = boxRight
176
- grid2 [dy ][bx - 1 ] = boxLeft
177
- } else {
174
+ }
175
+ if grid2 [dy ][dx + 1 ] == boxLeft {
176
+ if ! canBoxMove (dx + 1 , dy , direction ) {
178
177
return false
179
178
}
180
179
}
181
- }
182
-
183
- // All is well, move the object
184
- if isRobot {
185
- grid2 [dy ][dx ] = grid2 [y ][x ]
186
- grid2 [y ][x ] = empty
187
-
188
- robot2 .X = dx
189
- robot2 .Y = dy
180
+ } else if direction == left {
181
+ if grid2 [dy ][dx ] == boxRight {
182
+ return canBoxMove (dx - 1 , dy , direction )
183
+ }
184
+ } else {
185
+ if grid2 [dy ][dx + 1 ] == boundry {
186
+ return false
187
+ }
188
+ if grid2 [dy ][dx + 1 ] == boxLeft {
189
+ return canBoxMove (dx + 1 , dy , direction )
190
+ }
190
191
}
191
192
192
193
return true
193
194
}
194
195
195
- func can2BoxesMove (x , y int , direction byte ) bool {
196
- if direction == down {
197
- y += 2
198
- } else {
199
- y -= 2
196
+ func moveBox (x , y int , direction byte ) {
197
+ // Always asume the left of the box
198
+ if grid2 [y ][x ] == boxRight {
199
+ x --
200
200
}
201
201
202
- if y < 0 || y > len (grid )- 1 || x > len (grid2 [y ])- 4 {
203
- return true
204
- }
202
+ dx := x + moves [direction ].X
203
+ dy := y + moves [direction ].Y
205
204
206
- // Obstacles in the way?
207
- for i := 0 ; i < 4 ; i ++ {
208
- if grid2 [y ][x + i ] == boundry {
209
- return false
205
+ if direction == right {
206
+ if grid2 [dy ][dx + 1 ] == boxLeft {
207
+ moveBox (dx + 1 , dy , direction )
210
208
}
211
-
209
+ } else if grid2 [dy ][dx ] == boxLeft || grid2 [dy ][dx ] == boxRight {
210
+ moveBox (dx , dy , direction )
212
211
}
213
212
214
- // One+ box blocking?
215
- if x > len (grid2 [y ])- 5 {
216
- for i := - 1 ; i < 5 ; i ++ {
217
- if grid [y ][x + i ] == boxLeft && grid [y ][x + i + 1 ] == boxRight && ! moveObject2 (x + i , y , direction , false ) {
218
- return false
219
- }
213
+ if direction == up || direction == down {
214
+ if grid2 [dy ][dx + 1 ] == boxLeft || grid2 [dy ][dx + 1 ] == boxRight {
215
+ moveBox (dx + 1 , dy , direction )
220
216
}
221
217
}
222
218
223
- return true
219
+ grid2 [y ][x ] = empty
220
+ grid2 [y ][x + 1 ] = empty
221
+ grid2 [dy ][dx ] = boxLeft
222
+ grid2 [dy ][dx + 1 ] = boxRight
224
223
}
0 commit comments