summaryrefslogtreecommitdiff
path: root/2024/go
diff options
context:
space:
mode:
authoromagdy <omar.professional8777@gmail.com>2024-12-15 20:46:51 +0200
committeromagdy <omar.professional8777@gmail.com>2024-12-15 20:46:51 +0200
commit4ed10852e1d03f3c932ebaec6df2094da42ff9a6 (patch)
tree3fc09995192af0fcfe4b1c7d39c106029dc62bd8 /2024/go
parent83dde11bd7d6dfe2c1d1af72e90256aeb6a70759 (diff)
downloadaoc-4ed10852e1d03f3c932ebaec6df2094da42ff9a6.tar.xz
aoc-4ed10852e1d03f3c932ebaec6df2094da42ff9a6.zip
Day 15 part 2 done.
Diffstat (limited to '2024/go')
-rw-r--r--2024/go/input/day15_3.test9
-rw-r--r--2024/go/src/day15/main.go146
2 files changed, 145 insertions, 10 deletions
diff --git a/2024/go/input/day15_3.test b/2024/go/input/day15_3.test
new file mode 100644
index 0000000..6ee6098
--- /dev/null
+++ b/2024/go/input/day15_3.test
@@ -0,0 +1,9 @@
+#######
+#...#.#
+#.....#
+#..OO@#
+#..O..#
+#.....#
+#######
+
+<vv<<^^<<^^
diff --git a/2024/go/src/day15/main.go b/2024/go/src/day15/main.go
index becf95f..684f045 100644
--- a/2024/go/src/day15/main.go
+++ b/2024/go/src/day15/main.go
@@ -3,6 +3,7 @@ package main
import (
"fmt"
"os"
+ "slices"
"strings"
)
@@ -71,13 +72,37 @@ func inBounds(x, y, w, h int) bool {
}
func isBlock(x, y int, warehouse Grid) bool {
- return warehouse[x][y] == 'O'
+ return slices.Contains([]byte{'O', '[', ']'}, warehouse[x][y])
}
func isWall(x, y int, warehouse Grid) bool {
return warehouse[x][y] == '#'
}
+func constructWideWarehouse(warehouse Grid) Grid {
+ var newWarehouse Grid
+ for i := 0; i < len(warehouse); i++ {
+ var row []byte
+ for j := 0; j < len(warehouse[0]); j++ {
+ if warehouse[i][j] == '.' {
+ row = append(row, '.')
+ row = append(row, '.')
+ } else if warehouse[i][j] == 'O' {
+ row = append(row, '[')
+ row = append(row, ']')
+ } else if warehouse[i][j] == '@' {
+ row = append(row, '@')
+ row = append(row, '.')
+ } else {
+ row = append(row, '#')
+ row = append(row, '#')
+ }
+ }
+ newWarehouse = append(newWarehouse, row)
+ }
+ return newWarehouse
+}
+
func simulate(input Input) Grid {
dirMap := map[byte]Point{
'<': {0, -1},
@@ -103,6 +128,7 @@ func simulate(input Input) Grid {
}
if !isWall(nx+dx*step, ny+dy*step, input.warehouse) {
for i := step; i >= 1; i-- {
+ // swaps blocks backwares
input.warehouse[nx+dx*(i-1)][ny+dy*(i-1)], input.warehouse[nx+dx*(i)][ny+dy*(i)] = input.warehouse[nx+dx*(i)][ny+dy*(i)], input.warehouse[nx+dx*(i-1)][ny+dy*(i-1)]
}
input.warehouse[nx][ny], input.warehouse[robotPos.x][robotPos.y] = input.warehouse[robotPos.x][robotPos.y], input.warehouse[nx][ny]
@@ -115,11 +141,110 @@ func simulate(input Input) Grid {
return input.warehouse
}
+func getBlocksToMove(pos Point, dir byte, blocksToMove *map[Point]bool, warehosue Grid) {
+ dirMap := map[byte]Point{
+ '<': {0, -1},
+ '>': {0, 1},
+ '^': {-1, 0},
+ 'v': {1, 0},
+ }
+ x, y := pos.x, pos.y
+ (*blocksToMove)[pos] = true
+ dx, dy := dirMap[dir].x, dirMap[dir].y
+ if warehosue[x][y] == '[' {
+ if !(*blocksToMove)[Point{x, y + 1}] {
+ getBlocksToMove(Point{x, y + 1}, dir, blocksToMove, warehosue)
+ }
+ if isBlock(x+dx, y+dy, warehosue) {
+ getBlocksToMove(Point{x + dx, y + dy}, dir, blocksToMove, warehosue)
+ }
+ } else if warehosue[x][y] == ']' {
+ if !(*blocksToMove)[Point{x, y - 1}] {
+ getBlocksToMove(Point{x, y - 1}, dir, blocksToMove, warehosue)
+ }
+ if isBlock(x+dx, y+dy, warehosue) {
+ getBlocksToMove(Point{x + dx, y + dy}, dir, blocksToMove, warehosue)
+ }
+ }
+
+}
+
+func copySlice(src [][]byte) [][]byte {
+ dest := make([][]byte, len(src))
+ for i, inner := range src {
+ if inner != nil {
+ dest[i] = make([]byte, len(inner))
+ copy(dest[i], inner)
+ }
+ }
+ return dest
+}
+
+func canMove(blocksToMove map[Point]bool, delta Point, warehouse Grid) bool {
+ for b := range blocksToMove {
+ x, y := b.x, b.y
+ nx, ny := x+delta.x, y+delta.y
+ if isWall(nx, ny, warehouse) {
+ return false
+ }
+ }
+ return true
+}
+
+func simulateWide(input Input) Grid {
+ dirMap := map[byte]Point{
+ '<': {0, -1},
+ '>': {0, 1},
+ '^': {-1, 0},
+ 'v': {1, 0},
+ }
+ w, h := len(input.warehouse), len(input.warehouse[0])
+ robotPos := getRobotsPos(input.warehouse)
+ for _, dir := range input.directions {
+ dx, dy := dirMap[dir].x, dirMap[dir].y
+ nx, ny := robotPos.x+dx, robotPos.y+dy
+ // fmt.Printf("dir: %v\n", string(dir))
+ // printGrid(input.warehouse)
+ // fmt.Println()
+ if inBounds(nx, ny, w, h) && !isWall(nx, ny, input.warehouse) {
+ if input.warehouse[nx][ny] == '.' {
+ input.warehouse[nx][ny], input.warehouse[robotPos.x][robotPos.y] = input.warehouse[robotPos.x][robotPos.y], input.warehouse[nx][ny]
+ robotPos.x = nx
+ robotPos.y = ny
+ } else if isBlock(nx, ny, input.warehouse) {
+ blocksToMove := make(map[Point]bool)
+ if isBlock(nx, ny, input.warehouse) {
+ getBlocksToMove(Point{nx, ny}, dir, &blocksToMove, input.warehouse)
+ if canMove(blocksToMove, dirMap[dir], input.warehouse) {
+ copiedWarehouse := copySlice(input.warehouse)
+ for b := range blocksToMove {
+ copiedWarehouse[b.x][b.y] = '.'
+ }
+ for b := range blocksToMove {
+ copiedWarehouse[b.x+dx][b.y+dy] = input.warehouse[b.x][b.y]
+ }
+ input.warehouse = copiedWarehouse
+ for p := range blocksToMove {
+ delete(blocksToMove, p)
+ }
+ input.warehouse[nx][ny] = input.warehouse[robotPos.x][robotPos.y]
+ input.warehouse[robotPos.x][robotPos.y] = '.'
+ robotPos.x = nx
+ robotPos.y = ny
+
+ }
+ }
+ }
+ }
+ }
+ return input.warehouse
+}
+
func sumGpsCoordinates(warehouse Grid) int {
ans := 0
for i, row := range warehouse {
for j, cell := range row {
- if cell == 'O' {
+ if cell == 'O' || cell == '[' {
ans += i*100 + j
}
}
@@ -129,15 +254,16 @@ func sumGpsCoordinates(warehouse Grid) int {
func solve_part_one(data string) int {
input := parseInput(data)
- // printGrid(input.warehouse)
- // printDirs(input.directions)
- // fmt.Println()
- warehosue := simulate(input)
- return sumGpsCoordinates(warehosue)
+ warehouse := simulate(input)
+ return sumGpsCoordinates(warehouse)
}
func solve_part_two(data string) int {
- return 42
+ input := parseInput(data)
+ warehouse := constructWideWarehouse(input.warehouse)
+ input.warehouse = warehouse
+ simualtedWareHouse := simulateWide(input)
+ return sumGpsCoordinates(simualtedWareHouse)
}
func main() {
@@ -145,6 +271,6 @@ func main() {
prod := FileRead("../input/day15.prod")
fmt.Println("Part_1 test: ", solve_part_one(test))
fmt.Println("Part_1 prod: ", solve_part_one(prod))
- // fmt.Println("Part_2 test: ", solve_part_two(test))
- // fmt.Println("Part_2 prod: ", solve_part_two(test))
+ fmt.Println("Part_2 test: ", solve_part_two(test))
+ fmt.Println("Part_2 prod: ", solve_part_two(prod))
}