adventofcode2023/07/main_part1.s
2023-12-07 01:21:29 -06:00

255 lines
4.1 KiB
ArmAsm

global _start
[bits 32]
[section .text]
%include "utils.s"
; for h in hands
; ; score hands
; tmp := 0
; counts[15] := [0; 15]
; for c in h
; if c > '9'
; if c = 'T' then score := 10
; elif c = 'J' then score := 11
; elif c = 'Q' then score := 12
; elif c = 'K' then score := 13
; elif c = 'A' then score := 14
; else
; score := c - '0'
; end
; tmp := (tmp * 14) + score
; put in counts
; end
; ; check hand type
; has_five := 0
; has_four := 0
; has_three := 0
; has_two := 0
; for n in counts
; if n = 5 then inc has_five
; if n = 4 then inc has_four
; if n = 3 then inc has_three
; if n = 2 then inc has_two
; end
; if has_five then tmp := tmp + 60,000,000
; elif has_four then tmp := tmp + 50,000,000
; elif has_three and has_two then tmp := tmp + 40,000,000
; elif has_three then tmp := tmp + 30,000,000
; elif has_two = 2 then tmp := tmp + 20,000,000
; elif has_two = 1 then tmp := tmp + 10,000,000
; ; store tmp in array
; stosd tmp -> hand_array
; stosd bid -> hand_array
; end
;
; bubble sort hand_array
;
; calc total
; rank := 1
; for (_, bid) in hand_array
; final_value += rank * bid
; rank += 1
; end
;
; done
_start:
mov esi, file
mov edi, hand_array
; for l in lines
; ...
; end
for_in_lines:
; check for end
cmp esi, file.over
jae for_in_lines_end
; score hand
; tmp := 0
xor ebp, ebp ; tmp
; counts[15] := [0; 15]
push edi
mov edi, counts
mov ecx, 15
xor eax, eax
rep stosb
pop edi
get_hand_score:
; do 5 times
; ...
; end
mov ecx, 5
xor ebx, ebx ; char value
.next_char:
lodsb
; if c > '9'
cmp al, '9'
jle .is_num
mov edx, 10
cmp al, 'T'
cmove ebx, edx
mov edx, 11
cmp al, 'J'
cmove ebx, edx
mov edx, 12
cmp al, 'Q'
cmove ebx, edx
mov edx, 13
cmp al, 'K'
cmove ebx, edx
mov edx, 14
cmp al, 'A'
cmove ebx, edx
jmp .add_to_tmp
.is_num:
; else val := c - '0'
sub al, '0'
movzx ebx, al
; end
.add_to_tmp:
; tmp *= 14
; tmp += score
mov eax, ebp
mov edx, 14
mul edx
add eax, ebx
mov ebp, eax
; put in counts
inc byte [counts+ebx]
loop .next_char
; check hand type
mov byte [has_five], 0
mov byte [has_four], 0
mov byte [has_three], 0
mov byte [has_two], 0
; for n in counts
mov ecx, 15
push esi ; save line
mov esi, counts
check_counts:
lodsb
cmp al, 5
jne .check_4
inc byte [has_five]
.check_4:
cmp al, 4
jne .check_3
inc byte [has_four]
.check_3:
cmp al, 3
jne .check_2
inc byte [has_three]
.check_2:
cmp al, 2
jne .check_cont
inc byte [has_two]
.check_cont:
loop check_counts
; end
pop esi ; restore line
cmp byte [has_five], 0
je .maybe_four
add ebp, 60000000
jmp .save
.maybe_four:
cmp byte [has_four], 0
je .maybe_three
add ebp, 50000000
jmp .save
.maybe_three:
cmp byte [has_three], 0
je .maybe_twos
add ebp, 30000000
.maybe_twos:
mov cl, byte [has_two]
cmp cl, 0
je .save
mov eax, 10000000/2
shl eax, cl
add ebp, eax
.save:
; store tmp & bid in array
mov eax, ebp
stosd
inc esi ; skip space
call dec_parse ; bid
stosd
for_in_lines_cont:
jmp for_in_lines
for_in_lines_end:
; bubble sort hand_array
bubble_sort:
; get length (array is null terminated)
mov esi, hand_array
xor eax, eax
get_len:
cmp dword [esi+eax*8], 0
je .done
inc eax
jmp get_len
.done:
mov ebp, eax ; n
do_sort:
xor edx, edx ; newn
mov ecx, 1 ; i
.inner:
mov eax, [esi+ecx*8-8] ; A[i-1]
cmp eax, [esi+ecx*8] ; A[i]
jbe .inner_cont
; swap elements
xchg eax, [esi+ecx*8]
mov [esi+ecx*8-8], eax
mov eax, [esi+ecx*8-4] ; A[i-1] bid
xchg eax, [esi+ecx*8+4] ; A[i] bid
mov [esi+ecx*8-4], eax
mov edx, ecx ; newn
.inner_cont:
inc ecx
cmp ecx, ebp
jb .inner
mov ebp, edx ; n := newn
cmp ebp, 1
ja do_sort ; until n <= 1
done_sort:
; calc total
; rank := 1
mov ebx, 1
mov esi, hand_array
calc_total:
lodsd ; _
lodsd ; bid
test eax, eax
jz calc_total_done
mul ebx
add [final_value], eax
inc ebx
jmp calc_total
calc_total_done:
game_over:
mov eax, [final_value]
call print_dec
jmp exit
[section .data]
final_value: dd 0
counts: times 15 db 0
has_five: db 0
has_four: db 0
has_three: db 0
has_two: db 0
file_lim: dd file.over - file
file: incbin "input"
.over:
[section .bss]
hand_array: resd 4096