AdventOfCode2021/18/main.go

226 lines
3.3 KiB
Go

package main
import (
"bufio"
"fmt"
"os"
"strconv"
"time"
)
func mustAtoi(line rune) int {
i, _ := strconv.Atoi(string(line))
return i
}
func main() {
start := time.Now()
partOne()
duration := time.Since(start)
partTwo()
duration2 := time.Since(start)
fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration)
}
func makeScanner(test bool) *bufio.Scanner {
var f *os.File
if test {
f, _ = os.Open("inputs/testinput")
} else {
f, _ = os.Open("inputs/input")
}
reader := bufio.NewReader(f)
return bufio.NewScanner(reader)
}
type pair struct {
parent *pair
leftp *pair
left int
rightp *pair
right int
}
func Parse(raw string) *pair {
root := &pair{}
var current *pair
left := true
for _, v := range raw {
switch v {
case '[':
if current == nil {
current = root
} else {
p := &pair{parent: current}
if left {
current.leftp = p
} else {
current.rightp = p
}
current = p
}
left = true
case ']':
current = current.parent
case ',':
left = false
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
if left {
current.left = mustAtoi(v)
} else {
current.right = mustAtoi(v)
}
case ' ':
continue
default:
panic("what the: " + string(v))
}
}
return root
}
func (p *pair) String() string {
var left, right string
if p.leftp == nil {
left = fmt.Sprintf("%d", p.left)
} else {
left = p.leftp.String()
}
if p.rightp == nil {
right = fmt.Sprintf("%d", p.right)
} else {
right = p.rightp.String()
}
return fmt.Sprintf("[%s,%s]", left, right)
}
func (p *pair) Magnitude() int {
left := 0
right := 0
if p.leftp == nil {
left = p.left
} else {
left = p.leftp.Magnitude()
}
if p.rightp == nil {
right = p.right
} else {
right = p.rightp.Magnitude()
}
return left*3 + right*2
}
func Add(left, right *pair) *pair {
return &pair{
leftp: left,
rightp: right,
}
}
func Reduce(p *pair) {
for {
if MustExplode(0, p) {
Explode(p)
} else if MustSplit(p) {
Split(p)
} else {
break
}
}
}
func Split(p *pair) bool {
if p.left > 9 {
p.leftp = &pair{
left: p.left / 2,
right: (p.left / 2) + (p.left % 2),
}
p.left = 0
return true
}
if p.leftp != nil {
m := Split(p.leftp)
if m {
return true
}
}
if p.right > 9 {
p.rightp = &pair{
left: p.right / 2,
right: (p.right / 2) + (p.right % 2),
}
p.right = 0
return true
}
if p.rightp != nil {
m := Split(p.rightp)
if m {
return true
}
}
return false
}
func MustSplit(p *pair) bool {
if p.left > 9 || p.right > 9 {
return true
}
if p.leftp != nil {
m := MustSplit(p.leftp)
if m {
return true
}
}
if p.rightp != nil {
m := MustSplit(p.rightp)
if m {
return true
}
}
return false
}
func MustExplode(depth int, p *pair) bool {
if depth >= 4 {
return true
}
if p.leftp != nil {
m := MustExplode(depth+1, p.leftp)
if m {
return true
}
}
if p.rightp != nil {
m := MustExplode(depth+1, p.rightp)
if m {
return true
}
}
return false
}
func Explode(p *pair) {
}
func partOne() {
scanner := makeScanner(false)
scanner.Scan()
line := scanner.Text()
total := Parse(line)
for scanner.Scan() {
line := scanner.Text()
total = Add(total, Parse(line))
}
fmt.Println(total)
}
func partTwo() {
scanner := makeScanner(false)
for scanner.Scan() {
// line := scanner.Text()
}
}