Created
January 18, 2025 14:18
-
-
Save tcsullivan/7a194ff91975e2c3e9e3ba96141e045f to your computer and use it in GitHub Desktop.
Breakdown of day 3 solution for Advent of Code 2024
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| \ "string =", really a "starts with" check. Returns true if the first u2 characters | |
| \ in c-addr2 match c-addr1. | |
| : s= ( c-addr1 c-addr2 u2 -- b ) | |
| tuck compare 0= ; | |
| \ Reads up to 99 digits from c-addr and parses them into a number. Returns the number | |
| \ and c-addr2 which points to the character beyond the parsed number. | |
| : get-number ( c-addr -- n c-addr2 ) | |
| 99 0 s>d 2swap >number rot 2drop ; | |
| \ Solves day 3, returning the part 1 and part 2 answers. | |
| : scan-chars ( c-addr u -- n n ) | |
| 0 0 \ These will accumulate our two answers | |
| 2swap \ Stick the answers in the back of the stack | |
| 1 -rot \ Add a "mul() enable" flag to the stack | |
| \ Stack is now: p2-answer p1-answer mul-enable c-addr u | |
| over + swap do \ Convert `c-addr u` to a range that we iterate over with DO | |
| \ `i` will point to the current character in this range | |
| i s" do()" s= if drop 1 then \ If the string at `i` starts with "do()", set mul-enable to 1 | |
| \ Remember that S" pushes c-addr and u for the given string | |
| i s" don't()" s= if drop 0 then \ If the string starts with "don't()", set mul-enable to 0 | |
| i s" mul(" s= if \ If the string starts with "mul(" ... | |
| i 4 + get-number \ Advance `i` by 4 for the first number's location, then parse it | |
| dup c@ [char] , = if \ Sanity check: does the returned c-addr (beyond the number) point to a comma? | |
| 1+ get-number \ Increment the c-addr to parse the second number | |
| c@ [char] ) = if \ Confirm that a ')' comes after the second number (no dup since c-addr is no longer needed) | |
| \ Stack is now: p1-answer p1-answer mul-enable number1 number2 | |
| * \ Multiply number1 and number2. Need to add product to p1-answer (always) and p2-answer (if mul-enable) | |
| rot \ Stack: p2-answer mul-enable product p1-answer | |
| over + \ Stack: p2-ansewr mul-enable product (p1-answer+product) | |
| >r \ Stash new p1-answer on return stack. Stack: p2-answer mul-enable product | |
| over >r \ Stash mul-enable on return stack. | |
| * \ Multiply mul-enable and product, giving either product or zero if mul is disabled. | |
| + \ Stack: (p2-answer+product) | |
| 2r> \ Bring back p1-answer and mul-enable. 2R> has implicit swap, i.e. "R> R> SWAP" | |
| \ Stack is now: new-p2-answer new-p1-answer mul-enable | |
| else 2drop then \ No second number: drop the (invalid) second number and the first number | |
| else 2drop then \ No first number: drop our c-addr and the (invalid) first number | |
| then loop \ Stack is now: p2-answer p1-answer mul-enable | |
| drop ; \ Stack at return is: p2-answer p1-answer | |
| s" input" r/o open-file throw \ Open the input file (note: no file extension) | |
| dup file-size throw d>s \ Get the file's total size | |
| here swap rot read-file throw \ Read the entire file to HERE | |
| here swap scan-chars \ Pass HERE and character count from READ-FILE to scan-chars | |
| ." Part 1: " . cr | |
| ." Part 2: " . cr | |
| bye |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment