main.go (1923B)
1 package main
2
3 import (
4 "bufio"
5 "fmt"
6 "os"
7 )
8
9 const (
10 INACTIVE = 0
11 ACTIVE = 1
12 )
13
14 type pos [4]int
15
16 func (this pos) Add(dp pos) pos {
17 for i := 0; i < len(this); i++ {
18 this[i] += dp[i]
19 }
20 return this
21 }
22
23 func readInput(filename string) (res map[pos]int) {
24 file, _ := os.Open(filename)
25 defer file.Close()
26
27 scanner := bufio.NewScanner(file)
28 res = map[pos]int{}
29 for x := 0; scanner.Scan(); x++ {
30 for y, ch := range scanner.Text() {
31 switch ch {
32 case '#':
33 res[pos{x, y}] = ACTIVE
34 case '.':
35 res[pos{x, y}] = INACTIVE
36 }
37 }
38 }
39 return
40 }
41
42 func main() {
43 input := readInput("./input.txt")
44 // 424
45 fmt.Println(part1(input))
46 // 2460
47 fmt.Println(part2(input))
48 }
49
50 func boot(curr map[pos]int, steps int, dpos []pos) map[pos]int {
51 for i := 0; i < steps; i++ {
52 // update active count
53 next := map[pos]int{}
54 for p, v := range curr {
55 next[p] = next[p] // ensure key exists
56 for _, dp := range dpos {
57 next[p.Add(dp)] += v
58 }
59 }
60 // update state
61 for p, activeCount := range next {
62 switch curr[p] {
63 case ACTIVE:
64 if activeCount == 2 || activeCount == 3 {
65 next[p] = ACTIVE
66 } else {
67 next[p] = INACTIVE
68 }
69 case INACTIVE:
70 if activeCount == 3 {
71 next[p] = ACTIVE
72 } else {
73 next[p] = INACTIVE
74 }
75 }
76 }
77 curr = next
78 }
79 return curr
80 }
81
82 func neighborPos(maxDim int) []pos {
83 curr := []pos{{}}
84 for i := 0; i < maxDim; i++ {
85 next := []pos{}
86 for _, p := range curr {
87 // keep first element the origin
88 for _, d := range []int{0, 1, -1} {
89 p[i] += d
90 next = append(next, p)
91 p[i] -= d
92 }
93 }
94 curr = next
95 }
96 return curr[1:]
97 }
98
99 func part1(input map[pos]int) (activeCount int) {
100 input = boot(input, 6, neighborPos(3))
101 for _, v := range input {
102 activeCount += v
103 }
104 return
105 }
106
107 func part2(input map[pos]int) (activeCount int) {
108 input = boot(input, 6, neighborPos(4))
109 for _, v := range input {
110 activeCount += v
111 }
112 return
113 }