Files
aoc2025odin/day4/day4.odin
2025-12-05 23:18:07 -05:00

125 lines
2.5 KiB
Odin

package day4
import "../utils"
import "core:strings"
import "core:testing"
sample :: `..@@.@@@@.
@@@.@.@.@@
@@@@@.@.@@
@.@@@@..@.
@@.@@@@.@@
.@@@@@@@.@
.@.@.@.@@@
@.@@@.@@@@
.@@@@@@@@.
@.@.@@@.@.`
get_surrounding :: proc(lines: []string, x: int, y: int) -> (result: [8]u8) {
i: uint
for dy in -1 ..= 1 {
if y + dy < 0 || y + dy >= len(lines) do continue
for dx in -1 ..= 1 {
if x + dx < 0 || x + dx >= len(lines[0]) do continue
if dy == 0 && dx == 0 {
continue
}
result[i] = lines[y + dy][x + dx]
i += 1
}
}
return
}
solve_first :: proc(s: string) -> u64 {
input := s
num_rolls: u64
lines := strings.split_lines(input)
defer delete(lines)
for y in 0 ..< len(lines) {
for x in 0 ..< len(lines[0]) {
if lines[y][x] != '@' do continue
surrounding := get_surrounding(lines, x, y)
num_surrounding_rolls: uint
for c in surrounding {
if c == '@' do num_surrounding_rolls += 1
if num_surrounding_rolls == 4 do break
}
if num_surrounding_rolls < 4 {
num_rolls += 1
}
}
}
return num_rolls
}
@(test)
solve_first_sample :: proc(t: ^testing.T) {
testing.expect_value(t, solve_first(sample), 13)
}
@(test)
solve_first_puzzle :: proc(t: ^testing.T) {
content := utils.read_file("day4/input.txt")
defer delete(content)
testing.expect_value(t, solve_first(content), 1626)
}
Position :: struct {
x: int,
y: int,
}
get_removable :: proc(lines: []string) -> (positions: [dynamic]Position) {
for y in 0 ..< len(lines) {
for x in 0 ..< len(lines[0]) {
if lines[y][x] != '@' do continue
surrounding := get_surrounding(lines, x, y)
num_surrounding_rolls: uint
for c in surrounding {
if c == '@' do num_surrounding_rolls += 1
if num_surrounding_rolls == 4 do break
}
if num_surrounding_rolls < 4 {
append(&positions, Position{x = x, y = y})
}
}
}
return
}
solve_second :: proc(s: string) -> (total: u64) {
s := strings.clone(s)
defer delete(s)
lines := strings.split_lines(s)
defer delete(lines)
line_len := len(lines[0])
removed := true
for removed {
removed = false
positions := get_removable(lines)
defer delete(positions)
for p in positions {
removed = true
raw_data(lines[p.y])[p.x] = '.'
total += 1
}
}
return
}
@(test)
solve_second_sample :: proc(t: ^testing.T) {
testing.expect_value(t, solve_second(sample), 43)
}
@(test)
solve_second_puzzle :: proc(t: ^testing.T) {
content := utils.read_file("day4/input.txt")
defer delete(content)
testing.expect_value(t, solve_second(content), 9173)
}