From f7de9624d76ba02dc5d4063d529178d93cc608f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20M=C3=A5rdbrink?= Date: Thu, 4 Dec 2025 21:33:18 +0100 Subject: [PATCH] Day 4 --- d04/main.odin | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 d04/main.odin diff --git a/d04/main.odin b/d04/main.odin new file mode 100644 index 0000000..4a2d118 --- /dev/null +++ b/d04/main.odin @@ -0,0 +1,118 @@ +package main + +import "core:container/queue" +import "core:fmt" +import "core:math" +import "core:os" +import "core:slice" +import "core:strconv" +import "core:strings" +import "core:time" +import "core:unicode/utf8" + +import util "../util" + +Vec2 :: [2]int + +in_bounds :: proc(pos: Vec2, lines: ^[][]u8) -> bool { + return pos.x >= 0 && pos.x < len(lines[0]) && pos.y >= 0 && pos.y < len(lines) +} + +part_1 :: proc(lines: ^[][]u8) { + result: i64 = 0 + directions := [8]Vec2{{0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}} + + for line, y in lines { + for ch, x in line { + if ch != '@' do continue + + adj_paperroll := 0 + pos := Vec2{x, y} + + for dir in directions { + adj_pos := pos + dir + if in_bounds(adj_pos, lines) { + adj_ch := lines[adj_pos.y][adj_pos.x] + if adj_ch == '@' do adj_paperroll += 1 + } + } + + if adj_paperroll < 4 do result += 1 + } + } + + fmt.printfln(" [Result] %v", result) +} + +count_rolls :: proc(lines: ^[][]u8) -> (acc: int) { + for line in lines { + for ch in line do if ch == '@' do acc += 1 + } + return +} + +part_2 :: proc(lines: ^[][]u8) { + result := 0 + directions := [8]Vec2{{0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}} + to_remove := make([dynamic]Vec2) + + mutable_lines := make([][]u8, len(lines)) + for line, i in lines { + mutable_lines[i] = slice.clone(line) + } + + rolls := count_rolls(&mutable_lines) + for true { + for line, y in mutable_lines { + for ch, x in line { + if ch != '@' do continue + + adj_paperroll := 0 + pos := Vec2{x, y} + + for dir in directions { + adj_pos := pos + dir + if in_bounds(adj_pos, &mutable_lines) { + adj_ch := mutable_lines[adj_pos.y][adj_pos.x] + if adj_ch == '@' do adj_paperroll += 1 + } + } + + if adj_paperroll < 4 do append(&to_remove, pos) + } + } + for pos in to_remove do mutable_lines[pos.y][pos.x] = '.' + result += len(to_remove) + clear(&to_remove) + new_rolls := count_rolls(&mutable_lines) + + if new_rolls == rolls do break + else do rolls = new_rolls + } + + fmt.printfln(" [Result] %v", result) +} + +main :: proc() { + context.allocator = context.temp_allocator + defer free_all(context.temp_allocator) + + INPUT :: #load("input.txt") + lines := strings.split_lines(string(INPUT)) + lines = lines[:len(lines) - 1] + + byte_lines := make([][]u8, len(lines)) + for line, i in lines do byte_lines[i] = transmute([]u8)line + + fmt.println("[Part 1]") + start := time.tick_now() + part_1(&byte_lines) + duration := time.tick_diff(start, time.tick_now()) + fmt.printfln(" [Time] %fms\n", time.duration_milliseconds(duration)) + + fmt.printfln("[Part 2]") + start = time.tick_now() + part_2(&byte_lines) + duration = time.tick_diff(start, time.tick_now()) + fmt.printfln(" [Time] %fms", time.duration_milliseconds(duration)) +}