most of day 18, just missing the explode logic
This commit is contained in:
parent
3340be88a1
commit
917be0d8f1
182
18/main.go
Normal file
182
18/main.go
Normal file
@ -0,0 +1,182 @@
|
||||
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) *pair {
|
||||
return &pair{} // ???
|
||||
}
|
||||
|
||||
func Split(p *pair) *pair {
|
||||
if p.left > 9 {
|
||||
p.leftp = &pair{
|
||||
left: p.left / 2,
|
||||
right: (p.left / 2) + (p.left % 2),
|
||||
}
|
||||
p.left = 0
|
||||
return p
|
||||
}
|
||||
if p.right > 9 {
|
||||
p.rightp = &pair{
|
||||
left: p.right / 2,
|
||||
right: (p.right / 2) + (p.right % 2),
|
||||
}
|
||||
p.right = 0
|
||||
return p
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
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 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()
|
||||
}
|
||||
}
|
82
18/main_test.go
Normal file
82
18/main_test.go
Normal file
@ -0,0 +1,82 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
cases := []string{
|
||||
"[1,2]",
|
||||
"[[3,2],1]",
|
||||
"[[3,2],[4,5]]",
|
||||
"[[3,2],[[7,8],5]]",
|
||||
"[[1,2],3]",
|
||||
"[9,[8,7]]",
|
||||
"[[1,9],[8,5]]",
|
||||
"[[[[1,2],[3,4]],[[5,6],[7,8]]],9]",
|
||||
"[[[9,[3,8]],[[0,9],6]],[[[3,7],[4,9]],3]]",
|
||||
"[[[[1,3],[5,3]],[[1,3],[8,7]]],[[[4,9],[6,9]],[[8,2],[7,3]]]]",
|
||||
}
|
||||
for _, input := range cases {
|
||||
p := Parse(input)
|
||||
if input != p.String() {
|
||||
t.Log(p.String())
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMustExplode(t *testing.T) {
|
||||
cases := map[string]bool{
|
||||
"[1,2]": false,
|
||||
"[[[[2,4],4],[2,3]],1]": false,
|
||||
"[[[[[4,3],4],4],1],3]": true,
|
||||
"[2,[1,[4,[3,[4,3]]]]]": true,
|
||||
"[[[[0,7],4],[7,[[8,4],9]]],[1,1]]": true,
|
||||
}
|
||||
for input, output := range cases {
|
||||
if MustExplode(0, Parse(input)) != output {
|
||||
t.Log(input)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdd(t *testing.T) {
|
||||
cases := map[string][]*pair{
|
||||
"[[1,2],[[3,4],5]]": {
|
||||
&pair{left: 1, right: 2},
|
||||
&pair{leftp: &pair{left: 3, right: 4}, right: 5},
|
||||
},
|
||||
}
|
||||
for answer, pairs := range cases {
|
||||
r := Add(pairs[0], pairs[1])
|
||||
if r.String() != answer {
|
||||
fmt.Printf("%s %s", r, answer)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMagnitude(t *testing.T) {
|
||||
cases := map[int]*pair{
|
||||
29: {left: 9, right: 1},
|
||||
21: {left: 1, right: 9},
|
||||
129: {
|
||||
leftp: &pair{left: 9, right: 1},
|
||||
rightp: &pair{left: 1, right: 9},
|
||||
},
|
||||
143: {
|
||||
leftp: &pair{left: 1, right: 2},
|
||||
rightp: &pair{leftp: &pair{left: 3, right: 4}, right: 5},
|
||||
},
|
||||
}
|
||||
for answer, pair := range cases {
|
||||
r := pair.Magnitude()
|
||||
if r != answer {
|
||||
fmt.Printf("%d %d", r, answer)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user