when in doubt, copy and paste. part 2 completes in under a second!
This commit is contained in:
parent
e1d3ca5ea2
commit
d8ed532442
235
17/main.go
Normal file
235
17/main.go
Normal file
@ -0,0 +1,235 @@
|
||||
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)
|
||||
}
|
Loading…
Reference in New Issue
Block a user