package main import ( "fmt" "os" "strings" ) func FileRead(path string) string { file, err := os.ReadFile(path) if err != nil { fmt.Println("Couldn't Read file: ", err) } return string(file) } type Grid = [][]byte type Point struct { x int y int } type Input struct { warehouse Grid directions []byte } func getRobotsPos(warehouse Grid) Point { for i := 0; i < len(warehouse); i++ { for j := 0; j < len(warehouse[0]); j++ { if warehouse[i][j] == '@' { return Point{i, j} } } } return Point{0, 0} } func parseInput(data string) Input { splitted_data := strings.Split(data, "\n\n") directions := []byte(splitted_data[1]) var warehouse Grid for _, line := range strings.Split(splitted_data[0], "\n") { row := []byte(line) warehouse = append(warehouse, row) } return Input{ warehouse: warehouse, directions: directions, } } func printDirs(dirs []byte) { for _, dir := range dirs { fmt.Printf(string(dir)) } } func printGrid(grid [][]byte) { for _, row := range grid { for _, cell := range row { fmt.Printf(string(cell)) } fmt.Println() } } func inBounds(x, y, w, h int) bool { return x >= 0 && x < w && y >= 0 && y < h } func isBlock(x, y int, warehouse Grid) bool { return warehouse[x][y] == 'O' } func isWall(x, y int, warehouse Grid) bool { return warehouse[x][y] == '#' } func simulate(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 // printGrid(input.warehouse) 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) { step := 0 for isBlock(nx+dx*step, ny+dy*step, input.warehouse) { step++ } if !isWall(nx+dx*step, ny+dy*step, input.warehouse) { for i := step; i >= 1; i-- { 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] 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' { ans += i*100 + j } } } return ans } func solve_part_one(data string) int { input := parseInput(data) // printGrid(input.warehouse) // printDirs(input.directions) // fmt.Println() warehosue := simulate(input) return sumGpsCoordinates(warehosue) } func solve_part_two(data string) int { return 42 } func main() { test := FileRead("../input/day15_1.test") 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)) }