diff options
Diffstat (limited to 'day3/main.go')
-rw-r--r-- | day3/main.go | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/day3/main.go b/day3/main.go new file mode 100644 index 0000000..f631d77 --- /dev/null +++ b/day3/main.go @@ -0,0 +1,97 @@ +package main + +import ( + "fmt" + "os" + "strings" +) + +func main() { + content, err := os.ReadFile("data.txt") + if err != nil { + panic(err) + } + + fmt.Println(part1("xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))")) + fmt.Println(part1(string(content))) + + fmt.Println(part2("xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))")) + fmt.Println(part2(string(content))) +} + +func part1(s string) (result int) { + for { + index := strings.Index(s, "mul(") + if index < 0 { + return + } + + s = s[index+4:] + op1, opLength := parseOperand(&s) + if opLength < 1 || opLength > 3 { + continue + } + + if !expectChar(&s, ',') { + continue + } + + op2, opLength := parseOperand(&s) + if opLength < 1 || opLength > 3 { + continue + } + + if !expectChar(&s, ')') { + continue + } + + result += op1 * op2 + } +} + +func part2(s string) (result int) { + for { + dont_index := strings.Index(s, "don't()") + if dont_index < 0 { + result += part1(s) + return + } + + result += part1(s[:dont_index]) + s = s[dont_index+7:] + + do_index := strings.Index(s, "do()") + if do_index < 0 { + return + } + + s = s[do_index+4:] + } + + return +} + +func expectChar(s *string, r byte) bool { + if len(*s) == 0 || (*s)[0] != r { + return false + } else { + *s = (*s)[1:] + return true + } +} + +func parseOperand(s *string) (operand int, length int) { + for len(*s) > 0 { + c := (*s)[0] + + if c < '0' || c > '9' { + return + } + + operand = operand*10 + int(c-'0') + *s = (*s)[1:] + length++ + } + + return +} |