AdventOfCode2020/17/main.go

236 lines
6.1 KiB
Go
Raw Normal View History

package main
import (
"bufio"
"fmt"
"os"
"time"
)
func main() {
start := time.Now()
partOne()
duration := time.Since(start)
partTwo()
duration2 := time.Since(start)
fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration)
}
type cell struct {
x int // length
y int // width
z int // depth
w int // spissitude
}
type universe struct {
cells map[cell]bool
hyper bool // true: 4-dimensional; false: 3-dimensional
}
func makeNeighborsList(c cell, hyper bool) []cell {
cells := []cell{}
if hyper {
cells = append(cells, []cell{
// outward...?
// above
{x: c.x + 1, y: c.y + 1, z: c.z + 1, w: c.w + 1},
{x: c.x + 1, y: c.y, z: c.z + 1, w: c.w + 1},
{x: c.x + 1, y: c.y - 1, z: c.z + 1, w: c.w + 1},
{x: c.x, y: c.y + 1, z: c.z + 1, w: c.w + 1},
{x: c.x, y: c.y, z: c.z + 1, w: c.w + 1},
{x: c.x, y: c.y - 1, z: c.z + 1, w: c.w + 1},
{x: c.x - 1, y: c.y + 1, z: c.z + 1, w: c.w + 1},
{x: c.x - 1, y: c.y, z: c.z + 1, w: c.w + 1},
{x: c.x - 1, y: c.y - 1, z: c.z + 1, w: c.w + 1},
// same layer
{x: c.x + 1, y: c.y + 1, z: c.z, w: c.w + 1},
{x: c.x + 1, y: c.y, z: c.z, w: c.w + 1},
{x: c.x + 1, y: c.y - 1, z: c.z, w: c.w + 1},
{x: c.x, y: c.y + 1, z: c.z, w: c.w + 1},
{x: c.x, y: c.y, z: c.z, w: c.w + 1},
{x: c.x, y: c.y - 1, z: c.z, w: c.w + 1},
{x: c.x - 1, y: c.y + 1, z: c.z, w: c.w + 1},
{x: c.x - 1, y: c.y, z: c.z, w: c.w + 1},
{x: c.x - 1, y: c.y - 1, z: c.z, w: c.w + 1},
// below
{x: c.x + 1, y: c.y + 1, z: c.z - 1, w: c.w + 1},
{x: c.x + 1, y: c.y, z: c.z - 1, w: c.w + 1},
{x: c.x + 1, y: c.y - 1, z: c.z - 1, w: c.w + 1},
{x: c.x, y: c.y + 1, z: c.z - 1, w: c.w + 1},
{x: c.x, y: c.y, z: c.z - 1, w: c.w + 1},
{x: c.x, y: c.y - 1, z: c.z - 1, w: c.w + 1},
{x: c.x - 1, y: c.y + 1, z: c.z - 1, w: c.w + 1},
{x: c.x - 1, y: c.y, z: c.z - 1, w: c.w + 1},
{x: c.x - 1, y: c.y - 1, z: c.z - 1, w: c.w + 1},
// inward...?
// above
{x: c.x + 1, y: c.y + 1, z: c.z + 1, w: c.w - 1},
{x: c.x + 1, y: c.y, z: c.z + 1, w: c.w - 1},
{x: c.x + 1, y: c.y - 1, z: c.z + 1, w: c.w - 1},
{x: c.x, y: c.y + 1, z: c.z + 1, w: c.w - 1},
{x: c.x, y: c.y, z: c.z + 1, w: c.w - 1},
{x: c.x, y: c.y - 1, z: c.z + 1, w: c.w - 1},
{x: c.x - 1, y: c.y + 1, z: c.z + 1, w: c.w - 1},
{x: c.x - 1, y: c.y, z: c.z + 1, w: c.w - 1},
{x: c.x - 1, y: c.y - 1, z: c.z + 1, w: c.w - 1},
// same layer
{x: c.x + 1, y: c.y + 1, z: c.z, w: c.w - 1},
{x: c.x + 1, y: c.y, z: c.z, w: c.w - 1},
{x: c.x + 1, y: c.y - 1, z: c.z, w: c.w - 1},
{x: c.x, y: c.y + 1, z: c.z, w: c.w - 1},
{x: c.x, y: c.y, z: c.z, w: c.w - 1},
{x: c.x, y: c.y - 1, z: c.z, w: c.w - 1},
{x: c.x - 1, y: c.y + 1, z: c.z, w: c.w - 1},
{x: c.x - 1, y: c.y, z: c.z, w: c.w - 1},
{x: c.x - 1, y: c.y - 1, z: c.z, w: c.w - 1},
// below
{x: c.x + 1, y: c.y + 1, z: c.z - 1, w: c.w - 1},
{x: c.x + 1, y: c.y, z: c.z - 1, w: c.w - 1},
{x: c.x + 1, y: c.y - 1, z: c.z - 1, w: c.w - 1},
{x: c.x, y: c.y + 1, z: c.z - 1, w: c.w - 1},
{x: c.x, y: c.y, z: c.z - 1, w: c.w - 1},
{x: c.x, y: c.y - 1, z: c.z - 1, w: c.w - 1},
{x: c.x - 1, y: c.y + 1, z: c.z - 1, w: c.w - 1},
{x: c.x - 1, y: c.y, z: c.z - 1, w: c.w - 1},
{x: c.x - 1, y: c.y - 1, z: c.z - 1, w: c.w - 1},
}...)
}
// "normal" space
cells = append(cells, []cell{
// above
{x: c.x + 1, y: c.y + 1, z: c.z + 1, w: c.w},
{x: c.x + 1, y: c.y, z: c.z + 1, w: c.w},
{x: c.x + 1, y: c.y - 1, z: c.z + 1, w: c.w},
{x: c.x, y: c.y + 1, z: c.z + 1, w: c.w},
{x: c.x, y: c.y, z: c.z + 1, w: c.w},
{x: c.x, y: c.y - 1, z: c.z + 1, w: c.w},
{x: c.x - 1, y: c.y + 1, z: c.z + 1, w: c.w},
{x: c.x - 1, y: c.y, z: c.z + 1, w: c.w},
{x: c.x - 1, y: c.y - 1, z: c.z + 1, w: c.w},
// same layer
{x: c.x + 1, y: c.y + 1, z: c.z, w: c.w},
{x: c.x + 1, y: c.y, z: c.z, w: c.w},
{x: c.x + 1, y: c.y - 1, z: c.z, w: c.w},
{x: c.x, y: c.y + 1, z: c.z, w: c.w},
// <-- original cell
{x: c.x, y: c.y - 1, z: c.z, w: c.w},
{x: c.x - 1, y: c.y + 1, z: c.z, w: c.w},
{x: c.x - 1, y: c.y, z: c.z, w: c.w},
{x: c.x - 1, y: c.y - 1, z: c.z, w: c.w},
// below
{x: c.x + 1, y: c.y + 1, z: c.z - 1, w: c.w},
{x: c.x + 1, y: c.y, z: c.z - 1, w: c.w},
{x: c.x + 1, y: c.y - 1, z: c.z - 1, w: c.w},
{x: c.x, y: c.y + 1, z: c.z - 1, w: c.w},
{x: c.x, y: c.y, z: c.z - 1, w: c.w},
{x: c.x, y: c.y - 1, z: c.z - 1, w: c.w},
{x: c.x - 1, y: c.y + 1, z: c.z - 1, w: c.w},
{x: c.x - 1, y: c.y, z: c.z - 1, w: c.w},
{x: c.x - 1, y: c.y - 1, z: c.z - 1, w: c.w},
}...)
return cells
}
func checkNeighbors(u universe, c cell) bool {
sum := 0
for _, c := range makeNeighborsList(c, u.hyper) {
if u.cells[c] {
sum = sum + 1
}
}
if sum == 3 {
return true
} else if u.cells[c] && sum == 2 {
return true
}
return false
}
func step(old universe) universe {
new := universe{
cells: make(map[cell]bool, len(old.cells)),
hyper: old.hyper,
}
cellsToCheck := make([]cell, 0, len(old.cells)*80)
for c := range old.cells {
cellsToCheck = append(cellsToCheck, makeNeighborsList(c, old.hyper)...)
}
for _, c := range cellsToCheck {
if checkNeighbors(old, c) {
new.cells[c] = true
}
}
return new
}
func newUniverse(input []string, hyper bool) universe {
u := universe{
cells: make(map[cell]bool, len(input)),
hyper: hyper,
}
for i, r := range input {
for j, c := range r {
if c == '#' {
u.cells[cell{z: 0, x: i, y: j, w: 0}] = true
}
}
}
return u
}
func countActivesInUniverse(u universe) {
fmt.Println(len(u.cells))
}
func partOne() {
f, _ := os.Open("input")
reader := bufio.NewReader(f)
scanner := bufio.NewScanner(reader)
var input []string
for scanner.Scan() {
input = append(input, scanner.Text())
}
u := newUniverse(input, false)
u = step(u)
u = step(u)
u = step(u)
u = step(u)
u = step(u)
u = step(u)
countActivesInUniverse(u)
}
func partTwo() {
f, _ := os.Open("input")
reader := bufio.NewReader(f)
scanner := bufio.NewScanner(reader)
var input []string
for scanner.Scan() {
input = append(input, scanner.Text())
}
u := newUniverse(input, true)
u = step(u)
u = step(u)
u = step(u)
u = step(u)
u = step(u)
u = step(u)
countActivesInUniverse(u)
}