161 lines
3.4 KiB
Go
161 lines
3.4 KiB
Go
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()
|
|
|
|
}
|