From 8467b7c9a052ba4bfe7910726fcf6912cfe469ec Mon Sep 17 00:00:00 2001 From: Sijmen Schoon Date: Wed, 9 Dec 2020 13:27:21 +0100 Subject: [PATCH] Implement binary search tree and base day1a on it --- c64/btree.asm | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ c64/day01.asm | 102 +++++++++++++----------------------------------- c64/main.asm | 81 +++++++++++++++++++++++++++++++++++--- 3 files changed, 208 insertions(+), 81 deletions(-) create mode 100644 c64/btree.asm diff --git a/c64/btree.asm b/c64/btree.asm new file mode 100644 index 0000000..56e096e --- /dev/null +++ b/c64/btree.asm @@ -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 diff --git a/c64/day01.asm b/c64/day01.asm index ef84589..7b01f33 100644 --- a/c64/day01.asm +++ b/c64/day01.asm @@ -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 remainder = $24 +.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 -!: + 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 - iny - lda (outer_pointer), y - sta outer_value + 1 + !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 - dey - lda (outer_pointer), y - bne !not_zero+ - iny - lda (outer_pointer), y - bne !not_zero+ - jmp !error+ -!not_zero: + lda tree_values_hi, y + sta $fe + eor #$ff + adc #>2020 + sta $04 + sta $27 - // Subtract from 2020 to see what number we need - i16_imm_i16_sub(remainder, 2020, outer_value) + iny + jsr tree_contains + bne !loop- -!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 diff --git a/c64/main.asm b/c64/main.asm index 507dfeb..dc37dba 100644 --- a/c64/main.asm +++ b/c64/main.asm @@ -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: