adventofcode/2019/day24/layout.go

113 lines
2.2 KiB
Go
Raw Permalink Normal View History

2020-11-04 17:56:23 +00:00
package main
import (
"log"
"math"
"strings"
"io/ioutil"
h "git.bullercodeworks.com/brian/adventofcode/helpers"
)
type Layout struct {
Area map[h.Coordinate]bool
BottomRight h.Coordinate
History map[string]float64
}
func NewLayout(filename string) *Layout {
ret := Layout{
Area: make(map[h.Coordinate]bool),
BottomRight: h.Coordinate{X: 0, Y: 0},
History: make(map[string]float64),
}
input, err := ioutil.ReadFile(filename)
if err != nil {
log.Fatal(err.Error())
}
lines := make([]string, 0)
for _, line := range strings.Split(string(input), "\n") {
lines = append(lines, line)
}
for y := 0; y < len(lines); y++ {
if len(lines[y]) < ret.BottomRight.X {
break
}
ret.BottomRight.Y = y
for x := 0; x < len(lines[y]); x++ {
ret.BottomRight.X = x
ret.Area[h.Coordinate{X: x, Y: y}] = lines[y][x] == '#'
}
}
ret.SaveToHistory()
return &ret
}
func (l Layout) SaveToHistory() {
l.History[l.String()] = l.Rating()
}
func (l Layout) Rating() float64 {
var rating, pow float64
for y := 0; y <= l.BottomRight.Y; y++ {
for x := 0; x <= l.BottomRight.X; x++ {
if l.Area[h.Coordinate{X: x, Y: y}] {
rating = rating + math.Pow(2, pow)
}
pow++
}
}
return rating
}
func (l Layout) Step() bool {
a := make(map[h.Coordinate]bool)
for k, v := range l.Area {
a[k] = v
}
for y := 0; y <= l.BottomRight.Y; y++ {
for x := 0; x <= l.BottomRight.X; x++ {
c := h.Coordinate{X: x, Y: y}
neighbors := 0
for _, v := range []h.Coordinate{c.North(), c.East(), c.South(), c.West()} {
if n, ok := l.Area[v]; ok && n {
neighbors++
}
}
if l.Area[c] {
if neighbors != 1 {
a[c] = false
}
} else {
if neighbors == 1 || neighbors == 2 {
a[c] = true
}
}
}
}
for k, v := range a {
l.Area[k] = v
}
// Finally check/save to history
_, ok := l.History[l.String()]
l.History[l.String()] = l.Rating()
return ok
}
func (l Layout) String() string {
var ret string
for y := 0; y <= l.BottomRight.Y; y++ {
for x := 0; x <= l.BottomRight.X; x++ {
if l.Area[h.Coordinate{X: x, Y: y}] {
ret = ret + "#"
} else {
ret = ret + "."
}
}
ret = ret + "\n"
}
return ret
}