-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
120 lines (93 loc) · 2.28 KB
/
main.go
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package main
import (
"flag"
"fmt"
"regexp"
"github.com/itsluketwist/advent-of-code-2023/utils"
)
const Day = 8
func main() {
part := flag.Int("part", 0, "Which parts to try?")
try := flag.Int("try", 0, "Whether to try the real input?")
flag.Parse()
fmt.Println("Running day", Day, "( part:", *part, ", try:", *try, ")")
exampleOne, _ := utils.ReadFileToArray(Day, "example1", false)
exampleTwo, _ := utils.ReadFileToArray(Day, "example2", false)
input, _ := utils.ReadFileToArray(Day, "input", false)
if *part == 0 || *part == 1 {
solutionOneExample := SolvePartOne(exampleOne)
fmt.Println("Solution to part 1 (example):", solutionOneExample)
if *try == 1 {
SolutionOneInput := SolvePartOne(input)
fmt.Println("Solution to part 1 (input):", SolutionOneInput)
}
}
if *part == 0 || *part == 2 {
SolutionTwoExample := SolvePartTwo(exampleTwo)
fmt.Println("Solution to part 2 (example):", SolutionTwoExample)
if *try == 1 {
SolutionTwoInput := SolvePartTwo(input)
fmt.Println("Solution to part 2 (input):", SolutionTwoInput)
}
}
}
func parseData(data []string) map[string][]string {
ruleMap := make(map[string][]string)
for _, line := range data {
regexStr := "^([\\w\\d]+) = \\(([\\w\\d]+), ([\\w\\d]+)\\)$"
re := regexp.MustCompile(regexStr)
match := re.FindSubmatch([]byte(line))
if match != nil {
ruleMap[string(match[1])] = []string{string(match[2]), string(match[3])}
}
}
return ruleMap
}
func SolvePartOne(data []string) int {
path := data[0]
ruleMap := parseData(data)
i := 0
steps := 0
node := "AAA"
for {
if path[i] == 'L' {
node = ruleMap[node][0]
} else if path[i] == 'R' {
node = ruleMap[node][1]
}
i = (i + 1) % len(path)
steps++
if node == "ZZZ" {
return steps
}
}
}
func SolvePartTwo(data []string) int {
path := data[0]
ruleMap := parseData(data)
var nodes []string
for node := range ruleMap {
if node[2] == 'A' {
nodes = append(nodes, node)
}
}
var cycleLen []int
for _, node := range nodes {
i := 0
steps := 0
for {
if path[i] == 'L' {
node = ruleMap[node][0]
} else if path[i] == 'R' {
node = ruleMap[node][1]
}
i = (i + 1) % len(path)
steps++
if node[2] == 'Z' {
cycleLen = append(cycleLen, steps)
break
}
}
}
return utils.LCM(cycleLen)
}