adventofcode/2020/day10.go

122 lines
2.1 KiB
Go
Raw Normal View History

2020-12-11 10:19:50 +00:00
package main
import (
"fmt"
"log"
"os"
"git.annabunch.es/annabunches/adventofcode/2020/lib/fileutils"
)
func getMax(values map[int]bool) int {
max := 0
for value, _ := range values {
if value > max {
max = value
}
}
return max
}
2020-12-11 20:24:34 +00:00
type Node struct {
Value int
Children []*Node
Paths int // the total number of paths from here to some target
}
// Build a tree of possible paths, then count them.
func findArrangements(values map[int]bool, target int) int {
root := buildTree(values, target)
return countPaths(root, target)
}
func buildTree(values map[int]bool, target int) *Node {
values[0] = true
nodeMap := make(map[int]*Node)
for i := 0; i < target; i++ {
if values[i] {
node := createOrFetchNode(nodeMap, i)
for j := 1; j < 4; j++ {
if i+j > target {
break
}
if values[i+j] {
child := createOrFetchNode(nodeMap, i+j)
node.Children = append(node.Children, child)
}
}
}
}
return nodeMap[0]
}
func createOrFetchNode(nodeMap map[int]*Node, value int) *Node {
if node, ok := nodeMap[value]; ok {
return node
}
node := &Node{
Value: value,
Children: make([]*Node, 0),
}
nodeMap[value] = node
return node
}
func countPaths(node *Node, target int) int {
if node.Value == target {
return 1
}
paths := 0
for _, child := range node.Children {
if child.Paths != 0 {
paths += child.Paths
} else {
paths += countPaths(child, target)
}
}
node.Paths = paths
return paths
}
2020-12-11 10:19:50 +00:00
func main() {
2020-12-11 20:24:34 +00:00
step := os.Args[1]
2020-12-11 10:19:50 +00:00
values := fileutils.InputParserIntMap(os.Args[2])
diffMap := make(map[int]int)
device := getMax(values) + 3
values[device] = true
2020-12-11 20:24:34 +00:00
switch step {
case "1":
diff := 0
for i := 0; i < device; i++ {
// increment diff, make sure we haven't broken the chain
// Note that we're actually logically checking the joltage at i+1
// but that serves us well here
diff++
if diff > 3 {
log.Panicf("Diff too big, bailing.")
}
2020-12-11 10:19:50 +00:00
2020-12-11 20:24:34 +00:00
// if we have a device at this joltage, register and reset count
if values[i+1] {
diffMap[diff]++
diff = 0
}
2020-12-11 10:19:50 +00:00
}
2020-12-11 20:24:34 +00:00
fmt.Println(diffMap[1] * diffMap[3])
case "2":
fmt.Println(findArrangements(values, device))
2020-12-11 10:19:50 +00:00
}
}