-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path05p1.odin
105 lines (88 loc) · 2.07 KB
/
05p1.odin
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
package main
import "core:fmt"
import "core:strconv"
import "core:strings"
D05P1 :: proc() {
input_string := #load("inputs/05.txt", string)
lines := strings.split(input_string, "\n", context.temp_allocator)
sum_middle_page_numbers := get_sum_middle_page_numbers(lines)
fmt.printf("Sum of all correct middle page numbers: %d\n", sum_middle_page_numbers)
}
get_sum_middle_page_numbers :: proc(page_ordering_rules: []string) -> int {
sum := 0
rules, updates := parse_page_ordering_rules(page_ordering_rules)
defer {
for _, key in rules {
delete(key)
}
delete(rules)
for update in updates {
delete(update)
}
delete(updates)
}
valid_updates: [dynamic]int
defer delete(valid_updates)
for update, i in updates {
previous_pages: [dynamic]int
defer delete(previous_pages)
is_valid := true
for page in update {
// if any page in rules appears before the rule key, it is not valid
page_rules, ok := rules[page]
if !ok {
append(&previous_pages, page)
continue
}
for previous_page in previous_pages {
for rule in page_rules {
if rule == previous_page {
is_valid = false
break
}
}
}
append(&previous_pages, page)
}
if is_valid {
append(&valid_updates, i)
}
}
for idx in valid_updates {
// get the middle page number of all valid updates
sum += updates[idx][len(updates[idx]) / 2]
}
return sum
}
parse_page_ordering_rules :: proc(
lines: []string,
) -> (
rules: map[int][dynamic]int,
updates: [dynamic][dynamic]int,
) {
updates_start_at: int
for line, i in lines {
if line == "" {
updates_start_at = i + 1
break
}
parts := strings.split(line, "|", context.temp_allocator)
left := strconv.atoi(parts[0])
right := strconv.atoi(parts[1])
rule, ok := rules[left]
if !ok {
rule = [dynamic]int{}
}
append(&rule, right)
rules[left] = rule
}
for line in lines[updates_start_at:] {
parts := strings.split(line, ",", context.temp_allocator)
update := [dynamic]int{}
for part in parts {
append(&update, strconv.atoi(part))
}
append(&updates, update)
}
return
}