diff --git a/day3.go b/day3.go new file mode 100644 index 0000000..25da426 --- /dev/null +++ b/day3.go @@ -0,0 +1,142 @@ +package main + +import ( + "strconv" + "strings" +) + +type Day3Mul struct { + size int + number1 int + number2 int +} + +func Day3ParseMulInstruction(text string) *Day3Mul { + max_length := 0 + max_length += 4 // mul( + max_length += 3 // 999 + max_length += 1 // , + max_length += 3 // 999 + max_length += 1 // ) + + if len(text) < 4 { + return nil + } + + if len(text) > max_length { + text = text[:max_length] + } + + if text[0:4] != "mul(" { + return nil + } + + comma_index := strings.IndexRune(text, ',') + if (comma_index == -1) { + return nil + } + + closing_index := strings.IndexRune(text, ')') + if (closing_index == -1) { + return nil + } + + number1_text := text[4:comma_index] + number2_text := text[(comma_index+1):closing_index] + + number1, err := strconv.ParseUint(number1_text, 10, 0) + if err != nil { + return nil + } + if number1 > 999 { + return nil + } + + number2, err := strconv.ParseUint(number2_text, 10, 0) + if err != nil { + return nil + } + if number2 > 999 { + return nil + } + + inst := Day3Mul{ + size: closing_index + 1, + number1: int(number1), + number2: int(number2), + } + + return &inst +} + +func Day3Part1(lines []string) error { + answer := 0 + + for _, line := range lines { + cursor := 0 + for cursor < len(line) { + inst := Day3ParseMulInstruction(line[cursor:]) + if inst != nil { + cursor += inst.size + answer += inst.number1 * inst.number2 + } else { + cursor += 1 + } + } + } + + + println(answer) + + return nil +} + +func Day3StartsWith(haystack string, needle string) bool { + if len(haystack) < len(needle) { + return false + } + + return haystack[:len(needle)] == needle +} + +func Day3Part2(lines []string) error { + answer := 0 + + do_inst := "do()" + dont_inst := "don't()" + + enabled := true + for _, line := range lines { + cursor := 0 + for cursor < len(line) { + rest := line[cursor:] + if Day3StartsWith(rest, do_inst) { + enabled = true + cursor += len(do_inst) + continue + } + + if Day3StartsWith(rest, dont_inst) { + enabled = false + cursor += len(dont_inst) + continue + } + + if enabled { + inst := Day3ParseMulInstruction(rest) + if inst != nil { + cursor += inst.size + answer += inst.number1 * inst.number2 + continue + } + } + + cursor += 1 + } + } + + + println(answer) + + return nil +} diff --git a/main.go b/main.go index 4f7ec9d..ca2d31b 100644 --- a/main.go +++ b/main.go @@ -47,5 +47,11 @@ func main() { } else if part == "2" { Day2Part2(lines) } + } else if day == "3" { + if part == "1" { + Day3Part1(lines) + } else if part == "2" { + Day3Part2(lines) + } } }