Implement binary search tree and base day1a on it

This commit is contained in:
Sijmen 2020-12-09 13:27:21 +01:00
parent 438b622c58
commit 8467b7c9a0
Signed by: vijfhoek
GPG key ID: DAF7821E067D9C48
3 changed files with 208 additions and 81 deletions

106
c64/btree.asm Normal file
View file

@ -0,0 +1,106 @@
// vim: filetype=kickass
.const next_index = $02
.const input = $03
// NOTE Assumes the tree is zeroed
tree_insert:
ldx #0
!loop:
lda tree_values_lo, x
bne !not_zero+
lda tree_values_hi, x
bne !not_zero+
// Insert the node
lda input
sta tree_values_lo, x
lda input + 1
sta tree_values_hi, x
inc next_index
rts
!not_zero:
sec
lda tree_values_lo, x
sbc input
lda tree_values_hi, x
sbc input + 1
bcc !greater+
!less:
lda tree_left, x
bne !+
lda next_index
sta tree_left, x
!:
lda tree_left, x
tax
jmp !loop-
!greater:
lda tree_right, x
bne !+
lda next_index
sta tree_right, x
!:
lda tree_right, x
tax
jmp !loop-
brk
tree_contains:
ldx #0
!loop:
sec
lda tree_values_lo, x
sbc input
beq !lo_eq+
lda tree_values_hi, x
sbc input + 1
bcc !greater+
!less:
lda tree_left, x
beq !not_found+
tax
jmp !loop-
!greater:
lda tree_right, x
beq !not_found+
tax
jmp !loop-
!not_found:
// Match not found, set 1 so bne branches
lda #1
rts
!lo_eq:
lda tree_values_hi, x
sbc input + 1
bne !less-
// Match found, set 0 so beq branches
lda #0
rts
brk
.align $100
tree_values_lo:
.fill 256, 0
tree_values_hi:
.fill 256, 0
tree_left:
.fill 256, 0
tree_right:
.fill 256, 0

View file

@ -9,15 +9,13 @@
// Destroys:
// a, x, y, $02..$04, $10..$1c, $20..$25, $fd..$fe, everything you've ever loved
//
.const input_pointer = $03
.const buffer_pointer = $20
.const atoi_result = $22
.const input_pointer = $20
.const atoi_result = $03 // Needs to be $03 for tree_insert
.const outer_pointer = $20
.const inner_pointer = $22
.const loop_pointer = $20
.const remainder = $24
// Need to be $03 and $fd due to multiply_16bit_unsigned
// Need to be $26 and $fd due to multiply_16bit_unsigned
.const outer_value = $26
.const inner_value = $fd
@ -29,7 +27,6 @@ day01:
// Parse the input at day01_input into an array of integers.
//
move_16_imm(input_pointer, day01_input)
move_16_imm(buffer_pointer, buffer)
ldy #0
!line:
@ -64,26 +61,13 @@ day01:
jmp !digit-
!newline:
sty zp_temp
// Insert the converted number into the tree.
jsr tree_insert
// Append the result of the conversion to the array.
ldy #0
lda atoi_result + 0
sta (buffer_pointer), y
iny
lda atoi_result + 1
sta (buffer_pointer), y
// Increment the buffer pointer by 2.
lda #2
i16_i8_add_a(buffer_pointer)
ldy zp_temp
iny
bne !+
inc input_pointer + 1
!:
!:
// Check for the null terminator.
lda (input_pointer), y
@ -92,60 +76,28 @@ day01:
move_16_imm($03, str_parse_done)
jsr write_string
move_16_imm(outer_pointer, buffer)
// Add every number to every other number
!outer:
move_16_imm(inner_pointer, buffer)
// $03..$04 = buffer[i]
ldy #0
lda (outer_pointer), y
sta outer_value
!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
lda (outer_pointer), y
sta outer_value + 1
jsr tree_contains
bne !loop-
dey
lda (outer_pointer), y
bne !not_zero+
iny
lda (outer_pointer), y
bne !not_zero+
jmp !error+
!not_zero:
// Subtract from 2020 to see what number we need
i16_imm_i16_sub(remainder, 2020, outer_value)
!inner:
// $fd..$fe = buffer[j]
ldy #0
lda (inner_pointer), y
sta inner_value
iny
lda (inner_pointer), y
sta inner_value + 1
dey
lda (inner_pointer), y
bne !not_zero+
iny
lda (inner_pointer), y
bne !not_zero+
i16_inc(outer_pointer)
jmp !outer-
!not_zero:
// j++
lda #2
i16_i8_add_a(inner_pointer)
// Continue the loop if the number didn't match the needed number.
i16_i16_cmp_bne(remainder, inner_value, !inner-)
!done:
// Multiply the results together
sec
jsr multiply_16bit_unsigned

View file

@ -4,7 +4,7 @@
BasicUpstart2(main)
* = $0900 "Main program"
* = $1000 "Main program"
.const SCREEN_RAM = $0400
.const COLOR_RAM = $d800
@ -43,6 +43,77 @@
sta dst + i
}
}
test_tree:
move_16_imm($03, !str_test+)
jsr write_string
move_16_imm($03, $10)
jsr tree_insert
move_16_imm($03, $08)
jsr tree_insert
move_16_imm($03, $04)
jsr tree_insert
move_16_imm($03, $12)
jsr tree_insert
move_16_imm($03, $1337)
jsr tree_insert
move_16_imm($03, $08)
jsr tree_contains
bne !fail+
move_16_imm($03, $13)
jsr tree_contains
beq !fail+
move_16_imm($03, $12)
jsr tree_contains
bne !fail+
move_16_imm($03, $1337)
jsr tree_contains
bne !fail+
move_16_imm($03, $0420)
jsr tree_contains
beq !fail+
move_16_imm($03, !str_success+)
jsr write_string
rts
!fail:
u16_u16_move($10, $03)
move_16_imm($03, !str_fail+)
jsr write_string
lda $11
jsr print_hex_0x
lda $10
jsr print_hex
jsr print_newline
rts
!str_test:
.text "[ ] test-tree"
.byte '\r', 0
!str_fail:
.text "[!!]"
.byte '\n'
.text "Failed: "
.byte 0
!str_success:
.text "[OK]"
.byte '\n', 0
//
// main
//
@ -55,21 +126,19 @@ main:
sta $01
jsr generate_multiplication_tables
//jsr test_tree
jsr day01
!loop:
jmp !loop-
buffer:
.fill $0400, 0
#import "day01.asm"
#import "screen.asm"
#import "math.asm"
#import "btree.asm"
* = * "Day 01 Input"
day01_input: