Compare commits
No commits in common. "a83dccd53b4266dbef91de0d8b15cfe134bcb0ad" and "4e10039bfb84e74e6f7f3871692281eea6c2ca1d" have entirely different histories.
a83dccd53b
...
4e10039bfb
121
2020/day10.go
121
2020/day10.go
|
@ -1,121 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
step := os.Args[1]
|
|
||||||
values := fileutils.InputParserIntMap(os.Args[2])
|
|
||||||
|
|
||||||
diffMap := make(map[int]int)
|
|
||||||
|
|
||||||
device := getMax(values) + 3
|
|
||||||
values[device] = true
|
|
||||||
|
|
||||||
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.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we have a device at this joltage, register and reset count
|
|
||||||
if values[i+1] {
|
|
||||||
diffMap[diff]++
|
|
||||||
diff = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Println(diffMap[1] * diffMap[3])
|
|
||||||
|
|
||||||
case "2":
|
|
||||||
fmt.Println(findArrangements(values, device))
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user