// 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 = $03 .const buffer_pointer = $20 .const atoi_result = $22 .const outer_pointer = $20 .const inner_pointer = $22 .const remainder = $24 // Need to be $03 and $fd due to multiply_16bit_unsigned .const outer_value = $03 .const inner_value = $fd day01: 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) move_16_imm(buffer_pointer, buffer) ldy #0 !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: sty zp_temp // 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 bne !line- 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 dey lda (outer_pointer), y bne !not_zero+ iny lda (outer_pointer), y bne !not_zero+ .break 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 move_16_imm($03, str_calc_done) jsr write_string // 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 rts !error: move_16_imm($03, str_no_result) jsr write_string rts str_title: .text "# Day 01, part 1:" .byte '\n', 0 str_parse_done: .text "* Finished parsing" .byte '\n', 0 str_calc_done: .text "* Finished calculating" .byte '\n', 0 str_no_result: .byte '\n' .text "! Could not find a result" .byte '\n', 0