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