-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday19.um
101 lines (83 loc) · 1.88 KB
/
day19.um
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
import "std.um"
fn getline(): str {
line := ""
for true {
c := std::getchar()
if c == '\n' || c == '\0' {
break
}
if c == '\r' {
continue
}
line += c
}
return line
}
fn splitBy*(text: str, by: char): []str {
items := []str{}
last := 0
for i, c in text {
if c == by {
items = append(items, slice(text, last, i))
last = i+1 // Skip the character by adding one.
}
}
items = append(items, slice(text, last))
return items
}
fn startswith*(text: str, prefix: str): bool {
if len(text) < len(prefix) {
return false
}
return slice(text, 0, len(prefix)) == prefix
}
var cache: map[str]int
fn try(sample: str, rules: map[str]bool, maxl: int): int {
count := 0
if validkey(cache, sample) {
return cache[sample]
}
for l := maxl; l > 0; l-- {
if len(sample) < l {
continue
}
if validkey(rules, slice(sample, 0, l)) {
count += try(slice(sample, l), rules, maxl)
}
}
if len(sample) == 0 {
count++
}
cache[sample] = count
return count
}
fn main() {
rules:= []str{}
samples := []str{}
ruleline := splitBy(getline(), ',')
for i in ruleline {
rule := ""
if sscanf(ruleline[i], "%s", &rule) == 1 {
rules = append(rules, rule)
}
}
for sample := ""; scanf("%s", &sample) == 1 {
samples = append(samples, sample)
}
rulemap := map[str]bool{}
maxl := 0
for i, rule in rules {
rulemap[rule] = true
if len(rule) > maxl {
maxl = len(rule)
}
}
part1 := 0
part2 := 0
for i, sample in samples {
count := try(sample, rulemap, maxl)
part1 += int(count > 0)
part2 += count
}
printf("Part 1: %v\nPart 2: %v\n", part1, part2)
}