From 43ebc47a012a7b957d32748273438aaeda8649f6 Mon Sep 17 00:00:00 2001 From: RhiobeT Date: Fri, 23 Dec 2022 14:01:40 +0100 Subject: [PATCH] Day 23 --- day23/common/seeds.go | 228 ++++++++++++++++++++++++++++++++++++++++++ day23/ex1/main.go | 19 ++++ day23/ex2/main.go | 19 ++++ 3 files changed, 266 insertions(+) create mode 100644 day23/common/seeds.go create mode 100644 day23/ex1/main.go create mode 100644 day23/ex2/main.go diff --git a/day23/common/seeds.go b/day23/common/seeds.go new file mode 100644 index 0000000..ea1d565 --- /dev/null +++ b/day23/common/seeds.go @@ -0,0 +1,228 @@ +package common + +import ( + "bufio" + "fmt" + "math" +) + + +type Tile byte + +const ( + Empty Tile = iota + Elf +) + + +type Direction byte + +const ( + East Direction = iota + West + North + South +) + +func (direction Direction) GetNext() Direction { + switch direction { + case North: + return South + case South: + return West + case West: + return East + default: + return North + } +} + + +type Coordinates struct { + x int + y int +} + + +type Map struct { + tiles map[Coordinates]Tile + currentRound Direction + boundedCoordinates []Coordinates +} + +func (tileMap *Map) Round() bool { + nextCoordinates := map[Coordinates][]Coordinates{} + isFinalRound := true + + for coordinates, tile := range tileMap.tiles { + if tile == Elf { + neighbor := false + outer: + for i := -1; i <= 1; i++ { + for j := -1; j <= 1; j++ { + if i != 0 || j != 0 { + if tile, ok := tileMap.tiles[Coordinates{coordinates.x+i, coordinates.y+j}]; ok && tile == Elf { + neighbor = true + break outer + } + } + } + } + if !neighbor { + continue + } + + var nextC Coordinates + round := tileMap.currentRound + move := false + + loop: + for i := 0; i < 4; i++ { + switch round { + case North: + tile1, ok1 := tileMap.tiles[Coordinates{coordinates.x-1, coordinates.y-1}] + tile2, ok2 := tileMap.tiles[Coordinates{coordinates.x, coordinates.y-1}] + tile3, ok3 := tileMap.tiles[Coordinates{coordinates.x+1, coordinates.y-1}] + nextC = Coordinates{coordinates.x, coordinates.y-1} + if (!ok1 || tile1 == Empty) && (!ok2 || tile2 == Empty) && (!ok3 || tile3 == Empty) { + move = true + break loop + } + case South: + tile1, ok1 := tileMap.tiles[Coordinates{coordinates.x-1, coordinates.y+1}] + tile2, ok2 := tileMap.tiles[Coordinates{coordinates.x, coordinates.y+1}] + tile3, ok3 := tileMap.tiles[Coordinates{coordinates.x+1, coordinates.y+1}] + nextC = Coordinates{coordinates.x, coordinates.y+1} + if (!ok1 || tile1 == Empty) && (!ok2 || tile2 == Empty) && (!ok3 || tile3 == Empty) { + move = true + break loop + } + case West: + tile1, ok1 := tileMap.tiles[Coordinates{coordinates.x-1, coordinates.y-1}] + tile2, ok2 := tileMap.tiles[Coordinates{coordinates.x-1, coordinates.y}] + tile3, ok3 := tileMap.tiles[Coordinates{coordinates.x-1, coordinates.y+1}] + nextC = Coordinates{coordinates.x-1, coordinates.y} + if (!ok1 || tile1 == Empty) && (!ok2 || tile2 == Empty) && (!ok3 || tile3 == Empty) { + move = true + break loop + } + case East: + tile1, ok1 := tileMap.tiles[Coordinates{coordinates.x+1, coordinates.y-1}] + tile2, ok2 := tileMap.tiles[Coordinates{coordinates.x+1, coordinates.y}] + tile3, ok3 := tileMap.tiles[Coordinates{coordinates.x+1, coordinates.y+1}] + nextC = Coordinates{coordinates.x+1, coordinates.y} + if (!ok1 || tile1 == Empty) && (!ok2 || tile2 == Empty) && (!ok3 || tile3 == Empty) { + move = true + break loop + } + } + round = round.GetNext() + } + + if move { + if _, okc := nextCoordinates[nextC]; !okc { + nextCoordinates[nextC] = []Coordinates{} + } + nextCoordinates[nextC] = append(nextCoordinates[nextC], coordinates) + } + } + } + + for nextC := range nextCoordinates { + if len(nextCoordinates[nextC]) == 1 { + tileMap.tiles[nextCoordinates[nextC][0]] = Empty + tileMap.tiles[nextC] = Elf + isFinalRound = false + } + } + + tileMap.currentRound = tileMap.currentRound.GetNext() + + return isFinalRound +} + +func (tileMap *Map) GetEmpty() int { + nEmpty := 0 + for x := tileMap.boundedCoordinates[0].x; x <= tileMap.boundedCoordinates[1].x; x++ { + for y := tileMap.boundedCoordinates[0].y; y <= tileMap.boundedCoordinates[1].y; y++ { + if tileMap.tiles[Coordinates{x, y}] == Empty { + nEmpty++ + } + } + } + return nEmpty +} + +func (tileMap *Map) Bound() { + minX := math.MaxInt32 + minY := math.MaxInt32 + maxX := math.MinInt32 + maxY := math.MinInt32 + + for coordinates, tile := range tileMap.tiles { + if tile == Elf { + if coordinates.x < minX { + minX = coordinates.x + } + if coordinates.x > maxX { + maxX = coordinates.x + } + if coordinates.y < minY { + minY = coordinates.y + } + if coordinates.y > maxY { + maxY = coordinates.y + } + } + } + + tileMap.boundedCoordinates = []Coordinates{{minX, minY}, {maxX, maxY}} + + for x := minX; x <= maxX; x++ { + for y := minY; y <= maxY; y++ { + c := Coordinates{x, y} + if _, ok := tileMap.tiles[c]; !ok { + tileMap.tiles[c] = Empty + } + } + } +} + +func (tileMap *Map) Print() { + for y := tileMap.boundedCoordinates[0].y; y <= tileMap.boundedCoordinates[1].y; y++ { + for x := tileMap.boundedCoordinates[0].x; x <= tileMap.boundedCoordinates[1].x; x++ { + switch tileMap.tiles[Coordinates{x, y}] { + case Empty: + fmt.Print(".") + case Elf: + fmt.Print("#") + } + } + fmt.Println() + } +} + + +func Parse(scanner bufio.Scanner) Map { + tileMap := Map{} + tileMap.tiles = make(map[Coordinates]Tile) + + i := 0 + for scanner.Scan() { + line := scanner.Text() + + for j := range line { + switch line[j] { + case '.': + tileMap.tiles[Coordinates{j, i}] = Empty + case '#': + tileMap.tiles[Coordinates{j, i}] = Elf + } + } + i++ + } + + tileMap.currentRound = North + + return tileMap +} diff --git a/day23/ex1/main.go b/day23/ex1/main.go new file mode 100644 index 0000000..e0f9eb3 --- /dev/null +++ b/day23/ex1/main.go @@ -0,0 +1,19 @@ +package main + +import ( + "aoc2022/day23/common" + "bufio" + "fmt" + "os" +) + +func main() { + tileMap := common.Parse(*bufio.NewScanner(os.Stdin)) + + for i := 0; i < 10; i++ { + tileMap.Round() + } + + tileMap.Bound() + fmt.Println(tileMap.GetEmpty()) +} diff --git a/day23/ex2/main.go b/day23/ex2/main.go new file mode 100644 index 0000000..4301177 --- /dev/null +++ b/day23/ex2/main.go @@ -0,0 +1,19 @@ +package main + +import ( + "aoc2022/day23/common" + "bufio" + "fmt" + "os" +) + +func main() { + tileMap := common.Parse(*bufio.NewScanner(os.Stdin)) + + i := 1 + for !tileMap.Round() { + i++ + } + + fmt.Println(i) +}