224 lines
4.3 KiB
NASM
224 lines
4.3 KiB
NASM
// vim: filetype=kickass
|
|
|
|
* = * "Day 01"
|
|
|
|
|
|
//
|
|
// day01
|
|
//
|
|
// Destroys:
|
|
// a, x, y, $02..$04, $10..$1c, $20..$25, $fd..$fe, everything you've ever loved
|
|
//
|
|
.const input_pointer = $20
|
|
.const atoi_result = $03 // Needs to be $03 for tree_insert
|
|
|
|
.const loop_pointer = $20
|
|
.const remainder = $24
|
|
|
|
// Need to be $26 and $fd due to multiply_16bit_unsigned
|
|
.const outer_value = $26
|
|
.const inner_value = $fd
|
|
|
|
day01:
|
|
jsr tree_clear
|
|
|
|
move_16_imm($03, str_title)
|
|
jsr write_string
|
|
|
|
//
|
|
// Parse the input at day01_input into an array of integers.
|
|
//
|
|
move_16_imm(input_pointer, day01_input)
|
|
ldy #0
|
|
|
|
lda #0
|
|
sta zp_temp
|
|
|
|
!line:
|
|
// Create a temporary 16-bit integer to store the result in
|
|
// in between digits.
|
|
move_16_imm(atoi_result, 0)
|
|
|
|
!digit:
|
|
// Check for the newline character at the end of the line.
|
|
lda (input_pointer), y
|
|
cmp #'\n'
|
|
beq !newline+
|
|
|
|
// Multiply the stored number by 10.
|
|
i16_mul10(atoi_result)
|
|
|
|
// Subtract '0' from the current digit to convert it to "binary".
|
|
lda (input_pointer), y
|
|
sec
|
|
sbc #'0'
|
|
|
|
// Add the binary digit to the stored number
|
|
i16_i8_add_a(atoi_result)
|
|
|
|
// Increment y.
|
|
iny
|
|
bne !digit-
|
|
|
|
// If y overflows, increment the MSB of the input pointer as well,
|
|
// for a 16-bit increment.
|
|
inc input_pointer + 1
|
|
jmp !digit-
|
|
|
|
!newline:
|
|
// Insert the converted number into the tree.
|
|
jsr tree_insert
|
|
|
|
iny
|
|
bne !+
|
|
inc input_pointer + 1
|
|
!:
|
|
|
|
// Check for the null terminator.
|
|
lda (input_pointer), y
|
|
bne !line-
|
|
|
|
//
|
|
// Part 1
|
|
//
|
|
ldy #0
|
|
!loop:
|
|
// Subtract the number from 2020 to find the needed value.
|
|
lda tree_values_lo, y
|
|
sta $fd
|
|
eor #$ff
|
|
sec
|
|
adc #<2020
|
|
sta $03
|
|
sta $26
|
|
|
|
lda tree_values_hi, y
|
|
sta $fe
|
|
eor #$ff
|
|
adc #>2020
|
|
sta $04
|
|
sta $27
|
|
|
|
iny
|
|
jsr tree_contains
|
|
bne !loop-
|
|
|
|
// Multiply the results together
|
|
sec
|
|
jsr multiply_16bit_unsigned
|
|
|
|
// Print the 32-bit result as decimal.
|
|
lda $25
|
|
sta udivmod32_dividend + 3
|
|
lda $24
|
|
sta udivmod32_dividend + 2
|
|
lda $23
|
|
sta udivmod32_dividend + 1
|
|
lda $22
|
|
sta udivmod32_dividend + 0
|
|
jsr print_decimal_u32
|
|
|
|
move_16_imm($03, str_part2)
|
|
jsr write_string
|
|
|
|
.const val_a = $26
|
|
.const val_b = $fd
|
|
.const val_c = $44
|
|
.const val_temp = $46
|
|
.const outer_i = $1f
|
|
|
|
//
|
|
// Part 2
|
|
//
|
|
ldx #0
|
|
!outer_loop:
|
|
ldy #0
|
|
lda tree_values_lo, x
|
|
sta val_a + 0
|
|
lda tree_values_hi, x
|
|
sta val_a + 1
|
|
stx outer_i
|
|
|
|
!inner_loop:
|
|
// Subtract the numbers from 2020 to find the needed value.
|
|
lda tree_values_lo, y
|
|
sta val_b + 0
|
|
bne !not_zero+
|
|
|
|
lda tree_values_hi, y
|
|
bne !not_zero+
|
|
ldx outer_i
|
|
inx
|
|
bne !outer_loop-
|
|
!not_zero:
|
|
|
|
lda tree_values_hi, y
|
|
sta val_b + 1
|
|
|
|
lda val_a + 0
|
|
clc
|
|
adc val_b + 0
|
|
sta val_temp + 0
|
|
|
|
lda val_a + 1
|
|
adc val_b + 1
|
|
sta val_temp + 1
|
|
|
|
lda val_temp + 0
|
|
eor #$ff
|
|
sec
|
|
adc #<2020
|
|
sta $03
|
|
sta val_c + 0
|
|
|
|
lda val_temp + 1
|
|
eor #$ff
|
|
adc #>2020
|
|
sta $04
|
|
sta val_c + 1
|
|
|
|
iny
|
|
jsr tree_contains
|
|
bne !inner_loop-
|
|
|
|
// Multiply the three numbers together
|
|
sec
|
|
jsr multiply_16bit_unsigned
|
|
|
|
u16_u16_move($30, $22)
|
|
u16_u16_move($32, $24)
|
|
|
|
u16_u16_move($34, val_c)
|
|
move_16_imm($36, 0)
|
|
|
|
jsr multiply_32bit_unsigned
|
|
|
|
// Print the 32-bit result as decimal.
|
|
u16_u16_move(udivmod32_dividend, $38)
|
|
u16_u16_move(udivmod32_dividend + 2, $3a)
|
|
u16_u16_move(udivmod32_dividend + 4, $3c)
|
|
u16_u16_move(udivmod32_dividend + 6, $3e)
|
|
jsr print_decimal_u32
|
|
|
|
move_16_imm($03, str_done)
|
|
jsr write_string
|
|
|
|
rts
|
|
|
|
|
|
str_title:
|
|
.text "# Day 01"
|
|
.byte '\n', '\n'
|
|
.text "Part 1: "
|
|
.byte 0
|
|
|
|
str_part2:
|
|
.byte '\n'
|
|
.text "Part 2: "
|
|
.byte 0
|
|
|
|
str_done:
|
|
.byte '\n', '\n'
|
|
.text "* Done"
|
|
.byte '\n', 0
|