1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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
}
|