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/day7.asm | 302 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 2025/day7.asm (limited to '2025/day7.asm') diff --git a/2025/day7.asm b/2025/day7.asm new file mode 100644 index 0000000..1d990a7 --- /dev/null +++ b/2025/day7.asm @@ -0,0 +1,302 @@ +; Advent of Code 2025 - Day 7 + +bits 64 +default rel + +global _start + +%include "utils/io.asm" + +%define RAW_SIZE 1048576 +%define MAX_W 1024 +%define MAX_H 1024 +%define GRID_SIZE (MAX_W * MAX_H) + +section .data + input_path db "input/day7.txt", 0 + + label1 db "Part 1: ", 0 + label2 db "Part 2: ", 0 + +section .bss + raw resb RAW_SIZE + grid resb GRID_SIZE ; height x width, '.'-filled + g resq (MAX_W * MAX_H) ; part 2 timeline counts + cur resb MAX_W ; part 1 active columns (this row) + nxt resb MAX_W ; part 1 active columns (next row) + + raw_len resq 1 + width resq 1 + height resq 1 + srow resq 1 + scol resq 1 + + 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 + + ; width = length of the first line + xor rcx, rcx +width_scan: + cmp rcx, [raw_len] + jge width_done + mov al, [raw + rcx] + cmp al, 10 + je width_done + cmp al, 13 + je width_done + inc rcx + jmp width_scan +width_done: + mov [width], rcx + + ; height = number of lines + xor rcx, rcx + xor r8, r8 +height_scan: + cmp rcx, [raw_len] + jge height_tail + mov al, [raw + rcx] + cmp al, 10 + jne height_next + inc r8 +height_next: + inc rcx + jmp height_scan +height_tail: + mov rax, [raw_len] + test rax, rax + jz height_store + mov dl, [raw + rax - 1] + cmp dl, 10 + je height_store + inc r8 +height_store: + mov [height], r8 + + ; '.'-fill the grid, then copy the raw bytes into it + mov rax, [height] + imul rax, [width] + mov rcx, rax + lea rdi, [grid] + mov al, '.' + rep stosb + + xor r8, r8 ; raw index + xor r9, r9 ; row + xor r10, r10 ; col +fill_loop: + cmp r8, [raw_len] + jge fill_done + mov al, [raw + r8] + inc r8 + cmp al, 10 + je fill_newline + cmp al, 13 + je fill_loop + cmp r10, [width] + jge fill_loop + mov rdx, r9 + imul rdx, [width] + add rdx, r10 + mov [grid + rdx], al + inc r10 + jmp fill_loop +fill_newline: + inc r9 + xor r10, r10 + jmp fill_loop +fill_done: + + ; locate S + xor r8, r8 + mov rax, [height] + imul rax, [width] + mov r9, rax +find_s: + cmp r8, r9 + jge s_done + mov al, [grid + r8] + cmp al, 'S' + je s_found + inc r8 + jmp find_s +s_found: + mov rax, r8 + xor rdx, rdx + div qword [width] + mov [srow], rax + mov [scol], rdx +s_done: + + ; part 1: flood a set of active columns, counting splitter hits + lea rdi, [cur] + mov rcx, MAX_W + xor al, al + rep stosb + mov rax, [scol] + mov byte [cur + rax], 1 + + xor r15, r15 ; row +p1_row: + cmp r15, [height] + jge p1_done + lea rdi, [nxt] + mov rcx, MAX_W + xor al, al + rep stosb + + mov rax, r15 + imul rax, [width] + mov r14, rax ; row offset + xor r13, r13 ; col + xor r12, r12 ; any beam alive? +p1_col: + cmp r13, [width] + jge p1_col_done + mov al, [cur + r13] + test al, al + jz p1_next + mov rdx, r14 + add rdx, r13 + mov al, [grid + rdx] + cmp al, '^' + jne p1_pass + inc qword [part1] + mov rbx, r13 ; left neighbor + test rbx, rbx + jz p1_no_left + dec rbx + mov byte [nxt + rbx], 1 + mov r12, 1 +p1_no_left: + mov rbx, r13 ; right neighbor + inc rbx + cmp rbx, [width] + jge p1_no_right + mov byte [nxt + rbx], 1 + mov r12, 1 +p1_no_right: + jmp p1_next +p1_pass: + mov byte [nxt + r13], 1 + mov r12, 1 +p1_next: + inc r13 + jmp p1_col +p1_col_done: + lea rsi, [nxt] + lea rdi, [cur] + mov rcx, MAX_W + rep movsb + test r12, r12 + jz p1_done + inc r15 + jmp p1_row +p1_done: + + ; part 2: bottom-up DP of timeline counts, g[r][c] + mov r15, [height] + dec r15 ; row, counting down +p2_row: + cmp r15, 0 + jl p2_done + mov rax, r15 + imul rax, [width] + mov r14, rax ; row offset + xor r13, r13 ; col +p2_col: + cmp r13, [width] + jge p2_col_done + mov rdx, r14 + add rdx, r13 ; idx = r*W + c + mov al, [grid + rdx] + cmp al, '^' + je p2_split + + ; pass straight down: g = (r+1 in grid ? g[r+1][c] : 1) + mov rbx, r15 + inc rbx + cmp rbx, [height] + jge p2_pass_exit + mov rcx, rdx + add rcx, [width] + mov rax, [g + rcx*8] + jmp p2_store +p2_pass_exit: + mov rax, 1 + jmp p2_store + +p2_split: + ; left child enters (r+1, c-1) + mov rbx, r15 + inc rbx + cmp rbx, [height] + jge p2_left_one + cmp r13, 0 + jle p2_left_one + mov rcx, rdx + add rcx, [width] + dec rcx + mov r8, [g + rcx*8] + jmp p2_left_done +p2_left_one: + mov r8, 1 +p2_left_done: + ; right child enters (r+1, c+1) + mov rbx, r15 + inc rbx + cmp rbx, [height] + jge p2_right_one + mov rbx, r13 + inc rbx + cmp rbx, [width] + jge p2_right_one + mov rcx, rdx + add rcx, [width] + inc rcx + mov r9, [g + rcx*8] + jmp p2_right_done +p2_right_one: + mov r9, 1 +p2_right_done: + mov rax, r8 + add rax, r9 +p2_store: + mov [g + rdx*8], rax + inc r13 + jmp p2_col +p2_col_done: + dec r15 + jmp p2_row +p2_done: + mov rax, [srow] + imul rax, [width] + add rax, [scol] + mov rax, [g + rax*8] + mov [part2], rax + +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 -- cgit v1.3