2019 Day 24 Complete
This commit is contained in:
parent
847235118b
commit
fd5be536a3
5
2019/day24/input
Normal file
5
2019/day24/input
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
##.#.
|
||||||
|
.#.##
|
||||||
|
.#...
|
||||||
|
#..#.
|
||||||
|
.##..
|
112
2019/day24/layout.go
Normal file
112
2019/day24/layout.go
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
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
|
||||||
|
}
|
215
2019/day24/layout3d.go
Normal file
215
2019/day24/layout3d.go
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Layout3d struct {
|
||||||
|
Area map[h.Coordinate3d]bool
|
||||||
|
TopLeft h.Coordinate3d
|
||||||
|
BottomRight h.Coordinate3d
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLayout3d(filename string) *Layout3d {
|
||||||
|
ret := Layout3d{
|
||||||
|
Area: make(map[h.Coordinate3d]bool),
|
||||||
|
TopLeft: h.Coordinate3d{X: 0, Y: 0, Z: 0},
|
||||||
|
BottomRight: h.Coordinate3d{X: 0, Y: 0, Z: 0},
|
||||||
|
}
|
||||||
|
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.Coordinate3d{X: x, Y: y}] = lines[y][x] == '#'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Layout3d) Step() {
|
||||||
|
a := make(map[h.Coordinate3d]bool)
|
||||||
|
for k, v := range l.Area {
|
||||||
|
a[k] = v
|
||||||
|
}
|
||||||
|
middle := h.Coordinate{X: l.BottomRight.X / 2, Y: l.BottomRight.Y / 2}
|
||||||
|
for z := l.TopLeft.Z - 1; z <= l.BottomRight.Z+1; z++ {
|
||||||
|
for y := l.TopLeft.Y; y <= l.BottomRight.Y; y++ {
|
||||||
|
for x := l.TopLeft.X; x <= l.BottomRight.X; x++ {
|
||||||
|
c := h.Coordinate3d{X: x, Y: y, Z: z}
|
||||||
|
if x == middle.X && y == middle.Y {
|
||||||
|
a[c] = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
neighbors := l.GetNeighborCount(c)
|
||||||
|
if l.Area[c] {
|
||||||
|
if neighbors != 1 {
|
||||||
|
a[c] = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if neighbors == 1 || neighbors == 2 {
|
||||||
|
a[c] = true
|
||||||
|
// If c is on a new 'z', we need to expand our TopLeft/BottomRight
|
||||||
|
if c.Z < l.TopLeft.Z {
|
||||||
|
l.TopLeft.Z = c.Z
|
||||||
|
} else if c.Z > l.BottomRight.Z {
|
||||||
|
l.BottomRight.Z = c.Z
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for k, v := range a {
|
||||||
|
l.Area[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Layout3d) GetNeighborCount(c h.Coordinate3d) int {
|
||||||
|
middle := h.Coordinate3d{X: l.BottomRight.X / 2, Y: l.BottomRight.Y / 2, Z: c.Z}
|
||||||
|
var neighbors []h.Coordinate3d
|
||||||
|
|
||||||
|
if c.Y == l.TopLeft.Y {
|
||||||
|
neighbors = append(neighbors, middle.Up().North())
|
||||||
|
neighbors = append(neighbors, c.South())
|
||||||
|
if c.X == l.TopLeft.X {
|
||||||
|
neighbors = append(neighbors, middle.Up().West())
|
||||||
|
neighbors = append(neighbors, c.East())
|
||||||
|
} else if c.X == l.BottomRight.X {
|
||||||
|
neighbors = append(neighbors, middle.Up().East())
|
||||||
|
neighbors = append(neighbors, c.West())
|
||||||
|
} else {
|
||||||
|
neighbors = append(neighbors, c.West())
|
||||||
|
neighbors = append(neighbors, c.East())
|
||||||
|
}
|
||||||
|
} else if c.Y == l.BottomRight.Y {
|
||||||
|
neighbors = append(neighbors, middle.Up().South())
|
||||||
|
neighbors = append(neighbors, c.North())
|
||||||
|
if c.X == l.TopLeft.X {
|
||||||
|
neighbors = append(neighbors, middle.Up().West())
|
||||||
|
neighbors = append(neighbors, c.East())
|
||||||
|
} else if c.X == l.BottomRight.X {
|
||||||
|
neighbors = append(neighbors, middle.Up().East())
|
||||||
|
neighbors = append(neighbors, c.West())
|
||||||
|
} else {
|
||||||
|
neighbors = append(neighbors, c.West())
|
||||||
|
neighbors = append(neighbors, c.East())
|
||||||
|
}
|
||||||
|
} else if c.X == l.TopLeft.X {
|
||||||
|
neighbors = append(neighbors, middle.Up().West())
|
||||||
|
neighbors = append(neighbors, c.East())
|
||||||
|
if c.Y == l.TopLeft.Y {
|
||||||
|
neighbors = append(neighbors, middle.Up().North())
|
||||||
|
neighbors = append(neighbors, c.South())
|
||||||
|
} else if c.Y == l.BottomRight.Y {
|
||||||
|
neighbors = append(neighbors, middle.Up().South())
|
||||||
|
neighbors = append(neighbors, c.North())
|
||||||
|
} else {
|
||||||
|
neighbors = append(neighbors, c.South())
|
||||||
|
neighbors = append(neighbors, c.North())
|
||||||
|
}
|
||||||
|
} else if c.X == l.BottomRight.X {
|
||||||
|
neighbors = append(neighbors, middle.Up().East())
|
||||||
|
neighbors = append(neighbors, c.West())
|
||||||
|
if c.Y == l.TopLeft.Y {
|
||||||
|
neighbors = append(neighbors, middle.Up().North())
|
||||||
|
neighbors = append(neighbors, c.South())
|
||||||
|
} else if c.Y == l.BottomRight.Y {
|
||||||
|
neighbors = append(neighbors, middle.Up().South())
|
||||||
|
neighbors = append(neighbors, c.North())
|
||||||
|
} else {
|
||||||
|
neighbors = append(neighbors, c.South())
|
||||||
|
neighbors = append(neighbors, c.North())
|
||||||
|
}
|
||||||
|
} else if c.Y == middle.Y-1 && c.X == middle.X {
|
||||||
|
neighbors = append(neighbors, c.North())
|
||||||
|
neighbors = append(neighbors, c.East())
|
||||||
|
neighbors = append(neighbors, c.West())
|
||||||
|
// South is the North row of the lower grid
|
||||||
|
for x := l.TopLeft.X; x <= l.BottomRight.X; x++ {
|
||||||
|
neighbors = append(neighbors, h.Coordinate3d{X: x, Y: l.TopLeft.Y, Z: c.Down().Z})
|
||||||
|
}
|
||||||
|
} else if c.Y == middle.Y+1 && c.X == middle.X {
|
||||||
|
neighbors = append(neighbors, c.East())
|
||||||
|
neighbors = append(neighbors, c.South())
|
||||||
|
neighbors = append(neighbors, c.West())
|
||||||
|
// North is the South row of the lower grid
|
||||||
|
for x := l.TopLeft.X; x <= l.BottomRight.X; x++ {
|
||||||
|
neighbors = append(neighbors, h.Coordinate3d{X: x, Y: l.BottomRight.Y, Z: c.Down().Z})
|
||||||
|
}
|
||||||
|
} else if c.X == middle.X-1 && c.Y == middle.Y {
|
||||||
|
neighbors = append(neighbors, c.North())
|
||||||
|
neighbors = append(neighbors, c.South())
|
||||||
|
neighbors = append(neighbors, c.West())
|
||||||
|
// East is the West row of the lower grid
|
||||||
|
for y := l.TopLeft.Y; y <= l.BottomRight.Y; y++ {
|
||||||
|
neighbors = append(neighbors, h.Coordinate3d{X: l.TopLeft.X, Y: y, Z: c.Down().Z})
|
||||||
|
}
|
||||||
|
} else if c.X == middle.X+1 && c.Y == middle.Y {
|
||||||
|
neighbors = append(neighbors, c.North())
|
||||||
|
neighbors = append(neighbors, c.East())
|
||||||
|
neighbors = append(neighbors, c.South())
|
||||||
|
// West is the East row of the lower grid
|
||||||
|
for y := l.TopLeft.Y; y <= l.BottomRight.Y; y++ {
|
||||||
|
neighbors = append(neighbors, h.Coordinate3d{X: l.BottomRight.X, Y: y, Z: c.Down().Z})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
neighbors = append(neighbors, c.North())
|
||||||
|
neighbors = append(neighbors, c.East())
|
||||||
|
neighbors = append(neighbors, c.South())
|
||||||
|
neighbors = append(neighbors, c.West())
|
||||||
|
}
|
||||||
|
ret := 0
|
||||||
|
for _, v := range neighbors {
|
||||||
|
if n, ok := l.Area[v]; ok && n {
|
||||||
|
ret++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Layout3d) CountBugs() int {
|
||||||
|
var ret int
|
||||||
|
for _, v := range l.Area {
|
||||||
|
if v {
|
||||||
|
ret++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l Layout3d) String() string {
|
||||||
|
var ret string
|
||||||
|
middle := h.Coordinate{X: l.BottomRight.X / 2, Y: l.BottomRight.Y / 2}
|
||||||
|
for z := l.TopLeft.Z; z <= l.BottomRight.Z; z++ {
|
||||||
|
ret = fmt.Sprintf("%s\nDepth %d:\n", ret, z)
|
||||||
|
for y := l.TopLeft.Y; y <= l.BottomRight.Y; y++ {
|
||||||
|
for x := l.TopLeft.X; x <= l.BottomRight.X; x++ {
|
||||||
|
if x == middle.X && y == middle.Y {
|
||||||
|
ret = ret + "?"
|
||||||
|
} else if l.Area[h.Coordinate3d{X: x, Y: y, Z: z}] {
|
||||||
|
ret = ret + "#"
|
||||||
|
} else {
|
||||||
|
ret = ret + "."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = ret + "\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
39
2019/day24/main.go
Normal file
39
2019/day24/main.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
filename := "input"
|
||||||
|
if h.GetArgNumber(1) != "" {
|
||||||
|
filename = h.GetArgNumber(1)
|
||||||
|
}
|
||||||
|
if h.GetArgNumber(2) != "2" {
|
||||||
|
part1(filename)
|
||||||
|
} else {
|
||||||
|
part2(filename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func part1(filename string) {
|
||||||
|
l := NewLayout(filename)
|
||||||
|
for !l.Step() {
|
||||||
|
fmt.Println(h.CLEAR_SCREEN)
|
||||||
|
fmt.Println(l)
|
||||||
|
fmt.Println(int(l.Rating()))
|
||||||
|
}
|
||||||
|
fmt.Println(h.CLEAR_SCREEN)
|
||||||
|
fmt.Println(l)
|
||||||
|
fmt.Println(int(l.Rating()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func part2(filename string) {
|
||||||
|
l := NewLayout3d(filename)
|
||||||
|
for i := 0; i < 200; i++ {
|
||||||
|
l.Step()
|
||||||
|
}
|
||||||
|
fmt.Println("Bugs:", l.CountBugs())
|
||||||
|
}
|
5
2019/day24/testinput
Normal file
5
2019/day24/testinput
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
....#
|
||||||
|
#..#.
|
||||||
|
#..##
|
||||||
|
..#..
|
||||||
|
#....
|
@ -14,6 +14,19 @@ func NewCoordinate(x, y int) *Coordinate {
|
|||||||
return &Coordinate{x, y}
|
return &Coordinate{x, y}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Coordinate) North() Coordinate {
|
||||||
|
return Coordinate{X: c.X, Y: c.Y - 1}
|
||||||
|
}
|
||||||
|
func (c *Coordinate) East() Coordinate {
|
||||||
|
return Coordinate{X: c.X + 1, Y: c.Y}
|
||||||
|
}
|
||||||
|
func (c *Coordinate) South() Coordinate {
|
||||||
|
return Coordinate{X: c.X, Y: c.Y + 1}
|
||||||
|
}
|
||||||
|
func (c *Coordinate) West() Coordinate {
|
||||||
|
return Coordinate{X: c.X - 1, Y: c.Y}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Coordinate) GetNorthCoord() *Coordinate {
|
func (c *Coordinate) GetNorthCoord() *Coordinate {
|
||||||
return &Coordinate{
|
return &Coordinate{
|
||||||
X: c.X,
|
X: c.X,
|
||||||
|
@ -10,6 +10,25 @@ func NewCoordinate3d(x, y, z int) *Coordinate3d {
|
|||||||
return &Coordinate3d{x, y, z}
|
return &Coordinate3d{x, y, z}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c Coordinate3d) North() Coordinate3d {
|
||||||
|
return Coordinate3d{X: c.X, Y: c.Y - 1, Z: c.Z}
|
||||||
|
}
|
||||||
|
func (c Coordinate3d) East() Coordinate3d {
|
||||||
|
return Coordinate3d{X: c.X + 1, Y: c.Y, Z: c.Z}
|
||||||
|
}
|
||||||
|
func (c Coordinate3d) South() Coordinate3d {
|
||||||
|
return Coordinate3d{X: c.X, Y: c.Y + 1, Z: c.Z}
|
||||||
|
}
|
||||||
|
func (c Coordinate3d) West() Coordinate3d {
|
||||||
|
return Coordinate3d{X: c.X - 1, Y: c.Y, Z: c.Z}
|
||||||
|
}
|
||||||
|
func (c Coordinate3d) Up() Coordinate3d {
|
||||||
|
return Coordinate3d{X: c.X, Y: c.Y, Z: c.Z + 1}
|
||||||
|
}
|
||||||
|
func (c Coordinate3d) Down() Coordinate3d {
|
||||||
|
return Coordinate3d{X: c.X, Y: c.Y, Z: c.Z - 1}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Coordinate3d) GetNorthCoord() *Coordinate3d {
|
func (c *Coordinate3d) GetNorthCoord() *Coordinate3d {
|
||||||
return &Coordinate3d{
|
return &Coordinate3d{
|
||||||
X: c.X,
|
X: c.X,
|
||||||
|
Loading…
Reference in New Issue
Block a user