diff --git a/17/main.go b/17/main.go new file mode 100644 index 0000000..cff5f6d --- /dev/null +++ b/17/main.go @@ -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) +}