advent-of-code

Perserverance, or the lack thereof

git clone git://git.shimmy1996.com/advent-of-code.git
commit ced5160b78398f6857895b70adaa6d5ec90ee536
parent 127cd7561eb98b0095a614344525097c58e898b3
Author: Shimmy Xu <shimmy.xu@shimmy1996.com>
Date:   Thu, 17 Dec 2020 19:00:10 -0600

Add 2020 day 17

Diffstat:
A2020/day17/input.txt | 8++++++++
A2020/day17/main.go | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 121 insertions(+), 0 deletions(-)
diff --git a/2020/day17/input.txt b/2020/day17/input.txt
@@ -0,0 +1,8 @@
+..##.##.
+#.#..###
+##.#.#.#
+#.#.##.#
+###..#..
+.#.#..##
+#.##.###
+#.#..##.
diff --git a/2020/day17/main.go b/2020/day17/main.go
@@ -0,0 +1,113 @@
+package main
+
+import (
+	"bufio"
+	"fmt"
+	"os"
+)
+
+const (
+	INACTIVE = 0
+	ACTIVE   = 1
+)
+
+type pos [4]int
+
+func (this pos) Add(dp pos) pos {
+	for i := 0; i < len(this); i++ {
+		this[i] += dp[i]
+	}
+	return this
+}
+
+func readInput(filename string) (res map[pos]int) {
+	file, _ := os.Open(filename)
+	defer file.Close()
+
+	scanner := bufio.NewScanner(file)
+	res = map[pos]int{}
+	for x := 0; scanner.Scan(); x++ {
+		for y, ch := range scanner.Text() {
+			switch ch {
+			case '#':
+				res[pos{x, y}] = ACTIVE
+			case '.':
+				res[pos{x, y}] = INACTIVE
+			}
+		}
+	}
+	return
+}
+
+func main() {
+	input := readInput("./input.txt")
+	// 424
+	fmt.Println(part1(input))
+	// 2460
+	fmt.Println(part2(input))
+}
+
+func boot(curr map[pos]int, steps int, dpos []pos) map[pos]int {
+	for i := 0; i < steps; i++ {
+		// update active count
+		next := map[pos]int{}
+		for p, v := range curr {
+			next[p] = next[p] // ensure key exists
+			for _, dp := range dpos {
+				next[p.Add(dp)] += v
+			}
+		}
+		// update state
+		for p, activeCount := range next {
+			switch curr[p] {
+			case ACTIVE:
+				if activeCount == 2 || activeCount == 3 {
+					next[p] = ACTIVE
+				} else {
+					next[p] = INACTIVE
+				}
+			case INACTIVE:
+				if activeCount == 3 {
+					next[p] = ACTIVE
+				} else {
+					next[p] = INACTIVE
+				}
+			}
+		}
+		curr = next
+	}
+	return curr
+}
+
+func neighborPos(maxDim int) []pos {
+	curr := []pos{{}}
+	for i := 0; i < maxDim; i++ {
+		next := []pos{}
+		for _, p := range curr {
+			// keep first element the origin
+			for _, d := range []int{0, 1, -1} {
+				p[i] += d
+				next = append(next, p)
+				p[i] -= d
+			}
+		}
+		curr = next
+	}
+	return curr[1:]
+}
+
+func part1(input map[pos]int) (activeCount int) {
+	input = boot(input, 6, neighborPos(3))
+	for _, v := range input {
+		activeCount += v
+	}
+	return
+}
+
+func part2(input map[pos]int) (activeCount int) {
+	input = boot(input, 6, neighborPos(4))
+	for _, v := range input {
+		activeCount += v
+	}
+	return
+}