From e1496aa25aca7bef474150ef63c3b957e4aa39bb Mon Sep 17 00:00:00 2001 From: Joseph Montanaro Date: Fri, 6 Dec 2024 11:44:57 -0500 Subject: [PATCH] add 2024 day 3 part 1 --- 2024/03.fs | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 2024/03.fs diff --git a/2024/03.fs b/2024/03.fs new file mode 100644 index 0000000..7a6ed62 --- /dev/null +++ b/2024/03.fs @@ -0,0 +1,61 @@ +create data 20000 allot \ create a 20K buffer +variable fileid \ create a variable `fileid` +s" data/03.txt" r/o open-file \ open data file +drop \ drop the top value from the stack, it's just a status code and we aren't going to bother handling errors +fileid ! \ save the file id to the variable + +variable data-len +data 20000 fileid @ read-file +drop +data-len ! + +: data-str ( -- addr u ) + data data-len @ ; + +: chop-prefix ( addr u u2 -- addr2 u2 ) + \ chop the first `u2` bytes off the beginning of the string at `addr u` + tuck \ duplicate `u2` and store it "under" the length of the string + - \ subtract `u2` from the length of the string + -rot \ stick the new string length underneath the start pointer + + \ increment the start pointer by `u2` + swap \ put them back in the right order +; + +require regexp.fs + +: mul-instr ( addr u -- flag ) + (( =" mul(" \( {++ \d ++} \) ` , \( {++ \d ++} \) ` ) )) ; + + +: get-product ( addr u -- u2 ) + mul-instr \ match the string from `addr u` against the above regex + if \ if the regex matches, then: + \1 s>number drop \ convert the first capture from string to number, drop the status code (we already know it will succeed) + \2 s>number drop \ convert the second capture from string to number, drop the status code + * \ multiply, and leave the answer on the stack + else + 0 \ otherwise, leave 0 on the stack + then +; + +variable result +0 result ! + +: sum-mul-instrs ( addr u -- u2 ) + begin \ start looping + s" mul(" search \ search for the string "mul(" + if \ if successful, top 2 values on stack will be start address of "mul(" and remainder of original string + 2dup \ duplicate address and remaining length of string + get-product \ pass those to get-product above + result @ + \ load `result` and add to product + result ! \ store this new value back in `result` + 4 chop-prefix \ bump the start of the string by 4 characters + else \ if not successful, we have finished scanning through the string + 2drop \ dump the string address and length + result @ exit \ put the result on top of the stack and return to caller + then + again +; + +data-str sum-mul-instrs . +bye