-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path11p1.odin
93 lines (79 loc) · 2.22 KB
/
11p1.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
package main
import "core:fmt"
import "core:strconv"
import "core:strings"
D11P1 :: proc() {
input_string := #load("./inputs/11.txt", string)
lines := strings.split(input_string, "\n", context.temp_allocator)
flash_total := get_octopi_energy_flashes(lines, 100)
fmt.printfln("Total flashes after 100 steps: %v", flash_total)
}
get_octopi_energy_flashes :: proc(lines: []string, steps: int) -> int {
energy_levels := parse_octopi_energy_levels(lines)
flashes := 0
for _ in 0 ..< steps {
flashes += simulate_octopus_step(&energy_levels)
}
return flashes
}
parse_octopi_energy_levels :: proc(lines: []string) -> (energy_levels: [10][10]int) {
for line, i in lines {
energy_strings := strings.split(line, "", context.temp_allocator)
for str, j in energy_strings {
energy_levels[i][j] = strconv.atoi(str)
}
}
return
}
simulate_octopus_step :: proc(energy_levels: ^[10][10]int) -> (flashes_in_step: int) {
peak_energy_indexes: [dynamic]Vec2
defer delete(peak_energy_indexes)
for i in 0 ..< 10 {
for j in 0 ..< 10 {
energy_levels[i][j] += 1
if energy_levels[i][j] > 9 {
append(&peak_energy_indexes, Vec2{i, j})
}
}
}
flashes_in_step = simulate_octopus_energy_flash(energy_levels, &peak_energy_indexes)
return
}
simulate_octopus_energy_flash :: proc(
energy_levels: ^[10][10]int,
peak_energy_indexes: ^[dynamic]Vec2,
) -> (
flashes: int,
) {
for len(peak_energy_indexes) > 0 {
current := pop(peak_energy_indexes)
if energy_levels[current.x][current.y] == 0 {
continue
}
energy_levels[current.x][current.y] = 0
flashes += 1
neighbors := []Vec2 {
{current.x - 1, current.y},
{current.x + 1, current.y},
{current.x, current.y - 1},
{current.x, current.y + 1},
{current.x - 1, current.y - 1},
{current.x - 1, current.y + 1},
{current.x + 1, current.y - 1},
{current.x + 1, current.y + 1},
}
for neighbor in neighbors {
// check if neighbor is within bounds
if neighbor.x >= 0 && neighbor.x < 10 && neighbor.y >= 0 && neighbor.y < 10 {
if energy_levels[neighbor.x][neighbor.y] == 0 {
continue
}
energy_levels[neighbor.x][neighbor.y] += 1
if energy_levels[neighbor.x][neighbor.y] > 9 {
append(peak_energy_indexes, neighbor)
}
}
}
}
return
}