Commit 3925023b authored by Peter Fidelman's avatar Peter Fidelman
Browse files

Day 10

parent 09edcddd
......@@ -153,4 +153,22 @@ The result: x,y coordinates are now largely irrelevant and we can just traverse
The check of each square against its neighbors is naively written and there is probably a more elegant way of doing 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
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.
# Day 10
## Part A
I maintain a stack of expected closing delimiters. Every time I see an opening delimiter in the input, I figure out what the corresponding closing delimiter should be and push it to the stack. Every time I see a closing delimiter in the input, I pop off the top item of the stack and compare this to what I actually saw.
In `->closing`, note that the ASCII difference between opening and closing parens '(' -> ')' is 1, but the ASCII difference between opening and closing square, curly and angle brackets is, unfortunately, 2.
In `rank`, note the messy nested-if to calculate the point values for each syntax error -- if there was a closed form solution for these scores I didn't find it.
After parsing the inputs with `go`, type `report` to get your answer.
## Part B
Heh, I knew there was a reason to write an `?empty` function for my stack in Part A, even though it wasn't needed yet. Getting the matching delimiters is as simple as popping them off this stack until it's empty.
The highlight (or rather lowlight) of the problem is calculating the median score. Because there are not many scores, I avoided doing anything clever... I just laid all of the scores into the dictionary with `,` and then made a very nasty O(N^2) algorithm that walks that list n/2 times eliminating the minimum value. The lowest survivor is the median.
: stack create ( n ) here cell+ , allot does> ( [a] -- ) ;
: push ( n a -- ) tuck @ c! 1 swap +! ;
: pop ( a -- n ) dup -1 swap +! @ c@ ;
: ?empty ( a -- f ) dup @ 8 - = ;
: clear-stack ( a -- ) dup 8 + swap ! ;
: ?= ( n n' -- f n ) over = swap ;
: ?opening ( n -- f ) 40 ?= 60 ?= 91 ?= 123 ?= drop or or or ;
: ->closing ( n -- n' ) dup 40 = if drop 41 else 2 + then ;
32 stack exp-closes
: do-char ( c -- ?ok )
dup ?opening if ->closing exp-closes push -1 else exp-closes pop = then ;
: ?= ( n n' -- n f ) over = ;
: rank ( n -- n' )
41 ?= if drop 3 else
62 ?= if drop 25137 else
93 = if 57 else 1197 then then then ;
create total-rank 0 ,
: accept/bail ( a n -- n' ) accept dup 0= if ." Done" quit then ;
: do-line ( -- f )
exp-closes clear-stack
pad -1 1 >> accept/bail pad + pad do i c@ do-char
if else i c@ rank total-rank +! unloop exit then
loop ;
: go ( -- ) begin do-line again ;
: report ( -- ) ." Answer:" total-rank @ . ;
\ No newline at end of file
: stack create ( n ) here cell+ , allot does> ( [a] -- ) ;
: push ( n a -- ) tuck @ c! 1 swap +! ;
: pop ( a -- n ) dup -1 swap +! @ c@ ;
: ?empty ( a -- f ) dup @ 8 - = ;
: clear-stack ( a -- ) dup 8 + swap ! ;
: ?= ( n n' -- f n ) over = swap ;
: ?opening ( n -- f ) 40 ?= 60 ?= 91 ?= 123 ?= drop or or or ;
: ->closing ( n -- n' ) dup 40 = if drop 41 else 2 + then ;
32 stack exp-closes
: do-char ( c -- ?ok )
dup ?opening if ->closing exp-closes push -1 else exp-closes pop = then ;
: accept/bail ( a n -- n' ) accept dup 0= if ." Done" quit then ;
: ?= ( n n' -- n f ) over = ;
: rank ( n -- n' )
41 ?= if drop 1 else
93 ?= if drop 2 else
125 = if 3 else 4 then then then ;
: do-line ( -- f )
exp-closes clear-stack
pad -1 1 >> accept/bail pad + pad do i c@ do-char 0= if unloop exit then
loop
0 begin exp-closes ?empty 0= while exp-closes pop rank swap 5 * + repeat , ;
variable scores
: go ( -- ) here scores ! begin do-line again ;
: n-scores ( -- n ) here scores @ - cell / ;
: lowest-score ( -- a n ) 0 -1 1 >>
n-scores 0 do scores @ i cells + >r r@ @
over < if 2drop r@ r> @ else rdrop then
loop ;
: median ( -- n )
n-scores 2/ 0 do lowest-score drop -1 1 >> swap ! loop
lowest-score nip ;
: report ( -- ) median ." 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