adventofcode/2024/day03/main.go

103 lines
2.0 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)
fmt.Printf("%s -> %d * %d = %d\n", v, num1, num2, 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)
fmt.Println("Processing Command:", cmd)
fmt.Println("Remainder:", 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{}, ""
}