130 lines
2.4 KiB
Go
130 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
|
|
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
|
)
|
|
|
|
var rgx = regexp.MustCompile(`\([0-9\*\+ ]*\)`)
|
|
|
|
const (
|
|
LtoR = iota
|
|
AthenM
|
|
)
|
|
|
|
func main() {
|
|
fmt.Println("# Day 18")
|
|
fmt.Println()
|
|
inp := h.StdinToStringSlice()
|
|
fmt.Println("## Part1\nAnswer:", sum(inp, LtoR))
|
|
fmt.Println("## Part2\nAnswer:", sum(inp, AthenM))
|
|
}
|
|
|
|
func sum(inp []string, algo int) int {
|
|
var ret int
|
|
for k := range inp {
|
|
ret = ret + solve(inp[k], algo)
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func solve(inp string, algo int) int {
|
|
var total int
|
|
rs := rgx.FindString(inp)
|
|
if rs == "" {
|
|
// no parentheticals
|
|
total = evaluateLine(inp, algo)
|
|
} else {
|
|
for rs != "" {
|
|
repl := evaluateLine(rs[1:len(rs)-1], algo)
|
|
inp = strings.Replace(inp, rs, h.Itoa(repl), -1)
|
|
rs = rgx.FindString(inp)
|
|
}
|
|
total = evaluateLine(inp, algo)
|
|
}
|
|
return total
|
|
}
|
|
|
|
func evaluateLine(inp string, algo int) int {
|
|
switch algo {
|
|
case LtoR:
|
|
return evaluateLineLtoR(inp)
|
|
case AthenM:
|
|
return evaluateLineAthenM(inp)
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func evaluateLineLtoR(inp string) int {
|
|
var cnt, total int
|
|
var op string
|
|
// No parentheticals
|
|
pts := strings.Split(inp, " ")
|
|
for k := range pts {
|
|
switch pts[k] {
|
|
case "*", "+":
|
|
op = pts[k]
|
|
default:
|
|
if cnt == 0 {
|
|
total = h.Atoi(pts[k])
|
|
cnt++
|
|
} else {
|
|
if op == "+" {
|
|
total = total + h.Atoi(pts[k])
|
|
} else {
|
|
total = total * h.Atoi(pts[k])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return total
|
|
}
|
|
|
|
func evaluateLineAthenM(inp string) int {
|
|
// First solve all addition
|
|
inp = evaluateLineAddition(inp)
|
|
inp = evaluateLineMultiplication(inp)
|
|
return h.Atoi(inp)
|
|
}
|
|
|
|
func evaluateLineAddition(inp string) string {
|
|
var newPts []string
|
|
for strings.Contains(inp, "+") {
|
|
pts := strings.Split(inp, " ")
|
|
for k := 0; k < len(pts); k++ {
|
|
if pts[k] == "+" {
|
|
newPts = pts[:k-1]
|
|
newPts = append(newPts, h.Itoa(h.Atoi(pts[k-1])+h.Atoi(pts[k+1])))
|
|
newPts = append(newPts, pts[k+2:]...)
|
|
inp = strings.Join(newPts, " ")
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return inp
|
|
}
|
|
|
|
func evaluateLineMultiplication(inp string) string {
|
|
var newPts []string
|
|
for strings.Contains(inp, "*") {
|
|
pts := strings.Split(inp, " ")
|
|
for k := 0; k < len(pts); k++ {
|
|
if pts[k] == "*" {
|
|
newPts = pts[:k-1]
|
|
newPts = append(newPts, h.Itoa(h.Atoi(pts[k-1])*h.Atoi(pts[k+1])))
|
|
newPts = append(newPts, pts[k+2:]...)
|
|
inp = strings.Join(newPts, " ")
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return inp
|
|
}
|
|
|
|
type Token struct {
|
|
SubTokens []Token
|
|
}
|