day 12 part 1&2
This commit is contained in:
parent
dd65bf8a56
commit
400b90c50e
3
12/Makefile
Normal file
3
12/Makefile
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
all:
|
||||||
|
nasm -g -felf32 main.s && ld -melf_i386 -g main.o
|
||||||
|
|
7
12/input_test
Normal file
7
12/input_test
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
???.### 1,1,3
|
||||||
|
.??..??...?##. 1,1,3
|
||||||
|
?#?#?#?#?#?#?#? 1,3,1,6
|
||||||
|
????.#...#... 4,1,1
|
||||||
|
????.######..#####. 1,6,5
|
||||||
|
?###???????? 3,2,1
|
||||||
|
|
171
12/main.s
Normal file
171
12/main.s
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
global _start
|
||||||
|
[bits 32]
|
||||||
|
[section .text]
|
||||||
|
|
||||||
|
%include "utils.s"
|
||||||
|
|
||||||
|
_start:
|
||||||
|
|
||||||
|
mov esi, file
|
||||||
|
parse_line:
|
||||||
|
; find first num
|
||||||
|
mov ebp, esi ; line start
|
||||||
|
.first_num:
|
||||||
|
mov edi, esi ; save before loc
|
||||||
|
call dec_parse
|
||||||
|
jc .first_num
|
||||||
|
; edi has pointer to just before numbers
|
||||||
|
mov ecx, edi
|
||||||
|
sub ecx, ebp
|
||||||
|
dec ecx ; space
|
||||||
|
xchg esi, ebp
|
||||||
|
mov [line_len], ecx
|
||||||
|
mov edi, line
|
||||||
|
rep movsb
|
||||||
|
xchg esi, ebp
|
||||||
|
mov dword [contiguous_broken+ 0], 0
|
||||||
|
mov dword [contiguous_broken+ 4], 0
|
||||||
|
mov dword [contiguous_broken+ 8], 0
|
||||||
|
mov dword [contiguous_broken+12], 0
|
||||||
|
mov dword [contiguous_broken+16], 0
|
||||||
|
mov dword [contiguous_broken+20], 0
|
||||||
|
mov dword [contiguous_broken+24], 0
|
||||||
|
mov dword [contiguous_broken+28], 0
|
||||||
|
mov dword [contiguous_broken+32], 0
|
||||||
|
mov dword [contiguous_broken+36], 0
|
||||||
|
mov dword [contiguous_broken+40], 0
|
||||||
|
mov dword [contiguous_broken+44], 0
|
||||||
|
mov dword [contiguous_broken+48], 0
|
||||||
|
mov dword [contiguous_broken+52], 0
|
||||||
|
mov dword [contiguous_broken+56], 0
|
||||||
|
mov dword [contiguous_broken+60], 0
|
||||||
|
mov edi, contiguous_broken
|
||||||
|
stosb
|
||||||
|
.next_num:
|
||||||
|
cmp byte [esi-1], 10 ; \n
|
||||||
|
je .newline
|
||||||
|
call dec_parse
|
||||||
|
jc .next_num
|
||||||
|
.got_num:
|
||||||
|
stosb
|
||||||
|
jmp .next_num
|
||||||
|
.newline:
|
||||||
|
push esi ; save input line
|
||||||
|
|
||||||
|
; clear cache
|
||||||
|
mov edi, cache
|
||||||
|
mov ecx, (cache.end - cache)/4
|
||||||
|
mov eax, -1
|
||||||
|
rep stosd
|
||||||
|
; setup do_stream vars
|
||||||
|
xor esi, esi ; line idx
|
||||||
|
mov ebp, [line_len]
|
||||||
|
xor edi, edi ; contiguous_broken idx
|
||||||
|
xor edx, edx ; poss_counter high
|
||||||
|
xor ebx, ebx ; poss_counter low
|
||||||
|
call do_stream ; call into recursive routine
|
||||||
|
add [final_value+0], ebx ; poss_counter low
|
||||||
|
adc [final_value+4], edx ; poss_counter high
|
||||||
|
mov eax, edx
|
||||||
|
call print_dec
|
||||||
|
call space
|
||||||
|
mov eax, ebx
|
||||||
|
call print_dec
|
||||||
|
call newline
|
||||||
|
jmp parse_line_cont
|
||||||
|
|
||||||
|
do_stream:
|
||||||
|
cmp byte [line+esi], '.'
|
||||||
|
je .cont
|
||||||
|
cmp byte [line+esi], '#'
|
||||||
|
jne .branch
|
||||||
|
.broke:
|
||||||
|
cmp byte [contiguous_broken+edi], 0
|
||||||
|
je .ret ; branch impossible
|
||||||
|
movzx ecx, byte [contiguous_broken+edi]
|
||||||
|
inc edi
|
||||||
|
.consume_things:
|
||||||
|
mov al, byte [line+esi]
|
||||||
|
inc esi
|
||||||
|
cmp esi, ebp
|
||||||
|
ja .ret ; branch impossible
|
||||||
|
cmp al, '.'
|
||||||
|
je .ret ; branch impossible
|
||||||
|
loop .consume_things
|
||||||
|
cmp esi, ebp
|
||||||
|
je .cont
|
||||||
|
cmp byte [line+esi], '#'
|
||||||
|
je .ret ; branch impossible
|
||||||
|
; .cont consumes . or ? (must be .)
|
||||||
|
jmp .cont
|
||||||
|
.branch: ; recursive branch
|
||||||
|
mov eax, esi
|
||||||
|
shl eax, 8 ; *256
|
||||||
|
cmp dword [eax+edi*8+cache], -1
|
||||||
|
je .not_cached
|
||||||
|
add ebx, [eax+edi*8+(cache+0)]
|
||||||
|
adc edx, [eax+edi*8+(cache+4)]
|
||||||
|
jmp .cont
|
||||||
|
.not_cached:
|
||||||
|
push edx
|
||||||
|
push ebx
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
xor ebx, ebx
|
||||||
|
xor edx, edx
|
||||||
|
call do_stream.broke ; assume #
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
mov eax, esi
|
||||||
|
shl eax, 8
|
||||||
|
mov [eax+edi*8+(cache+0)], ebx
|
||||||
|
mov [eax+edi*8+(cache+4)], edx
|
||||||
|
pop eax
|
||||||
|
add ebx, eax
|
||||||
|
pop eax
|
||||||
|
adc edx, eax
|
||||||
|
; assume .
|
||||||
|
.cont:
|
||||||
|
inc esi
|
||||||
|
cmp esi, ebp
|
||||||
|
jb do_stream
|
||||||
|
; iff we are at the end of stream
|
||||||
|
; and contiguous_broken is exhausted
|
||||||
|
; we add a possibility
|
||||||
|
cmp byte [contiguous_broken+edi], 0
|
||||||
|
jne .ret
|
||||||
|
add ebx, 1 ; poss counter
|
||||||
|
adc edx, 0
|
||||||
|
.ret:
|
||||||
|
ret
|
||||||
|
|
||||||
|
parse_line_cont:
|
||||||
|
pop esi
|
||||||
|
cmp esi, file.over-1
|
||||||
|
jb parse_line
|
||||||
|
call newline
|
||||||
|
|
||||||
|
game_over:
|
||||||
|
mov eax, [final_value+4]
|
||||||
|
call print_dec
|
||||||
|
call space
|
||||||
|
mov eax, [final_value+0]
|
||||||
|
call print_dec
|
||||||
|
call newline
|
||||||
|
jmp exit
|
||||||
|
|
||||||
|
[section .data]
|
||||||
|
line_len: dd 0
|
||||||
|
final_value: dd 0, 0
|
||||||
|
final_setting: dd 0, 0
|
||||||
|
curr_setting: dd 0, 0
|
||||||
|
file: incbin "input5"
|
||||||
|
.over:
|
||||||
|
nl_str: db "new line!"
|
||||||
|
.over:
|
||||||
|
|
||||||
|
[section .bss]
|
||||||
|
contiguous_broken: resb 64
|
||||||
|
line: resb 512
|
||||||
|
cache: resd 256*64*2
|
||||||
|
cache.end:
|
124
12/main_part1.s
Normal file
124
12/main_part1.s
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
global _start
|
||||||
|
[bits 32]
|
||||||
|
[section .text]
|
||||||
|
|
||||||
|
%include "utils.s"
|
||||||
|
|
||||||
|
_start:
|
||||||
|
|
||||||
|
mov esi, file
|
||||||
|
parse_line:
|
||||||
|
; find first num
|
||||||
|
mov ebp, esi ; line start
|
||||||
|
.first_num:
|
||||||
|
mov edi, esi ; save before loc
|
||||||
|
call dec_parse
|
||||||
|
jc .first_num
|
||||||
|
; edi has pointer to just before numbers
|
||||||
|
mov ecx, edi
|
||||||
|
sub ecx, ebp
|
||||||
|
dec ecx ; space
|
||||||
|
xchg esi, ebp
|
||||||
|
mov [line_len], ecx
|
||||||
|
mov edi, line
|
||||||
|
rep movsb
|
||||||
|
xchg esi, ebp
|
||||||
|
mov dword [contiguous_broken+ 0], 0
|
||||||
|
mov dword [contiguous_broken+ 4], 0
|
||||||
|
mov dword [contiguous_broken+ 8], 0
|
||||||
|
mov dword [contiguous_broken+12], 0
|
||||||
|
mov edi, contiguous_broken
|
||||||
|
stosb
|
||||||
|
.next_num:
|
||||||
|
cmp byte [esi-1], 10 ; \n
|
||||||
|
je .newline
|
||||||
|
call dec_parse
|
||||||
|
jc .next_num
|
||||||
|
.got_num:
|
||||||
|
stosb
|
||||||
|
jmp .next_num
|
||||||
|
.newline:
|
||||||
|
push esi ; save input line
|
||||||
|
mov esi, line
|
||||||
|
mov ecx, [line_len]
|
||||||
|
xor ebx, ebx
|
||||||
|
count_qs:
|
||||||
|
lodsb
|
||||||
|
cmp al, '?'
|
||||||
|
jne .cont
|
||||||
|
stc
|
||||||
|
rcl ebx, 1
|
||||||
|
.cont:
|
||||||
|
loop count_qs
|
||||||
|
push ebx ; ? final setting
|
||||||
|
test_possibilities:
|
||||||
|
xor ebp, ebp ; ? settings
|
||||||
|
xor ebx, ebx ; poss counter
|
||||||
|
.next_poss:
|
||||||
|
mov edx, ebp
|
||||||
|
mov esi, line
|
||||||
|
mov ecx, [line_len]
|
||||||
|
xor eax, eax ; ah - curr broke run, al - lodsb
|
||||||
|
mov edi, contiguous_broken
|
||||||
|
.next_poss_loop:
|
||||||
|
lodsb
|
||||||
|
cmp al, '.'
|
||||||
|
je .working
|
||||||
|
cmp al, '#'
|
||||||
|
je .broke
|
||||||
|
; else ? - select based on edx
|
||||||
|
rcr edx, 1
|
||||||
|
jc .broke
|
||||||
|
.working:
|
||||||
|
cmp ah, 0
|
||||||
|
je .cont ; no broke
|
||||||
|
cmp [edi], ah
|
||||||
|
jne .fail_poss
|
||||||
|
inc edi
|
||||||
|
mov ah, 0
|
||||||
|
jmp .cont
|
||||||
|
.broke:
|
||||||
|
inc ah
|
||||||
|
.cont:
|
||||||
|
loop .next_poss_loop
|
||||||
|
cmp [edi], ah
|
||||||
|
jne .fail_poss
|
||||||
|
cmp byte [edi+1], 0
|
||||||
|
jne .fail_poss
|
||||||
|
inc ebx ; poss counter
|
||||||
|
mov eax, ebp
|
||||||
|
;call print_dec
|
||||||
|
;call space
|
||||||
|
.fail_poss:
|
||||||
|
.next_poss_cont:
|
||||||
|
inc ebp ; ? settings
|
||||||
|
cmp ebp, [esp] ; cmp to final
|
||||||
|
jbe .next_poss
|
||||||
|
;call newline
|
||||||
|
mov eax, ebx
|
||||||
|
call print_dec
|
||||||
|
call newline
|
||||||
|
add [final_value], ebx
|
||||||
|
add esp, 4
|
||||||
|
pop esi
|
||||||
|
cmp esi, file.over-1
|
||||||
|
jb parse_line
|
||||||
|
call newline
|
||||||
|
|
||||||
|
game_over:
|
||||||
|
mov eax, [final_value]
|
||||||
|
call print_dec
|
||||||
|
call newline
|
||||||
|
jmp exit
|
||||||
|
|
||||||
|
[section .data]
|
||||||
|
final_value: dd 0
|
||||||
|
line_len: dd 0
|
||||||
|
file: incbin "input"
|
||||||
|
.over:
|
||||||
|
nl_str: db "new line!"
|
||||||
|
.over:
|
||||||
|
|
||||||
|
[section .bss]
|
||||||
|
contiguous_broken: resb 16
|
||||||
|
line: resb 256
|
258
12/utils.s
Normal file
258
12/utils.s
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
; call # val val2
|
||||||
|
; int $0x80 eax eax edx -
|
||||||
|
;
|
||||||
|
; arg1 arg2 arg3 arg4 arg5 arg6 arg7
|
||||||
|
; ebx ecx edx esi edi ebp -
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mov eax, 1 ; exit
|
||||||
|
int 0x80
|
||||||
|
|
||||||
|
; filename in EBX
|
||||||
|
; return handle in EBX
|
||||||
|
; read only
|
||||||
|
open_file:
|
||||||
|
push eax
|
||||||
|
push ecx
|
||||||
|
mov eax, 5 ; open
|
||||||
|
xor ecx, ecx ; read only
|
||||||
|
int 0x80
|
||||||
|
mov ebx, eax
|
||||||
|
pop ecx
|
||||||
|
pop eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; file handle in EBX
|
||||||
|
; buffer in ECX
|
||||||
|
; count of bytes to read in EDX
|
||||||
|
; return bytes actually read in EAX
|
||||||
|
; exits on error
|
||||||
|
read_file:
|
||||||
|
mov eax, 3 ; read
|
||||||
|
int 0x80
|
||||||
|
test eax, eax
|
||||||
|
js .err
|
||||||
|
ret
|
||||||
|
.err:
|
||||||
|
mov eax, 4 ; write
|
||||||
|
mov ebx, 1 ; stdout
|
||||||
|
mov ecx, .err_str
|
||||||
|
mov edx, 21
|
||||||
|
int 0x80
|
||||||
|
jmp exit
|
||||||
|
.err_str: db `Could not read file.\n`
|
||||||
|
|
||||||
|
; string input in ESI
|
||||||
|
; value in EAX
|
||||||
|
; CF set if none, clear if some
|
||||||
|
; ESI set past checked area
|
||||||
|
dec_parse:
|
||||||
|
push ebx
|
||||||
|
push edx
|
||||||
|
push edi
|
||||||
|
xor eax, eax
|
||||||
|
xor edi, edi
|
||||||
|
mov ebx, 10 ; base
|
||||||
|
lodsb
|
||||||
|
sub al, '0'
|
||||||
|
js .no_input
|
||||||
|
cmp al, 9
|
||||||
|
jle .got_char
|
||||||
|
.no_input:
|
||||||
|
stc ; set CF
|
||||||
|
jmp .done
|
||||||
|
.loop:
|
||||||
|
xor eax,eax
|
||||||
|
lodsb
|
||||||
|
sub al, '0'
|
||||||
|
js .dec_done
|
||||||
|
cmp al, 9
|
||||||
|
jg .dec_done
|
||||||
|
.got_char:
|
||||||
|
xchg edi,eax
|
||||||
|
mul ebx
|
||||||
|
add edi,eax
|
||||||
|
jmp .loop
|
||||||
|
.dec_done:
|
||||||
|
clc ; clear CF
|
||||||
|
.done:
|
||||||
|
mov eax,edi
|
||||||
|
pop edi
|
||||||
|
pop edx
|
||||||
|
pop ebx
|
||||||
|
ret
|
||||||
|
|
||||||
|
; string input in ESI
|
||||||
|
; value in EAX
|
||||||
|
; CF set if none, clear if some
|
||||||
|
; ESI set past checked area
|
||||||
|
sign_dec_parse:
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
push edi
|
||||||
|
xor eax, eax
|
||||||
|
xor edi, edi
|
||||||
|
xor ecx, ecx ; neg flag
|
||||||
|
mov ebx, 10 ; base
|
||||||
|
cmp byte [esi], '-'
|
||||||
|
jne .no_minus
|
||||||
|
inc esi
|
||||||
|
mov cl, 1
|
||||||
|
.no_minus:
|
||||||
|
lodsb
|
||||||
|
sub al, '0'
|
||||||
|
js .no_input
|
||||||
|
cmp al, 9
|
||||||
|
jle .got_char
|
||||||
|
.no_input:
|
||||||
|
stc ; set CF
|
||||||
|
jmp .done
|
||||||
|
.loop:
|
||||||
|
xor eax,eax
|
||||||
|
lodsb
|
||||||
|
sub al, '0'
|
||||||
|
js .dec_done
|
||||||
|
cmp al, 9
|
||||||
|
jg .dec_done
|
||||||
|
.got_char:
|
||||||
|
xchg edi,eax
|
||||||
|
mul ebx
|
||||||
|
add edi,eax
|
||||||
|
jmp .loop
|
||||||
|
.dec_done:
|
||||||
|
test ecx, ecx
|
||||||
|
jz .not_neg
|
||||||
|
neg edi
|
||||||
|
.not_neg:
|
||||||
|
clc ; clear CF
|
||||||
|
.done:
|
||||||
|
mov eax,edi
|
||||||
|
pop edi
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
ret
|
||||||
|
|
||||||
|
; modifies no regs
|
||||||
|
newline:
|
||||||
|
pushad
|
||||||
|
push 10
|
||||||
|
mov eax, 4 ; write
|
||||||
|
mov ebx, 1 ; stdout
|
||||||
|
mov ecx, esp ; string
|
||||||
|
mov edx, 1 ; length
|
||||||
|
int 0x80
|
||||||
|
add esp, 4
|
||||||
|
popad
|
||||||
|
ret
|
||||||
|
; modifies no regs
|
||||||
|
space:
|
||||||
|
pushad
|
||||||
|
push 9
|
||||||
|
mov eax, 4 ; write
|
||||||
|
mov ebx, 1 ; stdout
|
||||||
|
mov ecx, esp ; string
|
||||||
|
mov edx, 1 ; length
|
||||||
|
int 0x80
|
||||||
|
add esp, 4
|
||||||
|
popad
|
||||||
|
ret
|
||||||
|
|
||||||
|
; input in EAX, all regs unmodified
|
||||||
|
print_dec:
|
||||||
|
pushad ; save regs
|
||||||
|
; max 4294967296 is 10 chars
|
||||||
|
; round to nearest 32-bit boundary
|
||||||
|
sub esp, 12
|
||||||
|
; string in ECX, length in EDX
|
||||||
|
lea ecx, [esp+11] ; last possible byte
|
||||||
|
; check for 0
|
||||||
|
test eax, eax
|
||||||
|
jz .zero
|
||||||
|
mov ebx, 10 ; base 10
|
||||||
|
xor esi, esi ; counter
|
||||||
|
.div_shit:
|
||||||
|
xor edx, edx
|
||||||
|
; divide
|
||||||
|
div ebx
|
||||||
|
dec ecx ; next char
|
||||||
|
inc esi
|
||||||
|
; store
|
||||||
|
add dl, '0'
|
||||||
|
mov byte [ecx], dl
|
||||||
|
; check if done
|
||||||
|
test eax, eax
|
||||||
|
jnz .div_shit ; continue
|
||||||
|
mov edx, esi ; counter in edx
|
||||||
|
jmp .write
|
||||||
|
.zero:
|
||||||
|
mov byte [ecx], '0'
|
||||||
|
mov edx, 1 ; length
|
||||||
|
.write:
|
||||||
|
mov eax, 4 ; write
|
||||||
|
mov ebx, 1 ; stdout
|
||||||
|
int 0x80
|
||||||
|
add esp, 12 ; restore stack
|
||||||
|
popad ; restore regs
|
||||||
|
ret
|
||||||
|
|
||||||
|
; input in EAX, all regs unmodified
|
||||||
|
print_sign_dec:
|
||||||
|
pushad ; save regs
|
||||||
|
; range -2147483648 to 2147483647 is 11 chars
|
||||||
|
; round to nearest 32-bit boundary
|
||||||
|
sub esp, 12
|
||||||
|
; string in ECX, length in EDX
|
||||||
|
lea ecx, [esp+11] ; last possible byte
|
||||||
|
; check for 0, negative
|
||||||
|
xor ebp, ebp
|
||||||
|
test eax, eax
|
||||||
|
jz .zero
|
||||||
|
jns .positive
|
||||||
|
neg eax
|
||||||
|
mov ebp, 1
|
||||||
|
.positive:
|
||||||
|
mov ebx, 10 ; base 10
|
||||||
|
xor esi, esi ; counter
|
||||||
|
.div_shit:
|
||||||
|
xor edx, edx
|
||||||
|
; divide
|
||||||
|
div ebx
|
||||||
|
dec ecx ; next char
|
||||||
|
inc esi
|
||||||
|
; store
|
||||||
|
add dl, '0'
|
||||||
|
mov byte [ecx], dl
|
||||||
|
; check if done
|
||||||
|
test eax, eax
|
||||||
|
jnz .div_shit ; continue
|
||||||
|
mov edx, esi ; counter in edx
|
||||||
|
jmp .write
|
||||||
|
.zero:
|
||||||
|
mov byte [ecx], '0'
|
||||||
|
mov edx, 1 ; length
|
||||||
|
.write:
|
||||||
|
test ebp, ebp
|
||||||
|
jz .no_minus
|
||||||
|
dec ecx
|
||||||
|
inc edx
|
||||||
|
mov byte [ecx], '-'
|
||||||
|
.no_minus:
|
||||||
|
mov eax, 4 ; write
|
||||||
|
mov ebx, 1 ; stdout
|
||||||
|
int 0x80
|
||||||
|
add esp, 12 ; restore stack
|
||||||
|
popad ; restore regs
|
||||||
|
ret
|
||||||
|
|
||||||
|
; input in ESI, len in ECX, all regs unmodified
|
||||||
|
print_string:
|
||||||
|
pushad ; save regs
|
||||||
|
mov eax, 4 ; write
|
||||||
|
mov ebx, 1 ; stdout
|
||||||
|
mov edx, ecx ; length
|
||||||
|
mov ecx, esi ; string
|
||||||
|
int 0x80
|
||||||
|
popad ; restore regs
|
||||||
|
ret
|
Loading…
Reference in New Issue
Block a user