/
d23.odin
104 lines (87 loc) · 2.97 KB
/
d23.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
package aoc
import "core:strings"
import "core:math"
WIDTH :: 2500;
SIZE :: WIDTH*WIDTH;
HALF_WIDTH :: WIDTH/2;
elf_t :: struct {
pos: int,
choice: int,
}
d23 :: proc(content: string) -> (result_t, result_t) {
p1, p2: int;
elves: [dynamic]elf_t;
grid := make([]^elf_t, SIZE);
choice_grid := make([]int, SIZE);
lines := strings.split_lines(content);
for line, y in lines {
byte_line := transmute([]u8)line;
for char, x in byte_line {
if char == '#' {
elf := elf_t{ pos = x + HALF_WIDTH + (y + HALF_WIDTH) * WIDTH, choice = max(int) };
idx := append(&elves, elf);
grid[elf.pos] = &elves[len(elves) - 1];
}
}
}
choice_idx: int;
choices := [][3]int {
{-WIDTH, -WIDTH - 1, -WIDTH + 1},
{WIDTH, WIDTH - 1, WIDTH + 1},
{ -1, -WIDTH - 1, WIDTH - 1},
{ 1, -WIDTH + 1, WIDTH + 1},
};
for i := 0; true; i += 1 {
choice_count := 0;
for _, e_idx in elves {
elf := &elves[e_idx];
if grid[elf.pos-WIDTH-1] == nil && grid[elf.pos-WIDTH] == nil && grid[elf.pos-WIDTH+1] == nil && grid[elf.pos-1] == nil &&
grid[elf.pos+1] == nil && grid[elf.pos+WIDTH-1] == nil && grid[elf.pos+WIDTH] == nil && grid[elf.pos+WIDTH+1] == nil {
continue;
}
for j in 0..<4 {
choice := &choices[(choice_idx + j) % 4];
if grid[elf.pos + choice[0]] == nil && grid[elf.pos + choice[1]] == nil && grid[elf.pos + choice[2]] == nil {
elf.choice = elf.pos + choice[0];
choice_grid[elf.choice] += 1;
choice_count += 1;
break;
}
}
}
if choice_count == 0 {
p2 = i + 1;
break;
}
for _, e_idx in elves {
elf := &elves[e_idx];
if elf.choice != max(int) {
value := choice_grid[elf.choice]
if value == 1 {
grid[elf.pos] = nil;
grid[elf.choice] = elf;
elf.pos = elf.choice;
}
}
}
for _, e_idx in elves {
elf := &elves[e_idx];
if elf.choice != max(int) do choice_grid[elf.choice] = 0;
elf.choice = max(int);
}
if i == 9 {
min_p := vec2{max(int), max(int)};
max_p : vec2;
for elf in elves {
p := vec2{elf.pos % WIDTH, elf.pos / WIDTH};
min_p.x = math.min(min_p.x, p.x);
min_p.y = math.min(min_p.y, p.y);
max_p.x = math.max(max_p.x, p.x);
max_p.y = math.max(max_p.y, p.y);
}
p1 = (max_p.x - min_p.x + 1) * (max_p.y - min_p.y + 1) - len(elves);
}
choice_idx += 1;
}
return p1, p2;
}