%define BUFF_LIM 32768 ;%define GRID_X 10 ;%define GRID_Y 10 %define GRID_X 140 %define GRID_Y 140 global _start [bits 32] [section .text] %include "utils.s" _start: mov ebx, filename call open_file mov ecx, read_buff mov edx, BUFF_LIM call read_file add eax, read_buff mov [file_lim], eax ; 1. read file into array, ; padding edges by 1 read_to_array: mov esi, read_buff ; first line padded by . mov edi, array mov ecx, (GRID_X+2) mov al, '.' rep stosb mov ecx, GRID_Y ; line count .read_lines: ; 1 char pad before line mov al, '.' stosb push ecx .read_chars: mov ecx, GRID_X ; line len (discluding newline) rep movsb ; copy line inc esi ; skip newline mov al, '.' stosb ; pad with . pop ecx loop .read_lines ; fill last line with . mov ecx, (GRID_X+2) mov al, '.' rep stosb ; 2. find numbers, putting indexes ; into numbers array in the index array find_numbers: push 1 ; current number index xor ecx, ecx ; index .find_next: ; check for end of array cmp ecx, (GRID_X+2)*(GRID_Y*2) jge .done lea esi, [ecx+array] ; current char mov edi, esi ; number start if num call dec_parse jnc .has_num ; no number inc ecx jmp .find_next .has_num: sub esi, edi ; get number char length add esi, ecx ; add to index dec esi ; write to index and to numbers pop ebx ; cur num idx mov [numbers+ebx*4], eax ; save number value .write_idx: mov [index+ecx*2], bx ; overwrite digits with . mov byte [array+ecx], '.' inc ecx cmp ecx, esi jl .write_idx inc ecx ; push new cur num idx inc ebx push ebx jmp .find_next .done: add esp, 4 ; no more cur num idx ; 3. go through array, checking the neighbors of ; numbers for symbols, skip *last added index*, ; if has * as neighbor, replace the index of the * ; with the current number index if it has no index currently, ; otherwise multiply by the number its index points to ; and add to final_value, setting last added index to current index check_neighbors: xor ecx, ecx ; index dec ecx ; gets incremented immediately xor ebx, ebx ; last added idx mov esi, array mov edi, index .check_next_number: ; check for end of array inc ecx cmp ecx, (GRID_X+2)*(GRID_Y*2) jge .done ; check if num movzx eax, word [index+ecx*2] test eax, eax jz .check_next_number .found_num: ; check if last added idx cmp eax, ebx je .check_next_number ; is last added idx, skip .check_symbols: lea edx, [ecx+array] ; current char ; right lea ebp, [ecx+1] cmp byte [edx+1], '*' je .has_sym_neighbor ; left lea ebp, [ecx-1] cmp byte [edx-1], '*' je .has_sym_neighbor ; top lea ebp, [ecx-(GRID_X+2)] cmp byte [edx-(GRID_X+2)], '*' je .has_sym_neighbor ; bottom lea ebp, [ecx+(GRID_X+2)] cmp byte [edx+(GRID_X+2)], '*' je .has_sym_neighbor ; top left lea ebp, [ecx-((GRID_X+2)+1)] cmp byte [edx-((GRID_X+2)+1)], '*' je .has_sym_neighbor ; top right lea ebp, [ecx-((GRID_X+2)-1)] cmp byte [edx-((GRID_X+2)-1)], '*' je .has_sym_neighbor ; bottom left lea ebp, [ecx+((GRID_X+2)-1)] cmp byte [edx+((GRID_X+2)-1)], '*' je .has_sym_neighbor ; bottom right lea ebp, [ecx+((GRID_X+2)+1)] cmp byte [edx+((GRID_X+2)+1)], '*' je .has_sym_neighbor ; there's no symbol neighbor ; get next number jmp .check_next_number .has_sym_neighbor: ; we have a symbol neighbor! ; get its id movzx edx, word [index+ebp*2] test edx, edx jz .no_sym_number ; * doesn't have a number assigned yet ; multiply by its number! pushad ; out of registers lol mov eax, [numbers+eax*4] ; our number mul dword [numbers+edx*4] ; * number ; add to final value add [final_value], eax popad ; get back values :3 ; set last added idx mov ebx, eax ; get next number jmp .check_next_number .no_sym_number: ; save our index in the * index mov [index+ebp*2], ax ; set last added idx mov ebx, eax ; get next number jmp .check_next_number .done: ; we can print final value mov eax, [final_value] call print_dec jmp exit [section .data] file_lim: dd 0 final_value: dd 0 filename: db "input",0 [section .bss] numbers: resd 2048 array: resb (GRID_X+2)*(GRID_Y*2) index: resw (GRID_X+2)*(GRID_Y*2) read_buff: resb BUFF_LIM