2023-12-03 02:11:23 -06:00
|
|
|
%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*,
|
2023-12-03 02:52:09 -06:00
|
|
|
; 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
|
2023-12-03 02:11:23 -06:00
|
|
|
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
|
2023-12-03 02:52:09 -06:00
|
|
|
lea ebp, [ecx+1]
|
|
|
|
cmp byte [edx+1], '*'
|
|
|
|
je .has_sym_neighbor
|
2023-12-03 02:11:23 -06:00
|
|
|
; left
|
2023-12-03 02:52:09 -06:00
|
|
|
lea ebp, [ecx-1]
|
|
|
|
cmp byte [edx-1], '*'
|
|
|
|
je .has_sym_neighbor
|
2023-12-03 02:11:23 -06:00
|
|
|
; top
|
2023-12-03 02:52:09 -06:00
|
|
|
lea ebp, [ecx-(GRID_X+2)]
|
|
|
|
cmp byte [edx-(GRID_X+2)], '*'
|
|
|
|
je .has_sym_neighbor
|
2023-12-03 02:11:23 -06:00
|
|
|
; bottom
|
2023-12-03 02:52:09 -06:00
|
|
|
lea ebp, [ecx+(GRID_X+2)]
|
|
|
|
cmp byte [edx+(GRID_X+2)], '*'
|
|
|
|
je .has_sym_neighbor
|
2023-12-03 02:11:23 -06:00
|
|
|
; top left
|
2023-12-03 02:52:09 -06:00
|
|
|
lea ebp, [ecx-((GRID_X+2)+1)]
|
|
|
|
cmp byte [edx-((GRID_X+2)+1)], '*'
|
|
|
|
je .has_sym_neighbor
|
2023-12-03 02:11:23 -06:00
|
|
|
; top right
|
2023-12-03 02:52:09 -06:00
|
|
|
lea ebp, [ecx-((GRID_X+2)-1)]
|
|
|
|
cmp byte [edx-((GRID_X+2)-1)], '*'
|
|
|
|
je .has_sym_neighbor
|
2023-12-03 02:11:23 -06:00
|
|
|
; bottom left
|
2023-12-03 02:52:09 -06:00
|
|
|
lea ebp, [ecx+((GRID_X+2)-1)]
|
|
|
|
cmp byte [edx+((GRID_X+2)-1)], '*'
|
|
|
|
je .has_sym_neighbor
|
2023-12-03 02:11:23 -06:00
|
|
|
; bottom right
|
2023-12-03 02:52:09 -06:00
|
|
|
lea ebp, [ecx+((GRID_X+2)+1)]
|
|
|
|
cmp byte [edx+((GRID_X+2)+1)], '*'
|
|
|
|
je .has_sym_neighbor
|
2023-12-03 02:11:23 -06:00
|
|
|
; there's no symbol neighbor
|
|
|
|
; get next number
|
|
|
|
jmp .check_next_number
|
|
|
|
.has_sym_neighbor:
|
|
|
|
; we have a symbol neighbor!
|
2023-12-03 02:52:09 -06:00
|
|
|
; 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
|
2023-12-03 02:11:23 -06:00
|
|
|
; add to final value
|
2023-12-03 02:52:09 -06:00
|
|
|
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
|
2023-12-03 02:11:23 -06:00
|
|
|
; 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
|