100 lines
1.8 KiB
Go
100 lines
1.8 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"regexp"
|
||
|
"strings"
|
||
|
|
||
|
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
inp := helpers.StdinToString()
|
||
|
part1(inp)
|
||
|
part2(inp)
|
||
|
}
|
||
|
|
||
|
func part1(inp string) {
|
||
|
mulCmds := regexp.MustCompile(`mul\(\d\d?\d?,\d\d?\d?\)`)
|
||
|
cmds := mulCmds.FindAllString(inp, -1)
|
||
|
var total int
|
||
|
for _, v := range cmds {
|
||
|
var num1, num2 int
|
||
|
fmt.Sscanf(v, "mul(%d,%d)", &num1, &num2)
|
||
|
total = total + (num1 * num2)
|
||
|
}
|
||
|
fmt.Println("# Part 1")
|
||
|
fmt.Printf("Total: %d\n\n", total)
|
||
|
}
|
||
|
|
||
|
func part2(inp string) {
|
||
|
var total int
|
||
|
do, run := true, true
|
||
|
for run {
|
||
|
var cmd Command
|
||
|
prev := inp
|
||
|
cmd, inp = getNextCommand(inp)
|
||
|
if prev == inp {
|
||
|
panic("Remainder didn't change")
|
||
|
}
|
||
|
run = len(inp) > 0
|
||
|
switch cmd.Name {
|
||
|
case "mul":
|
||
|
if do {
|
||
|
total = total + cmd.Run()
|
||
|
}
|
||
|
case "do":
|
||
|
do = true
|
||
|
case "don't":
|
||
|
do = false
|
||
|
}
|
||
|
}
|
||
|
fmt.Println("# Part 2")
|
||
|
fmt.Printf("Total: %d\n", total)
|
||
|
}
|
||
|
|
||
|
type Command struct {
|
||
|
Name string
|
||
|
Values []int
|
||
|
}
|
||
|
|
||
|
func (c *Command) Run() int {
|
||
|
if c.Name == "mul" {
|
||
|
return c.Values[0] * c.Values[1]
|
||
|
}
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
func (c Command) String() string {
|
||
|
switch c.Name {
|
||
|
case "mul":
|
||
|
return fmt.Sprintf("%s(%d,%d)", c.Name, c.Values[0], c.Values[1])
|
||
|
default:
|
||
|
return fmt.Sprintf("%s()", c.Name)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func getNextCommand(inp string) (Command, string) {
|
||
|
c := Command{
|
||
|
Values: make([]int, 2),
|
||
|
}
|
||
|
for i := range inp {
|
||
|
switch inp[i] {
|
||
|
case 'm':
|
||
|
if _, err := fmt.Sscanf(inp[i:], "mul(%d,%d)", &c.Values[0], &c.Values[1]); err == nil {
|
||
|
c.Name = "mul"
|
||
|
return c, inp[i+len(c.String()):]
|
||
|
}
|
||
|
case 'd':
|
||
|
if strings.HasPrefix(inp[i:], "do()") {
|
||
|
c.Name = "do"
|
||
|
return c, strings.TrimPrefix(inp[i:], "do()")
|
||
|
} else if strings.HasPrefix(inp[i:], "don't()") {
|
||
|
c.Name = "don't"
|
||
|
return c, strings.TrimPrefix(inp[i:], "don't()")
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return Command{}, ""
|
||
|
}
|