From ed24b9e13721ae51e9dcee505ff1b06413e980b5 Mon Sep 17 00:00:00 2001 From: Grant Horner Date: Fri, 5 Dec 2025 23:18:07 -0500 Subject: [PATCH] finish day 4 --- day4/day4.odin | 124 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 day4/day4.odin diff --git a/day4/day4.odin b/day4/day4.odin new file mode 100644 index 0000000..ec5745e --- /dev/null +++ b/day4/day4.odin @@ -0,0 +1,124 @@ +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) +} +