Skip to content

Instantly share code, notes, and snippets.

@tcsullivan
Created January 18, 2025 14:18
Show Gist options
  • Select an option

  • Save tcsullivan/7a194ff91975e2c3e9e3ba96141e045f to your computer and use it in GitHub Desktop.

Select an option

Save tcsullivan/7a194ff91975e2c3e9e3ba96141e045f to your computer and use it in GitHub Desktop.
Breakdown of day 3 solution for Advent of Code 2024
\ "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