%define EXPANSION 1000000-1 global _start [bits 32] [section .text] %include "utils.s" _start: ; find line length mov edi, file mov ecx, file.over - file mov al, 10 ; \n repne scasb mov eax, edi sub eax, file mov [line_len], eax call print_dec call newline mov eax, -1 mov ecx, 512 mov edi, empty_rows rep stosd mov eax, -1 mov ecx, 512*2 mov edi, stars rep stosd ; find empty rows xor ebx, ebx mov ebp, empty_rows check_rows: mov eax, [line_len] mov ecx, eax mul ebx lea edi, [eax+file] mov esi, edi add esi, ecx mov al, '.' repe scasb mov eax, esi cmp edi, esi jne .not_empty .empty: mov [ebp], ebx add ebp, 4 .not_empty: .cont: inc ebx cmp eax, file.over jb check_rows ; find empty cols xor ebx, ebx mov ebp, empty_cols check_cols: lea edi, [file+ebx] .l: cmp edi, file.over jae .empty cmp byte [edi], '.' jne .not_empty add edi, [line_len] jmp .l .empty: mov [ebp], ebx add ebp, 4 .not_empty: inc ebx cmp ebx, [line_len] jb check_cols print_empty_rows: mov esi, empty_str mov ecx, 6 call print_string mov esi, empty_rows xor eax, eax .l: lodsd cmp eax, -1 je .done call space call print_dec jmp .l .done: call newline print_empty_cols: mov esi, empty_str mov ecx, 6 call print_string mov esi, empty_cols xor eax, eax .l: lodsd cmp eax, -1 je .done call space call print_dec jmp .l .done: call newline ; find #s xor ebx, ebx ; row mov ebp, stars find_stars: mov eax, ebx mul dword [line_len] lea edi, [file+eax] ; row ptr cmp edi, file.over jae .done xor ecx, ecx ; col .for_cols: cmp byte [edi+ecx], '#' jne .for_cols_cont mov eax, ebx call print_dec call space mov [ebp], ebx ; row mov eax, ecx call print_dec call newline mov [ebp+4], ecx ; col add ebp, 8 .for_cols_cont: inc ecx cmp ecx, [line_len] jb .for_cols inc ebx jmp find_stars .done: call newline ; calc adjustments calc_adj: xor ecx, ecx .fill: mov [adj_rows+ecx*4], ecx mov [adj_cols+ecx*4], ecx inc ecx cmp ecx, 256 jb .fill ; do rows mov esi, empty_rows .rows: lodsd cmp eax, -1 je .rows_done inc eax .add_to_rows: add dword [adj_rows+eax*4], EXPANSION inc eax cmp eax, 256 jb .add_to_rows jmp .rows .rows_done: ; do cols mov esi, empty_cols .cols: lodsd cmp eax, -1 je .cols_done inc eax .add_to_cols: add dword [adj_cols+eax*4], EXPANSION inc eax cmp eax, 256 jb .add_to_cols jmp .cols .cols_done: ; apply adjustments apply_adj: xor eax, eax mov esi, stars mov edi, stars .l: lodsd ; row cmp eax, -1 je .done mov eax, [adj_rows+eax*4] stosd lodsd ; col mov eax, [adj_cols+eax*4] stosd jmp .l .done: ; print stars print_stars: mov esi, stars xor eax, eax .l: lodsd cmp eax, -1 je .done call print_dec call space lodsd call print_dec call newline jmp .l .done: call newline ; calc distances sub esp, 4 mov ebp, stars calc_dist: lea esi, [ebp+8] mov ecx, [ebp] ; row mov edx, [ebp+4] ; col mov [esp], ebp xor edi, edi ; running sum low xor ebp, ebp ; running sum high .to_next: lodsd ; row cmp eax, -1 je .all_added sub eax, ecx ; abs (m := n>>31, n := (n+m)^m) mov ebx, eax sar ebx, 31 add eax, ebx xor eax, ebx ; add to total add edi, eax adc ebp, 0 lodsd ; col sub eax, edx mov ebx, eax sar ebx, 31 add eax, ebx xor eax, ebx ; add to total add edi, eax adc ebp, 0 jmp .to_next .all_added: add dword [final_value], edi adc dword [final_value_high], ebp calc_dist_cont: mov ebp, [esp] add ebp, 8 cmp dword [ebp], -1 jne calc_dist calc_dist_end: add esp, 4 game_over: ; answer is penultimate + (ultimate * 2^32) mov eax, [final_value] call print_dec call newline mov eax, [final_value_high] call print_dec call newline jmp exit [section .data] line_len: dd 0 final_value: dd 0 final_value_high: dd 0 file: incbin "input" .over: empty_str: db "Empty:" not_empty_str: db "Not Empty:" [section .bss] empty_rows: resd 256 empty_cols: resd 256 adj_rows: resd 256 adj_cols: resd 256 stars: resd 512*2