255 lines
4.1 KiB
ArmAsm
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
|