Working on 2021 day 18
This commit is contained in:
149
2021/day18/main.go
Normal file
149
2021/day18/main.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToStringSlice()
|
||||
|
||||
var build *SNum
|
||||
for i := range inp {
|
||||
wrk, _ := ParseSNum(inp[i])
|
||||
if build == nil {
|
||||
build = wrk
|
||||
} else {
|
||||
build = build.add(wrk)
|
||||
}
|
||||
}
|
||||
fmt.Println(build)
|
||||
v := build.needsExplode(0)
|
||||
fmt.Println("Needs Explode:", v)
|
||||
v.explode()
|
||||
fmt.Println(build)
|
||||
|
||||
/*
|
||||
full := inp[0]
|
||||
for i := 1; i < len(inp); i++ {
|
||||
full = fmt.Sprintf("[%s,%s]", full, inp[i])
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
type SNum struct {
|
||||
parent, left, right *SNum
|
||||
regular bool
|
||||
value int
|
||||
}
|
||||
|
||||
// ParseSNum returns an SNum and what's left of inp
|
||||
// after it was produced
|
||||
func ParseSNum(inp string) (*SNum, string) {
|
||||
// inp should always start with either a number or a '['
|
||||
var rest string
|
||||
s := SNum{}
|
||||
if inp[0] == '[' {
|
||||
s.regular = false
|
||||
s.left, rest = ParseSNum(inp[1:])
|
||||
s.right, rest = ParseSNum(rest[1:])
|
||||
s.left.parent = &s
|
||||
s.right.parent = &s
|
||||
return &s, rest[1:]
|
||||
} else {
|
||||
s.regular = true
|
||||
var num []byte
|
||||
for i := range inp {
|
||||
if inp[i] >= '0' && inp[i] <= '9' {
|
||||
num = append(num, inp[i])
|
||||
} else {
|
||||
s.value = h.Atoi(string(num))
|
||||
return &s, inp[i:]
|
||||
}
|
||||
}
|
||||
}
|
||||
return &s, rest
|
||||
}
|
||||
|
||||
func (s *SNum) needsExplode(depth int) *SNum {
|
||||
if depth == 4 && !s.regular {
|
||||
return s
|
||||
}
|
||||
if s.regular {
|
||||
return nil
|
||||
}
|
||||
if tst := s.left.needsExplode(depth + 1); tst != nil {
|
||||
return tst
|
||||
} else if tst := s.right.needsExplode(depth + 1); tst != nil {
|
||||
return tst
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SNum) explode() {
|
||||
if s.parent == nil {
|
||||
return
|
||||
}
|
||||
s.parent.addToRegularRightOf(s.right.value, s)
|
||||
s.parent.addToRegularLeftOf(s.left.value, s)
|
||||
}
|
||||
|
||||
func (s *SNum) addToRegularLeftOf(v int, c *SNum) {
|
||||
if s.right.regular {
|
||||
s.right.value += v
|
||||
} else {
|
||||
if s.right != nil && s.right == c {
|
||||
r := s.left.findRightmostRegular()
|
||||
if r != nil {
|
||||
r.value += v
|
||||
}
|
||||
} else if s.left != nil && s.left == c {
|
||||
s.parent.addToRegularLeftOf(v, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SNum) addToRegularRightOf(v int, c *SNum) {
|
||||
if s.left.regular {
|
||||
s.left.value += v
|
||||
} else if s.left != nil && s.left == c {
|
||||
l := s.right.findLeftmostRegular()
|
||||
if l != nil {
|
||||
l.value += v
|
||||
}
|
||||
} else if s.right != nil && s.right == c {
|
||||
s.parent.addToRegularRightOf(v, s)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SNum) contains(n *SNum) bool {
|
||||
return s == n || s.left.contains(n) || s.right.contains(n)
|
||||
}
|
||||
|
||||
func (s *SNum) findRightmostRegular() *SNum {
|
||||
if s.regular {
|
||||
return s
|
||||
}
|
||||
return s.right.findRightmostRegular()
|
||||
}
|
||||
func (s *SNum) findLeftmostRegular() *SNum {
|
||||
if s.regular {
|
||||
return s
|
||||
}
|
||||
return s.left.findLeftmostRegular()
|
||||
}
|
||||
|
||||
func (s *SNum) add(n *SNum) *SNum {
|
||||
return &SNum{
|
||||
left: s,
|
||||
right: n,
|
||||
}
|
||||
}
|
||||
|
||||
func (s SNum) String() string {
|
||||
if s.regular {
|
||||
return fmt.Sprintf("%d", s.value)
|
||||
}
|
||||
return fmt.Sprintf("[%s,%s]", s.left, s.right)
|
||||
}
|
||||
Reference in New Issue
Block a user