advent-of-code

Perserverance, or the lack thereof

git clone git://git.shimmy1996.com/advent-of-code.git

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 }