Skip to content

Commit b3b2eef

Browse files
committed
2024.15 - Part 2 WIP
1 parent 27f33f1 commit b3b2eef

File tree

3 files changed

+172
-19
lines changed

3 files changed

+172
-19
lines changed

.vscode/launch.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
8+
{
9+
"name": "Launch Package",
10+
"type": "go",
11+
"request": "launch",
12+
"mode": "auto",
13+
"program": "${fileDirname}",
14+
"args": [
15+
"example.txt"
16+
]
17+
}
18+
]
19+
}

2024/15-warehouse/example2.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#########
2+
#....##.#
3+
#.......#
4+
#.@OO...#
5+
#.......#
6+
#...O...#
7+
#.......#
8+
#########
9+
10+
>>vvvv>>^^^^

2024/15-warehouse/main.go

Lines changed: 143 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@ package main
33
import (
44
"advent-of-code/util"
55
"bufio"
6-
"bytes"
76
"fmt"
87
)
98

109
const (
11-
boundry = '#'
12-
box = 'O'
13-
empty = '.'
14-
up = '^'
15-
right = '>'
16-
down = 'v'
17-
left = '<'
10+
boundry = '#'
11+
box = 'O'
12+
boxLeft = '['
13+
boxRight = ']'
14+
empty = '.'
15+
16+
up = '^'
17+
right = '>'
18+
down = 'v'
19+
left = '<'
1820
)
1921

2022
var moves = map[byte]position{
@@ -24,51 +26,77 @@ var moves = map[byte]position{
2426
left: {-1, 0},
2527
}
2628

27-
var grid [][]byte
28-
var robot position
29+
var grid, grid2 [][]byte
30+
var robot, robot2 position
2931

3032
func main() {
3133
file := util.FileFromArgs()
3234
scan := bufio.NewScanner(file)
3335

3436
// Read grid
35-
var x int
3637
for scan.Scan() {
3738
row := scan.Bytes()
3839
if len(row) == 0 {
3940
break
4041
}
4142

42-
x = bytes.IndexRune(row, '@')
43-
if x > -1 {
44-
robot.X = x
45-
robot.Y = len(grid)
46-
}
47-
48-
// Prevent scanner memory override
43+
// Part 1: Prevent scanner memory override
4944
gridRow := make([]byte, len(row))
5045
copy(gridRow, row)
5146
grid = append(grid, gridRow)
47+
48+
// Part 2
49+
gridRow = make([]byte, 0, len(row)*2)
50+
for x, b := range row {
51+
switch b {
52+
case '@':
53+
robot.X = x
54+
robot.Y = len(grid) - 1
55+
robot2.X = 2 * x
56+
robot2.Y = len(grid2)
57+
gridRow = append(gridRow, '@', empty)
58+
case boundry:
59+
gridRow = append(gridRow, boundry, boundry)
60+
case box:
61+
gridRow = append(gridRow, boxLeft, boxRight)
62+
case empty:
63+
gridRow = append(gridRow, empty, empty)
64+
}
65+
}
66+
grid2 = append(grid2, gridRow)
5267
}
5368

69+
util.PrintMatrix(grid2)
70+
5471
// Move stuf arround
5572
for scan.Scan() {
5673
for _, b := range scan.Bytes() {
5774
moveObject(robot.X, robot.Y, b, true)
75+
moveObject2(robot2.X, robot2.Y, b, true)
76+
77+
// util.PrintMatrix(grid2)
5878
}
5979
}
6080

6181
// Find boxes in our grid
62-
var result int
82+
var result, result2 int
6383
for y := range grid {
6484
for x := range grid[y] {
6585
if grid[y][x] == box {
6686
result += 100*y + x
6787
}
6888
}
6989
}
90+
for y := range grid2 {
91+
for x := range grid2[y] {
92+
if grid2[y][x] == boxLeft {
93+
result2 += 100*y + x
94+
}
95+
}
96+
}
7097

7198
fmt.Println(result)
99+
fmt.Println(result2)
72100
}
73101

74102
type position struct {
@@ -98,3 +126,99 @@ func moveObject(x, y int, direction byte, isRobot bool) bool {
98126

99127
return true
100128
}
129+
130+
func moveObject2(x, y int, direction byte, isRobot bool) bool {
131+
dx := x + moves[direction].X
132+
dy := y + moves[direction].Y
133+
134+
if grid2[dy][dx] == boundry {
135+
return false
136+
}
137+
138+
// Always start from the left box part
139+
bx := dx
140+
if grid2[dy][dx] == boxRight {
141+
bx -= 1
142+
}
143+
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 {
170+
return false
171+
}
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 {
178+
return false
179+
}
180+
}
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
190+
}
191+
192+
return true
193+
}
194+
195+
func can2BoxesMove(x, y int, direction byte) bool {
196+
if direction == down {
197+
y += 2
198+
} else {
199+
y -= 2
200+
}
201+
202+
if y < 0 || y > len(grid)-1 || x > len(grid2[y])-4 {
203+
return true
204+
}
205+
206+
// Obstacles in the way?
207+
for i := 0; i < 4; i++ {
208+
if grid2[y][x+i] == boundry {
209+
return false
210+
}
211+
212+
}
213+
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+
}
220+
}
221+
}
222+
223+
return true
224+
}

0 commit comments

Comments
 (0)