! Copyright (C) 2022 Keldan Chapman. ! See http://factorcode.org/license.txt for BSD license. USING: kernel AOC prettyprint splitting path-finding math assocs math.vectors math.matrices sequences accessors arrays tr ; IN: AOC.2022.12 TUPLE: terrain < astar map cache ; : ( map -- terrain ) terrain new swap >>map H{ } clone >>cache ; : tile ( pair terrain -- val ) map>> swap [ swap ?nth ] each [ 404 ] unless* ; M: terrain cost 3drop 1 ; M: terrain heuristic drop [ first2 ] bi@ swapd [ - abs ] bi@ + ; M: terrain neighbours 2dup cache>> at [ 1array 2nip ] [ [ tile ] 2keep { { 0 -1 } { 0 1 } { -1 0 } { 1 0 } } rot '[ _ v+ ] map [ 2over swap [ tile ] dip - 2 < ] filter 2nip ] if* ; : cache-path ( start end terrain -- path ) [ find-path dup dup dup [ rest ] when swap ] [ cache>> ] bi '[ _ set-at ] 2each ; : matrix-find ( matrix quot -- pair ) f -rot '[ 2array swap @ [ swap ] when drop 0 ] matrix-map-index drop ; inline TR: cnv "SE" "az" ; : start-cost ( end terrain v start -- end terrain cost ) swap CHAR: a = [ -rot [ cache-path length 1 - ] 2keep rot ] [ drop 999999 ] if ; : part-1 ( input -- result ) [ split-lines [ [ CHAR: S = ] matrix-find ] [ [ CHAR: E = ] matrix-find ] bi ] [ cnv split-lines ] bi find-path length 1 - ; : part-2 ( input -- result ) [ split-lines [ CHAR: E = ] matrix-find ] [ cnv split-lines [ ] keep ] bi [ 2array start-cost ] matrix-map-index mmin 2nip ; MAIN: [ 12 read-day-input [ part-1 . ] [ part-2 . ] bi ]