package main import ( "AOC2022/helper" "fmt" ) func main() { //args := os.Args[1:] lines := helper.ReadTextFile("day23/input") elves := make(map[[2]int][3]int) for i := 0; i < len(lines); i++ { line := lines[i] for j := 0; j < len(line); j++ { if lines[i][j] == '#' { elves[[2]int{i, j}] = [3]int{0, 0, 0} } } } noElvesMoves := false i := 0 for !noElvesMoves { //Get planned move for all elves for key, _ := range elves { elves[key] = getPlannedMove(key, elves, i) } //Move elves noElvesMoves = moveElves(&elves) i++ if i == 10 { print(elves) } } fmt.Println(i) } func moveElves(elves *map[[2]int][3]int) bool { elvesWithPossiblePlanedMoves := [][2]int{} plannedMoves := make(map[[2]int][][2]int) for key, val := range *elves { if val != [3]int{0, 0, 0} { plannedMove := [2]int{key[0] + val[0], key[1] + val[1]} plannedMoves[plannedMove] = append(plannedMoves[plannedMove], key) } } for _, val := range plannedMoves { if len(val) == 1 { elvesWithPossiblePlanedMoves = append(elvesWithPossiblePlanedMoves, val[0]) } } if len(elvesWithPossiblePlanedMoves) == 0 { return true } for _, elv := range elvesWithPossiblePlanedMoves { moveElv(elv, elves) } return false } func moveElv(elv [2]int, elves *map[[2]int][3]int) { plannedMove := (*elves)[elv] newElv := [2]int{elv[0] + plannedMove[0], elv[1] + plannedMove[1]} delete(*elves, elv) (*elves)[newElv] = [3]int{0, 0, plannedMove[2] + 1} } func getPlannedMove(point [2]int, elves map[[2]int][3]int, pastMoves int) [3]int { plannedMove := [3]int{0, 0, 0} neighbors := getNeighbors(point) neigborexist := false checkedNorth := 0 checkedWest := 0 checkedSouth := 0 checkedEast := 0 for i, neighbor := range neighbors { _, exist := elves[neighbor] if exist { neigborexist = true } else { if i >= 0 && i <= 2 { checkedNorth++ } if i >= 2 && i <= 4 { checkedEast++ } if i >= 4 && i <= 6 { checkedSouth++ } if i >= 6 || i == 0 { checkedWest++ } } } if neigborexist { priorityList := []int{checkedNorth, checkedSouth, checkedWest, checkedEast} directions := [][2]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}} for i := 0; i < pastMoves; i++ { priorityList = append(priorityList[1:], priorityList[0]) directions = append(directions[1:], directions[0]) } for i, priority := range priorityList { if priority == 3 { direction := directions[i] plannedMove = [3]int{direction[0], direction[1], 0} break } } } return plannedMove } func getNeighbors(point [2]int) (neighbors [8][2]int) { directions := [8][2]int{{-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}} for i, direction := range directions { neighbors[i] = [2]int{point[0] + direction[0], point[1] + direction[1]} } return } func print(elves map[[2]int][3]int) { highestY := 0 highestX := 0 lowestY := 0 lowestX := 0 for key, _ := range elves { if key[0] > highestY { highestY = key[0] } if key[0] < lowestY { lowestY = key[0] } if key[1] > highestX { highestX = key[1] } if key[1] < lowestX { lowestX = key[1] } } for i := lowestY - 1; i < highestY+2; i++ { fieldLine := []rune{} for j := lowestX - 1; j < highestX+2; j++ { val := '.' _, ok := elves[[2]int{i, j}] if ok { val = '#' } fieldLine = append(fieldLine, val) } fmt.Println(string(fieldLine)) } fmt.Println((highestY-lowestY+1)*(highestX-lowestX+1) - len(elves)) fmt.Println() }