adventofcode/2020/day24/main.go

125 lines
2.2 KiB
Go
Raw Permalink Normal View History

package main
import (
"fmt"
h "git.bullercodeworks.com/brian/adventofcode/helpers"
)
const (
White = iota
Black
)
var tiles map[h.Coordinate]bool
func init() {
tiles = make(map[h.Coordinate]bool)
}
func main() {
2020-12-25 13:57:34 +00:00
fmt.Println("# Day 24")
inp := h.StdinToStringSlice()
solve(inp, h.Atoi(h.OptArgNumber(1, "2")))
}
func solve(inp []string, part int) {
buildTiles(inp)
if part == 1 {
fmt.Println("## Part 1\nAnswer:", len(tiles))
} else {
for day := 1; day <= 100; day++ {
next := make(map[h.Coordinate]bool)
lx, ly, hx, hy := getBordering()
for y := ly; y <= hy; y++ {
for x := lx; x <= hx; x++ {
tst := h.Coordinate{X: x, Y: y}
_, ok := tiles[tst]
bl := CountTiles(GetAllNeighborCoords(tst))
if (ok && !(bl == 0 || bl > 2)) || (!ok && bl == 2) {
next[tst] = true
}
}
}
tiles = next
fmt.Printf("Day %d: %d\n", day, len(next))
}
}
}
func getBordering() (int, int, int, int) {
lx, ly, hx, hy := h.MAX_INT, h.MAX_INT, h.MIN_INT, h.MIN_INT
for k := range tiles {
lx = h.Min(lx, k.X)
ly = h.Min(ly, k.Y)
hx = h.Max(hx, k.X)
hy = h.Max(hy, k.Y)
}
return lx - 1, ly - 1, hx + 1, hy + 1
}
/*
o o
o o o
o o
*/
func buildTiles(inp []string) {
for k := range inp {
curr := h.Coordinate{}
var last rune
for _, r := range inp[k] {
if r == 'n' || r == 's' {
last = r
continue
}
curr = GetNeighborCoord(curr, last+r)
last = 0
}
if v := tiles[curr]; v {
delete(tiles, curr)
} else {
tiles[curr] = true
}
}
}
func CountTiles(c []h.Coordinate) int {
var ret int
for _, v := range c {
if _, ok := tiles[v]; ok {
ret++
}
}
return ret
}
func GetAllNeighborCoords(c h.Coordinate) []h.Coordinate {
var ret []h.Coordinate
for _, v := range []rune{
'e', 'n' + 'e', 's' + 'e', 'w', 'n' + 'w', 's' + 'w',
} {
ret = append(ret, GetNeighborCoord(c, v))
}
return ret
}
// Translate hex neighbors into a 2d plane
func GetNeighborCoord(c h.Coordinate, dir rune) h.Coordinate {
switch dir {
case 'e':
return c.East()
case 'n' + 'e':
return c.North()
case 's' + 'e':
return c.South().East()
case 'w':
return c.West()
case 'n' + 'w':
return c.North().West()
case 's' + 'w':
return c.South()
}
return c
}