%define BUFF_LIM 32768 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 ; skip until : ; loop until : ; get next number ; save in seeds@seedcnt ; increment seedcnt ; end ; ; get the map tables ; current_map := 0 ; do 7 times ; loop until : ; get next number ; save in tmp ; get next number ; save in ((maps@current_map)@current_line)+4 SRC ; get next number ; save in ((maps@current_map)@current_line)+8 RNG ; tmp := tmp - SRC ; changes DEST to represent *change* in location ; save in ((maps@current_map)@current_line)+0 DEST ; end ; end ; ; for (seed,srng) in seeds ; list_bs@0 := (seed,srng,0) ; listcnt := 1 ; for m in maps ; for (d,s,r) in m ; listi := 0 ; maxs := s + r - 1 ; while listi < listcnt ; (is, ir, mod) := list_bs@listi ; if mod is map .cont ; maxi := is + ir - 1 ; if maxi < s .cont ; if is > maxs .cont ; fr := greater(is, s) ; lr := less(maxi, maxs) ; rr := lr - fr + 1 ; .chk_AE: ; if is < fr ; (list_bs@listi).r := fr - is ; NEWENT(fr + d, rr, map) ; else ; (list_bs@listi).s := fr + d ; (list_bs@listi).r := rr ; (list_bs@listi).mod := map ; end ; .chk_AF: ; if imax > lr ; NEWENT(lr + 1, imax - lr, mod) ; end ; .cont: inc listi ; end ; end ; end ; find smallest ; tmp := final_value ; for (is, _, _) in list_bs ; if is < tmp then tmp := is ; end ; final_value := tmp ; end ; output final_value ; skip until : mov esi, read_buff skip_to_nums: lodsb cmp al, ':' jne skip_to_nums ; loop until : ; get next number ; save in seeds@seedcnt ; increment seedcnt ; end inc esi xor ebx, ebx ; seedcnt get_seeds: cmp byte [esi-1], ':' je .got_seeds call dec_parse jc get_seeds ; save number mov [seeds+ebx*4], eax inc ebx jmp get_seeds .got_seeds: mov [seedcnt], ebx inc esi ; don't retrigger : check ; get the map tables ; current_map := 0 mov dword [current_map], 0 ; do 7 times ; ... ; end mov ecx, 7 process_maps: push ecx ; loop until : ; ... ; end mov edi, [current_map] mov edi, [maps+edi*4] push ebx push ecx push edx map_chk: ; get next number ; save in tmp ; get next number ; save in ((maps@current_map)@current_line)+4 SRC ; get next number ; save in ((maps@current_map)@current_line)+8 RNG ; tmp := tmp - SRC ; changes DEST to represent *change* in location ; save in ((maps@current_map)@current_line)+0 DEST .get_dest: cmp byte [esi-1], ':' ; make sure we aren't passing into new map je .map_done call dec_parse jc .get_dest ; save in tmp mov ebx, eax .get_src: call dec_parse jc .get_src ; save in ((maps@current_map)@current_line)+4 SRC mov ecx, eax .get_rng: call dec_parse jc .get_rng ; save in ((maps@current_map)@current_line)+8 RNG mov edx, eax ; tmp := tmp - SRC ; changes DEST to represent *change* in location ; save in ((maps@current_map)@current_line)+0 DEST sub ebx, ecx mov eax, ebx stosd mov eax, ecx stosd mov eax, edx stosd jmp map_chk .map_done: inc dword [current_map] pop edx pop ecx pop ebx ; process_maps loop inc esi ; skip ':' pop ecx dec ecx test ecx, ecx jnz process_maps ; debug print maps ;mov ecx, 0 ;dbg_maps: ;push ecx ;mov esi, [maps+ecx*4] ;.lines: ;xor ebx, ebx ;lodsd ;add ebx, eax ;call print_dec ;call space ;lodsd ;add ebx, eax ;call print_dec ;call space ;lodsd ;add ebx, eax ;call print_dec ;call newline ;test ebx, ebx ;jnz .lines ;call newline ;inc ecx ;cmp ecx, 7 ;jb dbg_maps ; for (seed,srng) in seeds mov eax, [seedcnt] shr eax, 1 mov esi, seeds for_seeds: push eax ; seed count ; list_bs@0 := (seed,srng,0) ; listcnt := 1 mov edi, list_bs movsd ; seed movsd ; srng push esi ; seed ptr xor eax, eax stosd ; mod mov dword [listcnt], 1 ; for m in maps mov ecx, 0 for_maps: mov ebp, [maps+ecx*4] ; map push ecx ; map idx ; for line in m mov esi, ebp ; line := map@0 sub esp, 32 ; space for 0 ?, 4 ?, 8 map, 12 mod, 16 d, 20 r, 24 lineptr, 28 list counter for_lines: lodsd mov [esp+16], eax ; d lodsd mov edx, eax ; s lodsd mov [esp+20], eax ; r test eax, eax jz for_lines_end ; null entry - we're done mov [esp+24], esi ; lineptr ; maxs := s + r - 1 mov edi, [esp+20] add edi, edx dec edi ; for i in listcnt mov eax, [listcnt] mov [esp+28], eax mov esi, list_bs for_in_list: lodsd mov ecx, eax ; is lodsd mov ebx, eax ; ir lodsd ; mod ; if mod is map continue cmp eax, ebp je for_in_list_cont ; maxi := is + ir - 1 add ebx, ecx ; maxi, ir not needed anymore dec ebx ; if maxi < s .cont ; if is > maxs .cont cmp ebx, edx jb for_in_list_cont cmp ecx, edi ja for_in_list_cont ; make space mov [esp], edi ; maxs mov [esp+4], edx ; s mov [esp+8], ebp ; map mov [esp+12],eax ; mod ; fr := greater(is, s) ; lr := less(maxi, maxs) ; rr := lr - fr + 1 cmp ecx, edx cmova edx, ecx ; edx: fr cmp ebx, edi cmovb edi, ebx ; edi: lr .chk_AE: ; if is < fr cmp ecx, edx jae .chk_AE_else ; (list_bs@listi).r := fr - is mov eax, edx sub eax, ecx mov [esi-8], eax ; NEWENT(fr + d, rr, map) mov eax, [listcnt] shl eax, 1 add eax, [listcnt] lea eax, [list_bs+eax*4] mov [eax+8], ebp ; map mov ebp, edi sub ebp, edx inc ebp mov [eax+4], ebp ; rr add edx, [esp+16] mov [eax], edx ; fr + d inc dword [listcnt] jmp .chk_AF .chk_AE_else: ; else ; (list_bs@listi).mod := map mov [esi-4], ebp ; (list_bs@listi).r := rr mov eax, edi sub eax, edx inc eax mov [esi-8], eax ; (list_bs@listi).s := fr + d add edx, [esp+16] mov [esi-12], edx ; d .chk_AF: ; if imax > lr cmp ebx, edi jbe .chk_AF_not ; NEWENT(lr + 1, maxi - lr, mod) mov eax, [listcnt] shl eax, 1 add eax, [listcnt] lea eax, [list_bs+eax*4] mov edx, [esp+12] mov [eax+8], edx ; mod sub ebx, edi mov [eax+4], ebx ; maxi - lr inc edi mov [eax], edi ; lr + 1 inc dword [listcnt] .chk_AF_not: ; restore mov edi, [esp] ; maxs mov edx, [esp+4] ; s mov ebp, [esp+8] ; map mov eax, [esp+12] ; mod for_in_list_cont: sub dword [esp+28], 1 ; check if done jnz for_in_list ; end for_lines_cont: mov esi, [esp+24] ; lineptr jmp for_lines for_lines_end: add esp, 32 ; restore stack ; end for_maps_cont: pop ecx ; map idx inc ecx cmp ecx, 7 jl for_maps ; end ; find smallest ; tmp := final_value ; for (is, _, _) in list_bs ; if is < tmp then tmp := is ; end ; final_value := tmp mov ebx, [final_value] mov ecx, [listcnt] mov esi, list_bs find_smallest: lodsd cmp eax, ebx cmovb ebx, eax add esi, 8 loop find_smallest mov [final_value], ebx for_seeds_cont: pop esi ; seed ptr pop eax ; seed count sub eax, 1 jnz for_seeds ; loop if not finished ; end ; done processing... at last ;output tmp mov eax, [final_value] call print_dec game_over: jmp exit [section .data] file_lim: dd 0 final_value: dd 0xffffffff maps: dd seedsoil, soilfert, fertwater, waterlight, lighttemp, temphumid, humidloc current_map: dd 0 filename: db "input",0 [section .bss] seedcnt: resd 1 seeds: resd 64 seedsoil: resd 64*3 soilfert: resd 64*3 fertwater: resd 64*3 waterlight: resd 64*3 lighttemp: resd 64*3 temphumid: resd 64*3 humidloc: resd 64*3 read_buff: resb BUFF_LIM listcnt: resd 1 list_bs: resb 2000000000