mirror of
https://github.com/chylex/Advent-of-Code.git
synced 2024-10-17 02:42:45 +02:00
133 lines
3.2 KiB
NASM
133 lines
3.2 KiB
NASM
bits 64
|
|
default rel
|
|
|
|
section .text
|
|
|
|
extern print
|
|
global entryPoint
|
|
|
|
entryPoint:
|
|
push rbp
|
|
mov rbp, rsp
|
|
|
|
push rbx
|
|
push r12
|
|
push r13
|
|
sub rsp, 32
|
|
|
|
; rax = reserved for math
|
|
; rdx = reserved for math
|
|
|
|
; rbx = value of current character of input string
|
|
; rcx = pointer to current character of input string
|
|
; r8 = return value for nextNumber
|
|
; r9 = first dimension
|
|
; r10 = second dimension
|
|
; r11 = third dimension
|
|
; r12 = total wrapping paper required
|
|
; r13 = total ribbon length required
|
|
|
|
xor rdx, rdx
|
|
xor r12, r12
|
|
xor r13, r13
|
|
|
|
.nextLine:
|
|
call .nextNumber
|
|
mov r9, r8 ; save first dimension to r9
|
|
call .nextNumber
|
|
mov r10, r8 ; save second dimension to r10
|
|
call .nextNumber
|
|
mov r11, r8 ; save third dimension to r11
|
|
|
|
.sort1: ; initiate bubble sort of the three dimensions (possible configurations 123; 132; 213; 231; 312; 321)
|
|
cmp r9, r10 ; compare first pair of dimensions
|
|
jb .sort2 ; if they are already sorted, skip ahead (123; 132; 231)
|
|
xchg r9, r10 ; otherwise, swap the first pair (213->123; 312->132; 321->231)
|
|
.sort2:
|
|
cmp r10, r11 ; compare last pair of dimensions
|
|
jb .sort3 ; if they are already sorted, skip ahead (123)
|
|
xchg r10, r11 ; otherwise, swap the last pair (132->123; 231->213)
|
|
.sort3:
|
|
cmp r9, r10 ; compare first pair of dimensions again in case the smallest number started at the end and was moved to second position
|
|
jb .sortEnd ; if they are already sorted, skip ahead (123)
|
|
xchg r9, r10 ; otherwise, swap the first pair (213->123)
|
|
.sortEnd: ; at this point, the dimensions are sorted from smallest to largest in registers r9, r10, r11
|
|
|
|
mov rax, 2
|
|
mul r9
|
|
mul r10
|
|
add r12, rax ; add 2 * dim1 * dim2 to wrapping paper length
|
|
|
|
mov rax, 2
|
|
mul r9
|
|
mul r11
|
|
add r12, rax ; add 2 * dim1 * dim3 to wrapping paper length
|
|
|
|
mov rax, 2
|
|
mul r10
|
|
mul r11
|
|
add r12, rax ; add 2 * dim2 * dim3 to wrapping paper length
|
|
|
|
mov rax, r9
|
|
mul r10
|
|
add r12, rax ; add square area of smallest side to wrapping paper length
|
|
|
|
add r13, r9
|
|
add r13, r9
|
|
add r13, r10
|
|
add r13, r10 ; add smallest perimeter to the ribbon length
|
|
|
|
mov rax, r9
|
|
mul r10
|
|
mul r11
|
|
add r13, rax ; add volume of the present to the ribbon length
|
|
|
|
movzx rbx, byte [ rcx ] ; read current character
|
|
cmp bl, 0 ; if we have not reached end of string yet,
|
|
jne .nextLine ; go read the next line
|
|
|
|
lea rcx, [ print_wrapping_paper ]
|
|
mov rdx, r12
|
|
call print
|
|
|
|
lea rcx, [ print_ribbon_length ]
|
|
mov rdx, r13
|
|
call print
|
|
|
|
add rsp, 32
|
|
pop r13
|
|
pop r12
|
|
pop rbx
|
|
|
|
leave
|
|
ret
|
|
|
|
.nextNumber:
|
|
xor r8, r8 ; reset return value to zero
|
|
|
|
.nextDigit:
|
|
movzx rbx, byte [ rcx ] ; read current character
|
|
inc rcx ; move to next character
|
|
|
|
cmp bl, '0'
|
|
jb .nonDigitCharacter
|
|
cmp bl, '9'
|
|
ja .nonDigitCharacter
|
|
|
|
mov rax, 10
|
|
mul r8 ; shift digit accumulator by one decimal place
|
|
mov r8, rax ; move multiplied result back to digit accumulator
|
|
|
|
sub rbx, '0' ; convert ASCII to digit
|
|
add r8, rbx ; add digit to accumulator
|
|
|
|
jmp .nextDigit
|
|
|
|
.nonDigitCharacter:
|
|
ret ; return from nextNumber calls
|
|
|
|
section .data
|
|
|
|
print_wrapping_paper: db `Wrapping paper required: %d\n`, 0
|
|
print_ribbon_length: db `Ribbon length required: %d\n`, 0
|