Commit 07e68e19 by Peter Fidelman

### Day 9

parent 097b4dee
 ... ... @@ -136,4 +136,21 @@ Finally, the data structures I am using are extremely simple: ... 00000000 -- binary representation of digit #9 ... (10 bytes total) ``` \ No newline at end of file ``` # Day 9 ## Part A The trick here is the boundary behavior -- trying to read off the edge of the board should be treated exactly the same as reading a '9'. 2-D indexing is a huge pain in Forth, so I wanted a simpler way to track the board edges. Here's what I sound up doing. - **For the left and right edges** - When reading input, pad each line with a leading '9'. The empty line at the end of input also counts as a "line" so the effect of this logic is to '9'-delimit the input lines and the first and last character of the board will both wind up as '9's too. - **For the top and bottom edges** - Clamp out-of-range addresses to first or last character of board, which are now guaranteed to be 9's. The result: x,y coordinates are now largely irrelevant and we can just traverse every square without worrying about boundary conditions. The check of each square against its neighbors is very simple and there is probably a more elegant way of writing it, especially in Part B where significant code duplication creeps in. ## Part B Same as above, but when I find a low point I kick off a recursive flood-fill there and track how many squares I filled (see `basinsize`). Once the basin size is known, I store it in the minimum index of a 3-long ascended-sorted array, and re-sort that array to ensure the least of these top-3 values winds up in the minimum index again ripe for replacement. At the end of traversal I multiply together the top three values to get the answer. \ No newline at end of file
 variable (padend) : padend ( a ) (padend) @ ; variable stride : 9! ( a -- a+1 ) 57 over c! 1+ ; : line>> ( a -- a n ) 9! dup -1 1 >> accept ; : stride! ( n -- n ) dup 1+ stride ! ; : get-lines ( -- ) pad begin line>> dup if stride! + 0 else drop -1 then until (padend) ! ; : clamp@ ( a -- c ) pad max padend min c@ ; : r and and and if r> c@ 47 - + else rdrop then loop ." Answer:" . ;
 variable (padend) : padend ( a ) (padend) @ ; variable stride : 9! ( a -- a+1 ) 57 over c! 1+ ; : line>> ( a -- a n ) 9! dup -1 1 >> accept ; : stride! ( n -- n ) dup 1+ stride ! ; : get-lines ( -- ) pad begin line>> dup if stride! + 0 else drop -1 then until (padend) ! ; : clamp ( a -- c ) pad max padend 1- min ; : left ( a -- a' ) 1- clamp ; : right ( a -- a' ) 1+ clamp ; : above ( a -- a' ) stride @ - clamp ; : below ( a -- a' ) stride @ + clamp ; : r r@ 2@ 2dup < if swap then r> 2! ; : sort ( a -- ) dup cell+ pivot dup pivot cell+ pivot ; variable basinsize : basin ( a -- ) dup c@ 57 = if drop else 1 basinsize +! dup 48 swap c! ( so we don't ascend two paths to the same place ) if basinsize @ top-sizes ! top-sizes sort then ; : go ( -- ) get-lines padend pad do i r and and and if r> do-basin else rdrop then loop top-sizes 2 cells + @ top-sizes 2@ * * ." Answer:" . ;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment