day 16 part 2
This commit is contained in:
parent
45fc62c759
commit
83f5ba9fae
502
16/main.s
Normal file
502
16/main.s
Normal file
@ -0,0 +1,502 @@
|
|||||||
|
%include "utils.s"
|
||||||
|
|
||||||
|
global _start
|
||||||
|
[bits 32]
|
||||||
|
[section .text]
|
||||||
|
|
||||||
|
%define LINE_LEN 111 ; real
|
||||||
|
%define FILENAME "input"
|
||||||
|
;%define LINE_LEN 11 ; test
|
||||||
|
;%define FILENAME "input_test"
|
||||||
|
|
||||||
|
;%define ITER_PRINT
|
||||||
|
|
||||||
|
_start:
|
||||||
|
|
||||||
|
; bit 3 bit 2 bit 1 bit 0
|
||||||
|
; up down left right
|
||||||
|
|
||||||
|
; start top left going right
|
||||||
|
mov dword [test_edge_line], 0
|
||||||
|
mov dword [test_edge_col], 0
|
||||||
|
mov byte [test_edge_dir], 1
|
||||||
|
mov byte [energized], 1
|
||||||
|
jmp next_iteration
|
||||||
|
next_edge_tile:
|
||||||
|
; clear energized
|
||||||
|
mov edi, energized
|
||||||
|
xor eax, eax
|
||||||
|
mov ecx, (128*128)/4
|
||||||
|
rep stosd
|
||||||
|
|
||||||
|
mov eax, [test_edge_line]
|
||||||
|
mov ecx, [test_edge_col]
|
||||||
|
mov bl, [test_edge_dir]
|
||||||
|
cmp bl, 1 ; we're testing going right
|
||||||
|
jne .maybe_2
|
||||||
|
; we're going down first col
|
||||||
|
cmp eax, LINE_LEN-2 ; check if last line
|
||||||
|
je .bl_corner
|
||||||
|
inc eax
|
||||||
|
jmp start_iterations
|
||||||
|
.bl_corner:
|
||||||
|
mov bl, 8 ; try going up
|
||||||
|
jmp start_iterations
|
||||||
|
.maybe_2:
|
||||||
|
cmp bl, 2 ; we're testing going left
|
||||||
|
jne .maybe_4
|
||||||
|
; we're going up the last col
|
||||||
|
cmp eax, 0 ; check if first line
|
||||||
|
je .tr_corner
|
||||||
|
dec eax
|
||||||
|
jmp start_iterations
|
||||||
|
.tr_corner:
|
||||||
|
mov bl, 4 ; try going down
|
||||||
|
jmp start_iterations
|
||||||
|
.maybe_4:
|
||||||
|
cmp bl, 4 ; we're testing going down
|
||||||
|
jne .maybe_8
|
||||||
|
; we're going along the top line backward
|
||||||
|
cmp ecx, 0 ; check if first col
|
||||||
|
je .tl_corner
|
||||||
|
dec ecx
|
||||||
|
jmp start_iterations
|
||||||
|
.tl_corner:
|
||||||
|
jmp game_over ; nothing to do! jump to exit
|
||||||
|
.maybe_8: ; we're testing going up
|
||||||
|
; we're going along the bottom line
|
||||||
|
cmp ecx, LINE_LEN-2 ; check if last col
|
||||||
|
je .br_corner
|
||||||
|
inc ecx
|
||||||
|
jmp start_iterations
|
||||||
|
.br_corner:
|
||||||
|
mov bl, 2 ; try going left
|
||||||
|
jmp start_iterations
|
||||||
|
|
||||||
|
start_iterations:
|
||||||
|
mov [test_edge_line], eax
|
||||||
|
mov [test_edge_col], ecx
|
||||||
|
mov [test_edge_dir], bl
|
||||||
|
mov edx, LINE_LEN
|
||||||
|
mul edx
|
||||||
|
add eax, ecx
|
||||||
|
mov byte [energized+eax], bl
|
||||||
|
|
||||||
|
next_iteration:
|
||||||
|
|
||||||
|
%ifdef ITER_PRINT
|
||||||
|
; debug printing
|
||||||
|
dbg:
|
||||||
|
xor esi, esi ; top line
|
||||||
|
.for_lines:
|
||||||
|
xor ecx, ecx ; leftmost char
|
||||||
|
.for_chars:
|
||||||
|
movzx eax, byte [esi+ecx+energized]
|
||||||
|
movzx ebx, byte [esi+ecx+file]
|
||||||
|
pushad
|
||||||
|
test al, al
|
||||||
|
jz .prnt_char
|
||||||
|
p_string ansi_color_highbold_green
|
||||||
|
cmp bl, '.'
|
||||||
|
jne .prnt_char
|
||||||
|
popcnt ecx, eax
|
||||||
|
cmp ecx, 1
|
||||||
|
jg .prnt_num
|
||||||
|
cmp al, 1
|
||||||
|
je .prnt_right
|
||||||
|
cmp al, 2
|
||||||
|
je .prnt_left
|
||||||
|
cmp al, 4
|
||||||
|
je .prnt_down
|
||||||
|
.prnt_up: mov al, '^'
|
||||||
|
call print_char
|
||||||
|
jmp .prnt_done
|
||||||
|
.prnt_down: mov al, 'v'
|
||||||
|
call print_char
|
||||||
|
jmp .prnt_done
|
||||||
|
.prnt_left: mov al, '<'
|
||||||
|
call print_char
|
||||||
|
jmp .prnt_done
|
||||||
|
.prnt_right: mov al, '>'
|
||||||
|
call print_char
|
||||||
|
jmp .prnt_done
|
||||||
|
.prnt_num:
|
||||||
|
mov eax, ecx
|
||||||
|
call print_dec
|
||||||
|
jmp .prnt_done
|
||||||
|
.prnt_char:
|
||||||
|
mov al, [esi+ecx+file]
|
||||||
|
call print_char
|
||||||
|
.prnt_done:
|
||||||
|
p_string ansi_color_reset
|
||||||
|
popad
|
||||||
|
.for_chars_cont:
|
||||||
|
inc ecx
|
||||||
|
cmp ecx, LINE_LEN-2
|
||||||
|
jbe .for_chars
|
||||||
|
.for_chars_done:
|
||||||
|
.for_lines_cont:
|
||||||
|
call newline
|
||||||
|
add esi, LINE_LEN
|
||||||
|
cmp esi, len(file)
|
||||||
|
jb .for_lines
|
||||||
|
call newline
|
||||||
|
; debug printing end
|
||||||
|
%endif
|
||||||
|
|
||||||
|
xor esi, esi ; top line
|
||||||
|
for_lines:
|
||||||
|
xor ecx, ecx ; leftmost char
|
||||||
|
for_chars:
|
||||||
|
movzx eax, byte [esi+ecx+energized]
|
||||||
|
movzx ebx, byte [esi+ecx+file]
|
||||||
|
; skip if not energized
|
||||||
|
test eax, eax
|
||||||
|
jz for_chars_cont
|
||||||
|
; select thing
|
||||||
|
cmp bl, '.'
|
||||||
|
je empty
|
||||||
|
cmp bl, '/'
|
||||||
|
je mirror_one
|
||||||
|
cmp bl, '\'
|
||||||
|
je mirror_two
|
||||||
|
cmp bl, '-'
|
||||||
|
je horz_split
|
||||||
|
cmp bl, '|'
|
||||||
|
je vert_split
|
||||||
|
p_string what_the_fuck
|
||||||
|
jmp exit
|
||||||
|
empty: ; .
|
||||||
|
; propagate
|
||||||
|
; test right
|
||||||
|
bt eax, 0
|
||||||
|
jnc .t_left
|
||||||
|
or byte [esi+ecx+energized+1], 1<<0
|
||||||
|
.t_left:
|
||||||
|
bt eax, 1
|
||||||
|
jnc .t_down
|
||||||
|
or byte [esi+ecx+energized-1], 1<<1
|
||||||
|
.t_down:
|
||||||
|
bt eax, 2
|
||||||
|
jnc .t_up
|
||||||
|
or byte [esi+ecx+energized+LINE_LEN], 1<<2
|
||||||
|
.t_up:
|
||||||
|
bt eax, 3
|
||||||
|
jnc .done
|
||||||
|
or byte [esi+ecx+energized-LINE_LEN], 1<<3
|
||||||
|
.done:
|
||||||
|
jmp for_chars_cont
|
||||||
|
mirror_one: ; /
|
||||||
|
; our energized is what hits us
|
||||||
|
; test right >/
|
||||||
|
bt eax, 0
|
||||||
|
jnc .t_left
|
||||||
|
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up char going up
|
||||||
|
.t_left: ; /<
|
||||||
|
bt eax, 1
|
||||||
|
jnc .t_down
|
||||||
|
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down going down
|
||||||
|
.t_down:
|
||||||
|
bt eax, 2 ; v
|
||||||
|
jnc .t_up ; /
|
||||||
|
or byte [esi+ecx+energized-1], 1<<1 ; left going left
|
||||||
|
.t_up:
|
||||||
|
bt eax, 3 ; /
|
||||||
|
jnc .done ; ^
|
||||||
|
or byte [esi+ecx+energized+1], 1<<0 ; right going right
|
||||||
|
.done:
|
||||||
|
jmp for_chars_cont
|
||||||
|
mirror_two: ; \
|
||||||
|
; our energized is what hits us
|
||||||
|
; test right >\
|
||||||
|
bt eax, 0
|
||||||
|
jnc .t_left
|
||||||
|
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down char going down
|
||||||
|
.t_left: ; \<
|
||||||
|
bt eax, 1
|
||||||
|
jnc .t_down
|
||||||
|
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up going up
|
||||||
|
.t_down:
|
||||||
|
bt eax, 2 ; v
|
||||||
|
jnc .t_up ; \
|
||||||
|
or byte [esi+ecx+energized+1], 1<<0 ; right going right
|
||||||
|
.t_up:
|
||||||
|
bt eax, 3 ; \
|
||||||
|
jnc .done ; ^
|
||||||
|
or byte [esi+ecx+energized-1], 1<<1 ; left going left
|
||||||
|
.done:
|
||||||
|
jmp for_chars_cont
|
||||||
|
horz_split: ; -
|
||||||
|
; our energized is what hits us
|
||||||
|
; right and left propagate
|
||||||
|
; test right
|
||||||
|
bt eax, 0
|
||||||
|
jnc .t_left
|
||||||
|
or byte [esi+ecx+energized+1], 1<<0
|
||||||
|
.t_left:
|
||||||
|
bt eax, 1
|
||||||
|
jnc .t_vert
|
||||||
|
or byte [esi+ecx+energized-1], 1<<1
|
||||||
|
; down and up go both left and right
|
||||||
|
.t_vert:
|
||||||
|
and eax, 1<<2 | 1<<3
|
||||||
|
jz .done
|
||||||
|
or byte [esi+ecx+energized+1], 1<<0 ; right going right
|
||||||
|
or byte [esi+ecx+energized-1], 1<<1 ; left going left
|
||||||
|
.done:
|
||||||
|
jmp for_chars_cont
|
||||||
|
vert_split: ; |
|
||||||
|
; our energized is what hits us
|
||||||
|
; down and up propagate
|
||||||
|
; test down
|
||||||
|
bt eax, 2
|
||||||
|
jnc .t_up
|
||||||
|
or byte [esi+ecx+energized+LINE_LEN], 1<<2
|
||||||
|
.t_up:
|
||||||
|
bt eax, 3
|
||||||
|
jnc .t_vert
|
||||||
|
or byte [esi+ecx+energized-LINE_LEN], 1<<3
|
||||||
|
; left and right go both down and up
|
||||||
|
.t_vert:
|
||||||
|
and eax, 1<<0 | 1<<1
|
||||||
|
jz .done
|
||||||
|
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down going down
|
||||||
|
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up going up
|
||||||
|
.done:
|
||||||
|
for_chars_cont:
|
||||||
|
inc ecx
|
||||||
|
cmp ecx, LINE_LEN-2
|
||||||
|
jbe for_chars
|
||||||
|
for_chars_done:
|
||||||
|
for_lines_cont:
|
||||||
|
add esi, LINE_LEN
|
||||||
|
cmp esi, len(file)
|
||||||
|
jb for_lines
|
||||||
|
|
||||||
|
xor ebp, ebp ; energized count
|
||||||
|
sub esi, LINE_LEN ; last line
|
||||||
|
; now go through backward
|
||||||
|
bkwd_for_lines:
|
||||||
|
mov ecx, LINE_LEN-2 ; rightmost char
|
||||||
|
bkwd_for_chars:
|
||||||
|
movzx eax, byte [esi+ecx+energized]
|
||||||
|
movzx ebx, byte [esi+ecx+file]
|
||||||
|
; skip if not energized
|
||||||
|
test eax, eax
|
||||||
|
jz bkwd_for_chars_cont
|
||||||
|
inc ebp ; energized count
|
||||||
|
; select thing
|
||||||
|
cmp bl, '.'
|
||||||
|
je bkwd_empty
|
||||||
|
cmp bl, '/'
|
||||||
|
je bkwd_mirror_one
|
||||||
|
cmp bl, '\'
|
||||||
|
je bkwd_mirror_two
|
||||||
|
cmp bl, '-'
|
||||||
|
je bkwd_horz_split
|
||||||
|
cmp bl, '|'
|
||||||
|
je bkwd_vert_split
|
||||||
|
p_string what_the_fuck
|
||||||
|
jmp exit
|
||||||
|
bkwd_empty: ; .
|
||||||
|
; propagate
|
||||||
|
; test right
|
||||||
|
bt eax, 0
|
||||||
|
jnc .t_left
|
||||||
|
or byte [esi+ecx+energized+1], 1<<0
|
||||||
|
.t_left:
|
||||||
|
bt eax, 1
|
||||||
|
jnc .t_down
|
||||||
|
or byte [esi+ecx+energized-1], 1<<1
|
||||||
|
.t_down:
|
||||||
|
bt eax, 2
|
||||||
|
jnc .t_up
|
||||||
|
or byte [esi+ecx+energized+LINE_LEN], 1<<2
|
||||||
|
.t_up:
|
||||||
|
bt eax, 3
|
||||||
|
jnc .done
|
||||||
|
or byte [esi+ecx+energized-LINE_LEN], 1<<3
|
||||||
|
.done:
|
||||||
|
jmp bkwd_for_chars_cont
|
||||||
|
bkwd_mirror_one: ; /
|
||||||
|
; our energized is what hits us
|
||||||
|
; test right >/
|
||||||
|
bt eax, 0
|
||||||
|
jnc .t_left
|
||||||
|
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up char going up
|
||||||
|
.t_left: ; /<
|
||||||
|
bt eax, 1
|
||||||
|
jnc .t_down
|
||||||
|
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down going down
|
||||||
|
.t_down:
|
||||||
|
bt eax, 2 ; v
|
||||||
|
jnc .t_up ; /
|
||||||
|
or byte [esi+ecx+energized-1], 1<<1 ; left going left
|
||||||
|
.t_up:
|
||||||
|
bt eax, 3 ; /
|
||||||
|
jnc .done ; ^
|
||||||
|
or byte [esi+ecx+energized+1], 1<<0 ; right going right
|
||||||
|
.done:
|
||||||
|
jmp bkwd_for_chars_cont
|
||||||
|
bkwd_mirror_two: ; \
|
||||||
|
; our energized is what hits us
|
||||||
|
; test right >\
|
||||||
|
bt eax, 0
|
||||||
|
jnc .t_left
|
||||||
|
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down char going down
|
||||||
|
.t_left: ; \<
|
||||||
|
bt eax, 1
|
||||||
|
jnc .t_down
|
||||||
|
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up going up
|
||||||
|
.t_down:
|
||||||
|
bt eax, 2 ; v
|
||||||
|
jnc .t_up ; \
|
||||||
|
or byte [esi+ecx+energized+1], 1<<0 ; right going right
|
||||||
|
.t_up:
|
||||||
|
bt eax, 3 ; \
|
||||||
|
jnc .done ; ^
|
||||||
|
or byte [esi+ecx+energized-1], 1<<1 ; left going left
|
||||||
|
.done:
|
||||||
|
jmp bkwd_for_chars_cont
|
||||||
|
bkwd_horz_split: ; -
|
||||||
|
; our energized is what hits us
|
||||||
|
; right and left propagate
|
||||||
|
; test right
|
||||||
|
bt eax, 0
|
||||||
|
jnc .t_left
|
||||||
|
or byte [esi+ecx+energized+1], 1<<0
|
||||||
|
.t_left:
|
||||||
|
bt eax, 1
|
||||||
|
jnc .t_vert
|
||||||
|
or byte [esi+ecx+energized-1], 1<<1
|
||||||
|
; down and up go both left and right
|
||||||
|
.t_vert:
|
||||||
|
and eax, 1<<2 | 1<<3
|
||||||
|
jz .done
|
||||||
|
or byte [esi+ecx+energized+1], 1<<0 ; right going right
|
||||||
|
or byte [esi+ecx+energized-1], 1<<1 ; left going left
|
||||||
|
.done:
|
||||||
|
jmp bkwd_for_chars_cont
|
||||||
|
bkwd_vert_split: ; |
|
||||||
|
; our energized is what hits us
|
||||||
|
; down and up propagate
|
||||||
|
; test down
|
||||||
|
bt eax, 2
|
||||||
|
jnc .t_up
|
||||||
|
or byte [esi+ecx+energized+LINE_LEN], 1<<2
|
||||||
|
.t_up:
|
||||||
|
bt eax, 3
|
||||||
|
jnc .t_vert
|
||||||
|
or byte [esi+ecx+energized-LINE_LEN], 1<<3
|
||||||
|
; left and right go both down and up
|
||||||
|
.t_vert:
|
||||||
|
and eax, 1<<0 | 1<<1
|
||||||
|
jz .done
|
||||||
|
or byte [esi+ecx+energized+LINE_LEN], 1<<2 ; down going down
|
||||||
|
or byte [esi+ecx+energized-LINE_LEN], 1<<3 ; up going up
|
||||||
|
.done:
|
||||||
|
bkwd_for_chars_cont:
|
||||||
|
dec ecx
|
||||||
|
jnz bkwd_for_chars
|
||||||
|
bkwd_for_chars_done:
|
||||||
|
bkwd_for_lines_cont:
|
||||||
|
sub esi, LINE_LEN
|
||||||
|
jns bkwd_for_lines
|
||||||
|
|
||||||
|
cmp ebp, [last_energized]
|
||||||
|
mov [last_energized], ebp
|
||||||
|
jne next_iteration
|
||||||
|
|
||||||
|
|
||||||
|
; print final
|
||||||
|
xor ebp, ebp
|
||||||
|
print_final:
|
||||||
|
xor esi, esi ; top line
|
||||||
|
.for_lines:
|
||||||
|
xor ecx, ecx ; leftmost char
|
||||||
|
.for_chars:
|
||||||
|
movzx eax, byte [esi+ecx+energized]
|
||||||
|
movzx ebx, byte [esi+ecx+file]
|
||||||
|
test al, al
|
||||||
|
jz .prnt_char
|
||||||
|
inc ebp
|
||||||
|
p_string ansi_color_highbold_green
|
||||||
|
cmp bl, '.'
|
||||||
|
jne .prnt_char
|
||||||
|
popcnt edx, eax
|
||||||
|
cmp edx, 1
|
||||||
|
jg .prnt_num
|
||||||
|
cmp al, 1
|
||||||
|
je .prnt_right
|
||||||
|
cmp al, 2
|
||||||
|
je .prnt_left
|
||||||
|
cmp al, 4
|
||||||
|
je .prnt_down
|
||||||
|
.prnt_up: mov al, '^'
|
||||||
|
call print_char
|
||||||
|
jmp .prnt_done
|
||||||
|
.prnt_down: mov al, 'v'
|
||||||
|
call print_char
|
||||||
|
jmp .prnt_done
|
||||||
|
.prnt_left: mov al, '<'
|
||||||
|
call print_char
|
||||||
|
jmp .prnt_done
|
||||||
|
.prnt_right: mov al, '>'
|
||||||
|
call print_char
|
||||||
|
jmp .prnt_done
|
||||||
|
.prnt_num:
|
||||||
|
mov eax, edx
|
||||||
|
call print_dec
|
||||||
|
jmp .prnt_done
|
||||||
|
.prnt_char:
|
||||||
|
mov al, [esi+ecx+file]
|
||||||
|
call print_char
|
||||||
|
.prnt_done:
|
||||||
|
p_string ansi_color_reset
|
||||||
|
.for_chars_cont:
|
||||||
|
inc ecx
|
||||||
|
cmp ecx, LINE_LEN-2
|
||||||
|
jbe .for_chars
|
||||||
|
.for_chars_done:
|
||||||
|
.for_lines_cont:
|
||||||
|
call newline
|
||||||
|
add esi, LINE_LEN
|
||||||
|
cmp esi, len(file)
|
||||||
|
jb .for_lines
|
||||||
|
mov eax, ebp
|
||||||
|
call print_dec
|
||||||
|
call newline
|
||||||
|
call newline
|
||||||
|
cmp [final_value], ebp
|
||||||
|
cmova ebp, [final_value]
|
||||||
|
mov [final_value], ebp
|
||||||
|
jmp next_edge_tile
|
||||||
|
|
||||||
|
game_over:
|
||||||
|
mov eax, [final_value]
|
||||||
|
call print_dec
|
||||||
|
call newline
|
||||||
|
jmp exit
|
||||||
|
|
||||||
|
[section .data]
|
||||||
|
final_value: dd 0
|
||||||
|
last_energized: dd 0
|
||||||
|
test_edge_line: dd 0
|
||||||
|
test_edge_col: dd 0
|
||||||
|
test_edge_dir: dd 0
|
||||||
|
file: incbin FILENAME
|
||||||
|
.over:
|
||||||
|
|
||||||
|
[section .bss]
|
||||||
|
padding: resb 128
|
||||||
|
energized: resb 128*128
|
||||||
|
|
||||||
|
[section .rodata]
|
||||||
|
what_the_fuck: db "Something is terribly wrong in this world."
|
||||||
|
.over:
|
||||||
|
ansi_color_reset: db `\e[0m`
|
||||||
|
.over:
|
||||||
|
ansi_color_green: db `\e[0;32m`
|
||||||
|
.over:
|
||||||
|
ansi_color_highbold_green: db `\e[1;92m`
|
||||||
|
.over:
|
Loading…
Reference in New Issue
Block a user