USING: arrays assocs combinators io.encodings.utf8 io.files kernel math math.functions math.matrices math.vectors path-finding sequences splitting ; IN: aoc.12 : input ( -- lines ) "~/factor/aoc/12/12.in" utf8 file-lines [ >array ] map ; : neighbour-indices ( idx -- neighbours ) { [ { 0 1 } v+ ] [ { 0 -1 } v+ ] [ { 1 0 } v+ ] [ { -1 0 } v+ ] } cleave 4array ; :: neighbours ( elt i j m -- seq ) { i j } neighbour-indices [ [ m dimension v< ] [ { 0 0 } v>= ] bi append [ ] all? ] filter [ m matrix-nth elt - 1 <= ] filter ; : I ( -- astar ) input [ "S" "a" replace "E" "z" replace ] map dup [ neighbours ] curry matrix-map-index input dimension [ concat ] bi@ swap zip ; : m-find ( matrix char -- {row,col} ) [ [ first length ] [ concat ] bi ] dip swap index swap /mod 2array ; : to-end ( start -- n ) input CHAR: E m-find I find-path length 1 - ; : part1 ( -- n ) input CHAR: S m-find to-end ; ! bruteforce... not the most efficient, but I was too lazy to implement a custom class that path-finding works on : part2 ( -- n ) input dimension first [ 1 2array ] map [ to-end ] map infimum 1 + ;