From 054d372a716bca4f628674e524e3d027f6824019 Mon Sep 17 00:00:00 2001 From: hachem Date: Sun, 6 Sep 2026 04:12:25 +0200 Subject: refactor: clean up repository layout --- 2025/day4.asm | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 2025/day4.asm (limited to '2025/day4.asm') diff --git a/2025/day4.asm b/2025/day4.asm new file mode 100644 index 0000000..60e53ec --- /dev/null +++ b/2025/day4.asm @@ -0,0 +1,236 @@ +; Advent of Code 2025 - Day 4 + +bits 64 +default rel + +global _start + +%include "utils/io.asm" + +%define RAW_SIZE 4194304 ; 4 MiB scratch for the raw file +%define GRID_SIZE 4194304 ; 4 MiB for the padded grid / mark buffers + +section .data + input_path db "input/day4.txt", 0 + + label1 db "Part 1: ", 0 + label2 db "Part 2: ", 0 + +section .bss + raw resb RAW_SIZE ; raw file bytes + grid resb GRID_SIZE ; padded grid: 1 = roll, 0 = empty + mark resb GRID_SIZE ; per-round removal marks + + raw_len resq 1 + width resq 1 ; real columns per row + height resq 1 ; real rows + stride resq 1 ; width + 2 (padding on both sides) + + part1 resq 1 + part2 resq 1 + +section .text + +_start: + mov rdi, input_path + lea rsi, [raw] + mov rdx, RAW_SIZE + call read_file + mov [raw_len], rax + + xor rcx, rcx ; column scanner +width_scan: + cmp rcx, [raw_len] + jge width_done + mov al, [raw + rcx] + cmp al, 13 ; CR + je width_done + cmp al, 10 ; LF + je width_done + inc rcx + jmp width_scan +width_done: + mov [width], rcx + add rcx, 2 ; padding on left + right + mov [stride], rcx + + ; real cell (r, c) lives at grid[(r+1)*stride + (c+1)] + mov r10, [raw_len] + xor r8, r8 ; i (raw index) + xor r9, r9 ; r (row, 0-based) + xor r11, r11 ; c (col, 0-based) +fill_loop: + cmp r8, r10 + jge fill_end + mov al, [raw + r8] + inc r8 + + cmp al, 13 ; CR -> ignore + je fill_loop + cmp al, 10 ; LF -> end of line + je fill_newline + + cmp al, '@' + jne fill_next_col ; '.' leaves the zeroed cell alone + + ; grid[(r9+1)*stride + (r11+1)] = 1 + mov rbx, r9 + inc rbx + imul rbx, [stride] + add rbx, r11 + add rbx, 1 + mov byte [grid + rbx], 1 +fill_next_col: + inc r11 + jmp fill_loop +fill_newline: + cmp r11, 0 ; blank line -> skip (e.g. trailing newline) + je fill_loop + inc r9 + xor r11, r11 + jmp fill_loop +fill_end: + cmp r11, 0 ; last line had no trailing newline + je fill_height + inc r9 +fill_height: + mov [height], r9 + + mov r13, 1 ; row = 1..height +p1_row: + cmp r13, [height] + jg p1_done + mov rbx, r13 + imul rbx, [stride] + inc rbx ; idx of (row, col=1) + mov r12, 1 ; col = 1..width +p1_col: + cmp r12, [width] + jg p1_row_next + movzx eax, byte [grid + rbx] + test eax, eax + jz p1_next ; not a roll + mov rdi, rbx + call count_neighbors + cmp rax, 4 + jge p1_next ; 4 or more neighbors -> blocked + inc qword [part1] +p1_next: + inc rbx + inc r12 + jmp p1_col +p1_row_next: + inc r13 + jmp p1_row +p1_done: + +peel_loop: + mov r13, 1 +mark_row: + cmp r13, [height] + jg mark_done + mov rbx, r13 + imul rbx, [stride] + inc rbx + mov r12, 1 +mark_col: + cmp r12, [width] + jg mark_row_next + movzx eax, byte [grid + rbx] + test eax, eax + jz mark_zero ; empty cell + mov rdi, rbx + call count_neighbors + cmp rax, 4 + jl mark_one ; accessible +mark_zero: + mov byte [mark + rbx], 0 + jmp mark_next +mark_one: + mov byte [mark + rbx], 1 +mark_next: + inc rbx + inc r12 + jmp mark_col +mark_row_next: + inc r13 + jmp mark_row +mark_done: + + xor r11, r11 ; removed this round + mov r13, 1 +apply_row: + cmp r13, [height] + jg apply_done + mov rbx, r13 + imul rbx, [stride] + inc rbx + mov r12, 1 +apply_col: + cmp r12, [width] + jg apply_row_next + movzx eax, byte [mark + rbx] + test eax, eax + jz apply_next + mov byte [grid + rbx], 0 + inc r11 +apply_next: + inc rbx + inc r12 + jmp apply_col +apply_row_next: + inc r13 + jmp apply_row +apply_done: + add [part2], r11 + test r11, r11 + jnz peel_loop ; something changed -> another round + +print_results: + mov rcx, label1 + call print_string + mov rax, [part1] + call print_int64 + call print_newline + + mov rcx, label2 + call print_string + mov rax, [part2] + call print_int64 + call print_newline + + mov rax, SYS_EXIT + xor rdi, rdi + syscall + +; count_neighbors: sum of the 8 cells around a padded index +; Input: RDI = grid index +; Output: RAX = number of neighboring rolls (0..8) +; Clobbers: RAX, RCX, RDX, R8 +count_neighbors: + mov rcx, [stride] + xor eax, eax + + mov rdx, rdi + sub rdx, rcx ; row above + movzx r8d, byte [grid + rdx - 1] + add eax, r8d + movzx r8d, byte [grid + rdx] + add eax, r8d + movzx r8d, byte [grid + rdx + 1] + add eax, r8d + + movzx r8d, byte [grid + rdi - 1] ; same row, sides + add eax, r8d + movzx r8d, byte [grid + rdi + 1] + add eax, r8d + + mov rdx, rdi + add rdx, rcx ; row below + movzx r8d, byte [grid + rdx - 1] + add eax, r8d + movzx r8d, byte [grid + rdx] + add eax, r8d + movzx r8d, byte [grid + rdx + 1] + add eax, r8d + ret -- cgit v1.3