diff options
Diffstat (limited to 'day11/main.go')
-rw-r--r-- | day11/main.go | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/day11/main.go b/day11/main.go new file mode 100644 index 0000000..0212daa --- /dev/null +++ b/day11/main.go @@ -0,0 +1,68 @@ +package main + +import ( + "fmt" + "math" + "strconv" +) + +func main() { + fmt.Println(expand([]int64{125, 17}, 25), 55312) + fmt.Println(expand([]int64{6, 11, 33023, 4134, 564, 0, 8922422, 688775}, 25), 220999) + fmt.Println(expand([]int64{6, 11, 33023, 4134, 564, 0, 8922422, 688775}, 75)) +} + +func evenLength(v int64) bool { + return int(math.Ceil(math.Log10(float64(v)+0.5)))%2 == 0 +} + +func splitEven(v int64) (a, b int64) { + s := strconv.FormatInt(v, 10) + sa, sb := s[:len(s)/2], s[len(s)/2:] + a, err := strconv.ParseInt(sa, 10, 64) + if err != nil { + panic(err) + } + b, err = strconv.ParseInt(sb, 10, 64) + if err != nil { + panic(err) + } + return +} + +type Entry struct { + Value int64 + Depth int +} + +func expand(initial []int64, depth int) (result int) { + memo := make(map[Entry]int) + for _, n := range initial { + result += expandOne(memo, n, depth) + } + return +} + +func expandOne(memo map[Entry]int, v int64, depth int) int { + if depth == 0 { + return 1 + } + + entry := Entry{v, depth} + n, ok := memo[entry] + if ok { + return n + } + + if v == 0 { + n = expandOne(memo, 1, depth-1) + } else if evenLength(v) { + a, b := splitEven(v) + n = expandOne(memo, a, depth-1) + expandOne(memo, b, depth-1) + } else { + n = expandOne(memo, v*2024, depth-1) + } + + memo[entry] = n + return n +} |