111 lines
2.2 KiB
Go
111 lines
2.2 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
|
||
|
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||
|
)
|
||
|
|
||
|
// 2185006187 is too high
|
||
|
// 1920491799 is too high
|
||
|
|
||
|
func main() {
|
||
|
inp := h.StdinToStringSlice()
|
||
|
solve(inp)
|
||
|
}
|
||
|
|
||
|
func solve(input []string) {
|
||
|
var p1result, p2result int
|
||
|
for i := range input {
|
||
|
s := NewSeq(i, input[i])
|
||
|
s.stabilize()
|
||
|
s.predict()
|
||
|
v2, v1 := s.value()
|
||
|
p1result += v1
|
||
|
p2result += v2
|
||
|
}
|
||
|
fmt.Println("# Part 1")
|
||
|
fmt.Println(p1result)
|
||
|
fmt.Println()
|
||
|
fmt.Println("# Part 2")
|
||
|
fmt.Println(p2result)
|
||
|
}
|
||
|
|
||
|
type Seq struct {
|
||
|
row int
|
||
|
history [][]int
|
||
|
}
|
||
|
|
||
|
func NewSeq(row int, input string) *Seq {
|
||
|
s := Seq{row: row}
|
||
|
pts := strings.Fields(input)
|
||
|
first := []int{}
|
||
|
for i := range pts {
|
||
|
first = append(first, h.Atoi(pts[i]))
|
||
|
}
|
||
|
s.history = append(s.history, first)
|
||
|
return &s
|
||
|
}
|
||
|
|
||
|
func (s *Seq) value() (int, int) {
|
||
|
return s.history[0][0], s.history[0][len(s.history[0])-1]
|
||
|
}
|
||
|
func (s *Seq) predict() {
|
||
|
s.history[len(s.history)-1] = append(s.history[len(s.history)-1], 0)
|
||
|
s.history[len(s.history)-1] = append([]int{0}, s.history[len(s.history)-1]...)
|
||
|
if len(s.history) > 1 {
|
||
|
for i := len(s.history) - 2; i >= 0; i-- {
|
||
|
nV := s.history[i][len(s.history[i])-1] + s.history[i+1][len(s.history[i+1])-1]
|
||
|
s.history[i] = append(s.history[i], nV)
|
||
|
|
||
|
// And now go backwards
|
||
|
pV := s.history[i][0] - s.history[i+1][0]
|
||
|
s.history[i] = append([]int{pV}, s.history[i]...)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *Seq) stabilize() {
|
||
|
for !s.isStable() {
|
||
|
s.iterate()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *Seq) iterate() {
|
||
|
idx := len(s.history) - 1
|
||
|
l := len(s.history[idx]) - 1
|
||
|
var next []int
|
||
|
for i := range s.history[idx] {
|
||
|
if i < l {
|
||
|
next = append(next, s.history[idx][i+1]-s.history[idx][i])
|
||
|
}
|
||
|
}
|
||
|
s.history = append(s.history, next)
|
||
|
}
|
||
|
|
||
|
func (s *Seq) isStable() bool {
|
||
|
for _, v := range s.history[len(s.history)-1] {
|
||
|
if v != 0 {
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
func (s Seq) String() string {
|
||
|
return fmt.Sprintf("MINE: Row %d Result: %d + %d = %d\n",
|
||
|
s.row,
|
||
|
s.history[0][len(s.history[0])-2],
|
||
|
s.history[1][len(s.history[1])-1],
|
||
|
s.history[0][len(s.history[0])-1])
|
||
|
}
|
||
|
|
||
|
func (s Seq) Detail() string {
|
||
|
var res string
|
||
|
for i := range s.history {
|
||
|
res = fmt.Sprintf("%s%v\n", res, s.history[i])
|
||
|
}
|
||
|
return res
|
||
|
}
|