day 17 part 2 (almost, it's wrong)
This commit is contained in:
parent
d1478ac425
commit
3362719e79
422
17/main.s
Normal file
422
17/main.s
Normal file
@ -0,0 +1,422 @@
|
|||||||
|
%include "utils.s"
|
||||||
|
|
||||||
|
global _start
|
||||||
|
[bits 32]
|
||||||
|
[section .text]
|
||||||
|
|
||||||
|
; len +2 for padding
|
||||||
|
%define LINE_LEN (141+2)
|
||||||
|
%define FILENAME "input"
|
||||||
|
;%define LINE_LEN (13+2)
|
||||||
|
;%define FILENAME "input_test"
|
||||||
|
|
||||||
|
%define DBG_PRINT
|
||||||
|
|
||||||
|
_start:
|
||||||
|
|
||||||
|
; convert input file to useful data
|
||||||
|
mov esi, file
|
||||||
|
mov edi, cost
|
||||||
|
convert_input:
|
||||||
|
lodsb
|
||||||
|
cmp al, 10 ; \n
|
||||||
|
je .cont
|
||||||
|
cmp al, '$'
|
||||||
|
jne .num
|
||||||
|
mov al, 0xFF
|
||||||
|
stosb
|
||||||
|
jmp .cont
|
||||||
|
.num:
|
||||||
|
sub al, '0'
|
||||||
|
stosb
|
||||||
|
.cont:
|
||||||
|
cmp esi, file.over
|
||||||
|
jb convert_input
|
||||||
|
|
||||||
|
; im lazy so doing dijkstra
|
||||||
|
; thanks wikipedia
|
||||||
|
|
||||||
|
; for each vertex v in Graph.Vertices:
|
||||||
|
; dist[v] ← INFINITY
|
||||||
|
; prev[v] ← UNDEFINED
|
||||||
|
; add v to Q
|
||||||
|
mov ecx, LINE_LEN*LINE_LEN*32
|
||||||
|
mov eax, 0xffffffff
|
||||||
|
mov edi, dist
|
||||||
|
rep stosd
|
||||||
|
mov ecx, LINE_LEN*LINE_LEN*32
|
||||||
|
mov eax, 0xffffffff
|
||||||
|
mov edi, prev
|
||||||
|
rep stosd
|
||||||
|
mov ecx, LINE_LEN*LINE_LEN*32
|
||||||
|
mov eax, 1
|
||||||
|
mov edi, q
|
||||||
|
rep stosb
|
||||||
|
|
||||||
|
; for all real dir:
|
||||||
|
; dist[source@dir] ← 0
|
||||||
|
mov dword [dist+((((LINE_LEN*32)+(32*1)))|0b00_000)*4], 0
|
||||||
|
mov dword [dist+((((1*(LINE_LEN*32))+(32*1)))|0b10_000)*4], 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; while Q is not empty and any dist[u] in Q < inf:
|
||||||
|
; u ← vertex in Q with min dist[u]
|
||||||
|
while_q:
|
||||||
|
xor ebp, ebp ; test node
|
||||||
|
mov ecx, 0xffffffff ; best dist
|
||||||
|
mov edx, 0xffffffff ; best node
|
||||||
|
.find_min:
|
||||||
|
cmp byte [q+ebp], 1
|
||||||
|
jne .cont
|
||||||
|
cmp [dist+ebp*4], ecx
|
||||||
|
cmovb ecx, [dist+ebp*4]
|
||||||
|
cmovb edx, ebp
|
||||||
|
.cont:
|
||||||
|
inc ebp
|
||||||
|
cmp ebp, LINE_LEN*LINE_LEN*32
|
||||||
|
jb .find_min
|
||||||
|
cmp ecx, 0xffffffff
|
||||||
|
je while_q_done
|
||||||
|
|
||||||
|
%ifdef DBG_PRINT
|
||||||
|
pushad
|
||||||
|
call newline
|
||||||
|
mov ebp, edx
|
||||||
|
mov eax, edx
|
||||||
|
xor edx, edx
|
||||||
|
shr eax, 5
|
||||||
|
mov ebx, LINE_LEN
|
||||||
|
div ebx
|
||||||
|
call print_dec
|
||||||
|
call space
|
||||||
|
mov eax, edx
|
||||||
|
call print_dec
|
||||||
|
call space
|
||||||
|
mov eax, ebp
|
||||||
|
and eax, 0b11111
|
||||||
|
call print_dec
|
||||||
|
call space
|
||||||
|
mov eax, ecx
|
||||||
|
call print_dec
|
||||||
|
call newline
|
||||||
|
popad
|
||||||
|
%endif
|
||||||
|
|
||||||
|
; remove u from Q
|
||||||
|
mov byte [q+edx], 0
|
||||||
|
|
||||||
|
; for each neighbor v of u still in Q:
|
||||||
|
; alt ← dist[u] + Graph.Edges(u, v)
|
||||||
|
; if alt < dist[v]:
|
||||||
|
; dist[v] ← alt
|
||||||
|
; prev[v] ← u
|
||||||
|
mov ebp, LINE_LEN*32 ; whatever
|
||||||
|
for_neighbor:
|
||||||
|
; turning neighbor 0
|
||||||
|
neighbor_0:
|
||||||
|
; neighbors += v@dir(u, ~u.dir & 0b10_000)
|
||||||
|
mov ebx, edx
|
||||||
|
not ebx
|
||||||
|
and ebx, 0b10000
|
||||||
|
; tmp := 32
|
||||||
|
mov edi, 32
|
||||||
|
; bt dir, 4
|
||||||
|
bt ebx, 4
|
||||||
|
; if CF tmp := LINE_LEN
|
||||||
|
cmovc edi, ebp
|
||||||
|
; bt dir, 3
|
||||||
|
; if CF tmp := -tmp
|
||||||
|
mov esi, edi
|
||||||
|
neg esi
|
||||||
|
bt ebx, 3
|
||||||
|
cmovc edi, esi
|
||||||
|
mov eax, edi
|
||||||
|
; v.dir := dir
|
||||||
|
or edi, ebx
|
||||||
|
; v := u + tmp
|
||||||
|
; CheckBounds(v)
|
||||||
|
; Graph.Edges(u, v) := cost(v)
|
||||||
|
; v := v + tmp
|
||||||
|
; CheckBounds(v)
|
||||||
|
; Graph.Edges(u, v) += cost(v)
|
||||||
|
; v := v + tmp
|
||||||
|
; CheckBounds(v)
|
||||||
|
; Graph.Edges(u, v) += cost(v)
|
||||||
|
; v := v + tmp
|
||||||
|
; CheckBounds(v)
|
||||||
|
; Graph.Edges(u, v) += cost(v)
|
||||||
|
mov ebx, eax
|
||||||
|
mov esi, edx
|
||||||
|
and esi, ~0b11111
|
||||||
|
add edi, esi ; v := u + tmp
|
||||||
|
mov eax, edi
|
||||||
|
shr eax, 5
|
||||||
|
movzx eax, byte [cost+eax]
|
||||||
|
cmp al, 0xff
|
||||||
|
je neighbor_1 ; off graph
|
||||||
|
mov esi, eax ; Graph.Edges(u, v) := cost(v)
|
||||||
|
add edi, ebx ; v := v + tmp
|
||||||
|
mov eax, edi
|
||||||
|
shr eax, 5
|
||||||
|
movzx eax, byte [cost+eax]
|
||||||
|
cmp al, 0xff
|
||||||
|
je neighbor_1 ; off graph
|
||||||
|
add esi, eax ; Graph.Edges(u, v) += cost(v)
|
||||||
|
add edi, ebx ; v := v + tmp
|
||||||
|
mov eax, edi
|
||||||
|
shr eax, 5
|
||||||
|
movzx eax, byte [cost+eax]
|
||||||
|
cmp al, 0xff
|
||||||
|
je neighbor_1 ; off graph
|
||||||
|
add esi, eax ; Graph.Edges(u, v) += cost(v)
|
||||||
|
add edi, ebx ; v := v + tmp
|
||||||
|
mov eax, edi
|
||||||
|
shr eax, 5
|
||||||
|
movzx eax, byte [cost+eax]
|
||||||
|
cmp al, 0xff
|
||||||
|
je neighbor_1 ; off graph
|
||||||
|
add esi, eax ; Graph.Edges(u, v) += cost(v)
|
||||||
|
; alt ← dist[u] + cost(v)
|
||||||
|
; if alt < dist[v]:
|
||||||
|
; dist[v] ← alt
|
||||||
|
; prev[v] ← u
|
||||||
|
add esi, ecx
|
||||||
|
%ifdef DBG_PRINT
|
||||||
|
pushad
|
||||||
|
call space
|
||||||
|
mov esi, eax
|
||||||
|
mov eax, edi
|
||||||
|
shr eax, 5
|
||||||
|
mov ecx, LINE_LEN
|
||||||
|
xor edx, edx
|
||||||
|
div ecx
|
||||||
|
call print_dec
|
||||||
|
call space
|
||||||
|
mov eax, edx
|
||||||
|
call print_dec
|
||||||
|
call space
|
||||||
|
mov eax, edi
|
||||||
|
and eax, 0x1f
|
||||||
|
call print_dec
|
||||||
|
call space
|
||||||
|
mov eax, esi
|
||||||
|
call print_dec
|
||||||
|
call newline
|
||||||
|
popad
|
||||||
|
%endif
|
||||||
|
cmp esi, [dist+edi*4]
|
||||||
|
jae neighbor_1 ; not better
|
||||||
|
mov [dist+edi*4], esi
|
||||||
|
mov [prev+edi*4], edx
|
||||||
|
; turning neighbor 1
|
||||||
|
neighbor_1:
|
||||||
|
; neighbors += v@dir(u, (~u.dir & 0b10_000) | 0b01_000)
|
||||||
|
mov ebx, edx
|
||||||
|
not ebx
|
||||||
|
and ebx, 0b10000
|
||||||
|
or ebx, 0b01000
|
||||||
|
; tmp := 32
|
||||||
|
mov edi, 32
|
||||||
|
; bt dir, 4
|
||||||
|
bt ebx, 4
|
||||||
|
; if CF tmp := LINE_LEN
|
||||||
|
cmovc edi, ebp
|
||||||
|
; bt dir, 3
|
||||||
|
; if CF tmp := -tmp
|
||||||
|
mov esi, edi
|
||||||
|
neg esi
|
||||||
|
bt ebx, 3
|
||||||
|
cmovc edi, esi
|
||||||
|
mov eax, edi
|
||||||
|
; v.dir := dir
|
||||||
|
or edi, ebx
|
||||||
|
; v := u + tmp
|
||||||
|
; CheckBounds(v)
|
||||||
|
; Graph.Edges(u, v) := cost(v)
|
||||||
|
; v := v + tmp
|
||||||
|
; CheckBounds(v)
|
||||||
|
; Graph.Edges(u, v) += cost(v)
|
||||||
|
; v := v + tmp
|
||||||
|
; CheckBounds(v)
|
||||||
|
; Graph.Edges(u, v) += cost(v)
|
||||||
|
; v := v + tmp
|
||||||
|
; CheckBounds(v)
|
||||||
|
; Graph.Edges(u, v) += cost(v)
|
||||||
|
mov ebx, eax
|
||||||
|
mov esi, edx
|
||||||
|
and esi, ~0b11111
|
||||||
|
add edi, esi ; v := u + tmp
|
||||||
|
mov eax, edi
|
||||||
|
shr eax, 5
|
||||||
|
movzx eax, byte [cost+eax]
|
||||||
|
cmp al, 0xff
|
||||||
|
je neighbor_2 ; off graph
|
||||||
|
mov esi, eax ; Graph.Edges(u, v) := cost(v)
|
||||||
|
add edi, ebx ; v := v + tmp
|
||||||
|
mov eax, edi
|
||||||
|
shr eax, 5
|
||||||
|
movzx eax, byte [cost+eax]
|
||||||
|
cmp al, 0xff
|
||||||
|
je neighbor_2 ; off graph
|
||||||
|
add esi, eax ; Graph.Edges(u, v) += cost(v)
|
||||||
|
add edi, ebx ; v := v + tmp
|
||||||
|
mov eax, edi
|
||||||
|
shr eax, 5
|
||||||
|
movzx eax, byte [cost+eax]
|
||||||
|
cmp al, 0xff
|
||||||
|
je neighbor_2 ; off graph
|
||||||
|
add esi, eax ; Graph.Edges(u, v) += cost(v)
|
||||||
|
add edi, ebx ; v := v + tmp
|
||||||
|
mov eax, edi
|
||||||
|
shr eax, 5
|
||||||
|
movzx eax, byte [cost+eax]
|
||||||
|
cmp al, 0xff
|
||||||
|
je neighbor_2 ; off graph
|
||||||
|
add esi, eax ; Graph.Edges(u, v) += cost(v)
|
||||||
|
; alt ← dist[u] + cost(v)
|
||||||
|
; if alt < dist[v]:
|
||||||
|
; dist[v] ← alt
|
||||||
|
; prev[v] ← u
|
||||||
|
add esi, ecx
|
||||||
|
%ifdef DBG_PRINT
|
||||||
|
pushad
|
||||||
|
call space
|
||||||
|
mov esi, eax
|
||||||
|
mov eax, edi
|
||||||
|
shr eax, 5
|
||||||
|
mov ecx, LINE_LEN
|
||||||
|
xor edx, edx
|
||||||
|
div ecx
|
||||||
|
call print_dec
|
||||||
|
call space
|
||||||
|
mov eax, edx
|
||||||
|
call print_dec
|
||||||
|
call space
|
||||||
|
mov eax, edi
|
||||||
|
and eax, 0x1f
|
||||||
|
call print_dec
|
||||||
|
call space
|
||||||
|
mov eax, esi
|
||||||
|
call print_dec
|
||||||
|
call newline
|
||||||
|
popad
|
||||||
|
%endif
|
||||||
|
cmp esi, [dist+edi*4]
|
||||||
|
jae neighbor_2 ; not better
|
||||||
|
mov [dist+edi*4], esi
|
||||||
|
mov [prev+edi*4], edx
|
||||||
|
; straight - neighbor 2
|
||||||
|
neighbor_2:
|
||||||
|
mov ebx, edx
|
||||||
|
and ebx, ~0b11111
|
||||||
|
cmp edx, (((LINE_LEN*32)+(32*1)))
|
||||||
|
je while_q_cont
|
||||||
|
; if u.dir & 0b00_111 < 6
|
||||||
|
; neighbors += v@dir(u, u.dir + 1)
|
||||||
|
mov ebx, edx
|
||||||
|
and ebx, 0b00111
|
||||||
|
cmp ebx, 6
|
||||||
|
jae while_q_cont ; neighbors done
|
||||||
|
mov ebx, edx
|
||||||
|
and ebx, 0b11111
|
||||||
|
inc ebx
|
||||||
|
; tmp := 32
|
||||||
|
mov edi, 32
|
||||||
|
; bt dir, 4
|
||||||
|
bt ebx, 4
|
||||||
|
; if CF tmp := LINE_LEN
|
||||||
|
cmovc edi, ebp
|
||||||
|
; bt dir, 3
|
||||||
|
; if CF tmp := -tmp
|
||||||
|
mov esi, edi
|
||||||
|
neg esi
|
||||||
|
bt ebx, 3
|
||||||
|
cmovc edi, esi
|
||||||
|
; v := u + tmp
|
||||||
|
mov esi, edx
|
||||||
|
and esi, ~0b11111
|
||||||
|
add edi, esi
|
||||||
|
; v.dir := dir
|
||||||
|
or edi, ebx
|
||||||
|
; alt ← dist[u] + cost(v)
|
||||||
|
; if alt < dist[v]:
|
||||||
|
; dist[v] ← alt
|
||||||
|
; prev[v] ← u
|
||||||
|
mov eax, edi
|
||||||
|
shr eax, 5
|
||||||
|
movzx eax, byte [cost+eax]
|
||||||
|
cmp al, 0xff
|
||||||
|
je while_q_cont ; off graph
|
||||||
|
add eax, ecx
|
||||||
|
%ifdef DBG_PRINT
|
||||||
|
pushad
|
||||||
|
call space
|
||||||
|
mov esi, eax
|
||||||
|
mov eax, edi
|
||||||
|
shr eax, 5
|
||||||
|
mov ecx, LINE_LEN
|
||||||
|
xor edx, edx
|
||||||
|
div ecx
|
||||||
|
call print_dec
|
||||||
|
call space
|
||||||
|
mov eax, edx
|
||||||
|
call print_dec
|
||||||
|
call space
|
||||||
|
mov eax, edi
|
||||||
|
and eax, 0x1f
|
||||||
|
call print_dec
|
||||||
|
call space
|
||||||
|
mov eax, esi
|
||||||
|
call print_dec
|
||||||
|
call newline
|
||||||
|
popad
|
||||||
|
%endif
|
||||||
|
cmp eax, [dist+edi*4]
|
||||||
|
jae while_q_cont ; not better
|
||||||
|
mov [dist+edi*4], eax
|
||||||
|
mov [prev+edi*4], edx
|
||||||
|
|
||||||
|
while_q_cont:
|
||||||
|
jmp while_q
|
||||||
|
|
||||||
|
while_q_done:
|
||||||
|
|
||||||
|
call newline
|
||||||
|
|
||||||
|
; last dist values
|
||||||
|
mov ebx, ((((LINE_LEN-2)*(LINE_LEN*32))+((LINE_LEN-2)*32))+0b00000)
|
||||||
|
print_last_dist:
|
||||||
|
mov eax, [dist+ebx*4]
|
||||||
|
call print_sign_dec
|
||||||
|
inc ebx
|
||||||
|
mov ecx, ebx
|
||||||
|
and ecx, 0b111
|
||||||
|
cmp ecx, 0b111
|
||||||
|
jne .space
|
||||||
|
call newline
|
||||||
|
mov ecx, ebx
|
||||||
|
and ecx, 0b11111
|
||||||
|
cmp ecx, 0b11111
|
||||||
|
je .done
|
||||||
|
inc ebx
|
||||||
|
jmp .cont
|
||||||
|
.space:
|
||||||
|
call space
|
||||||
|
.cont:
|
||||||
|
jmp print_last_dist
|
||||||
|
.done:
|
||||||
|
|
||||||
|
game_over:
|
||||||
|
jmp exit
|
||||||
|
|
||||||
|
[section .data]
|
||||||
|
file: incbin FILENAME
|
||||||
|
.over:
|
||||||
|
|
||||||
|
[section .bss]
|
||||||
|
dist: resd LINE_LEN*LINE_LEN*32
|
||||||
|
prev: resd LINE_LEN*LINE_LEN*32
|
||||||
|
q: resb LINE_LEN*LINE_LEN*32
|
||||||
|
cost: resb LINE_LEN*LINE_LEN
|
||||||
|
new_file: resb len(file)
|
55
17/pseudo
55
17/pseudo
@ -1,37 +1,54 @@
|
|||||||
Graph.Edges(u@dir, v@dir) {
|
|
||||||
; if cost(v) = 0xff, we're off graph,
|
|
||||||
; in the padded area
|
|
||||||
Graph.Edges := cost(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
v@dir(u, dir) {
|
v@dir(u, dir) {
|
||||||
v.dir := dir
|
v.dir := dir
|
||||||
tmp := 1
|
tmp := 32
|
||||||
|
bt dir, 4
|
||||||
|
if CF
|
||||||
|
tmp := LINE_LEN*32
|
||||||
bt dir, 3
|
bt dir, 3
|
||||||
if CF
|
|
||||||
tmp := LINE_LEN
|
|
||||||
bt dir, 2
|
|
||||||
if CF
|
if CF
|
||||||
tmp := -tmp
|
tmp := -tmp
|
||||||
|
|
||||||
|
if dir & 0b0_111 = 0
|
||||||
v := u + tmp
|
v := u + tmp
|
||||||
|
CheckBounds(v)
|
||||||
|
Graph.Edges(u, v) := cost(v)
|
||||||
|
v := v + tmp
|
||||||
|
CheckBounds(v)
|
||||||
|
Graph.Edges(u, v) += cost(v)
|
||||||
|
v := v + tmp
|
||||||
|
CheckBounds(v)
|
||||||
|
Graph.Edges(u, v) += cost(v)
|
||||||
|
v := v + tmp
|
||||||
|
CheckBounds(v)
|
||||||
|
Graph.Edges(u, v) += cost(v)
|
||||||
|
else
|
||||||
|
v := u + tmp
|
||||||
|
CheckBounds(v)
|
||||||
|
Graph.Edges(u, v) := cost(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
neighbors(u@dir) {
|
neighbors(u@dir) {
|
||||||
; can always turn
|
; can always turn
|
||||||
neighbors += v@dir(u, ~u.dir & 0b1000)
|
neighbors += v@dir(u, ~u.dir & 0b10_000)
|
||||||
neighbors += v@dir(u, (~u.dir & 0b1000) | 0b0100)
|
neighbors += v@dir(u, (~u.dir & 0b10_000) | 0b01_000)
|
||||||
; can go forward if consec < 3
|
; can go forward if consec < 6
|
||||||
if u.dir & 0b0011 < 3
|
if u.dir & 0b00_111 < 6
|
||||||
neighbors += v@dir(u, u.dir + 1)
|
neighbors += v@dir(u, u.dir + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
; 12 possibilities, use 16 so we can do bit hacks
|
; 28 possibilities, use 32 so we can do bit hacks
|
||||||
; 0000 0001 0010 0011 0100 0101 0110 0111
|
; 00000 00001 00010 00011 00100 00101 00110 00111
|
||||||
; 0 1 2 3 4 5 6 7
|
; 0 1 2 3 4 5 6 7
|
||||||
dir = { R1, R2, R3, XX, L1, L2, L3, XX,
|
dir = { R4, R5, R6, R7, R8, R9, RA, XX,
|
||||||
; 1000 1001 1010 1011 1100 1101 1110 1111
|
; 01000 01001 01010 01011 01100 01101 01110 01111
|
||||||
; 8 9 10 11 12 13 14 15
|
; 8 9 10 11 12 13 14 15
|
||||||
D1, D2, D3, XX, U1, U2, U3, XX}
|
L4, L5, L6, L7, L8, L9, LA, XX,
|
||||||
|
; 10000 10001 10010 10011 10100 10101 10110 10111
|
||||||
|
; 16 17 18 19 20 21 22 23
|
||||||
|
D4, D5, D6, D7, D8, D9, DA, XX,
|
||||||
|
; 11000 11001 11010 11011 11100 11101 11110 11111
|
||||||
|
; 24 25 26 27 28 29 30 31
|
||||||
|
U4, U5, U6, U7, U8, U9, UA, XX}
|
||||||
|
|
||||||
dist[(x,y),dir]
|
dist[(x,y),dir]
|
||||||
prev[(x,y),dir]
|
prev[(x,y),dir]
|
||||||
|
Loading…
Reference in New Issue
Block a user