Paste: aoc20

Author: jon
Mode: factor
Date: Tue, 8 Jan 2019 13:41:05
Plain Text |
EBNF: parse-alternates
  options = "("~ elems ( "|"~ elems )* ")"~ => [[ unclip [ first ] dip prefix ]]
  literal = [NSEW]+ => [[ >string ]]
  elem = options | literal
  elems=elem* => [[ >array ]]
;EBNF
: letter>direction ( char -- v )
  {
    { CHAR: E [ {  1  0 } ] }
    { CHAR: W [ { -1  0 } ] }
    { CHAR: N [ {  0  1 } ] }
    { CHAR: S [ {  0 -1 } ] }
  } case ;
: explore-string ( str pos map -- pos' )
  [
    [ letter>direction over v+ ] dip
    [ [ 2array natural-sort ] dip adjoin ] curry keep
  ] curry reduce ;
: explore ( insn pos map -- pos' )
{
  { [ pick array? ] [ [ swapd explore ] curry reduce ] }
  { [ pick vector? ] [ [ explore ] 2curry map first ] }
  { [ pick string? ] [ explore-string ] }
} cond ;

USING: path-finding path-finding.private ;
TUPLE: facility-bfs < bfs map ;
: possible-neighbours ( pos -- neighbours )
  { { 1 0 } { -1 0 } { 0 1 } { 0 -1 } } [ v+ ] with map ;
M: facility-bfs neighbours
  [ dup possible-neighbours [ 2array natural-sort ] with map ]
  [ map>> ] bi* [ in? ] curry filter concat members ;
: make-map ( str -- edges )
  parse-alternates { 0 0 } HS{ } clone [ explore drop ] keep ;
: aoc20 ( str -- )
  make-map facility-bfs new swap >>map
  [ { 0 0 } f ] dip [ find-path drop ] keep
  g>> values [ supremum . ] [ [ 1000 >= ] count . ] bi ;
: aoc20input ( -- )
  "/tmp/input" ascii file-lines first rest but-last aoc20 ;
aoc20input

New Annotation

Summary:
Author:
Mode:
Body: