summaryrefslogtreecommitdiff
path: root/day3/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'day3/main.go')
-rw-r--r--day3/main.go97
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
+}