USING: math.combinatorics math.ranges math.vectors io.encodings.ascii ; : Mi,j ( {i,j} grid -- el ) [ first2 swap ] dip nth nth ; : mmap-index ( grid quot: ( a {i,j} -- b ) -- grid' ) [ [ swap 2array ] ] dip compose [ curry map-index ] curry map-index ; inline : neighbours ( {i,j} -- neighbours ) -1 1 [a,b] 2 selections [ { 0 0 } = ] reject [ v+ ] with map ; : grid-neighbours ( {i,j} grid -- neighbours ) [ neighbours ] dip [ [ length ] [ first length ] bi 2array [ [ [ drop 0 >= ] [ < ] 2bi and ] 2all? ] curry filter ] keep [ Mi,j ] curry map ; : stepcell ( el {i,j} grid -- el' ) rot { { 76 [ grid-neighbours [ 35 = ] count zero? 35 76 ? ] } { 35 [ grid-neighbours [ 35 = ] count 4 >= 76 35 ? ] } [ 2nip ] } case ; : neighbour-dirs ( -- neighbours ) -1 1 [a,b] 2 selections [ { 0 0 } = ] reject ; : ingrid? ( {i,j} grid -- ? ) [ length ] [ first length ] bi 2array [ [ drop 0 >= ] [ < ] 2bi and ] 2all? ; : (grid-see) ( {i,j} grid dir -- L/# ) [ f ] 3dip [ swap [ v+ ] dip 2dup ingrid? [ [ Mi,j nip ] 2keep pick CHAR: . = ] [ f ] if ] curry loop 2drop ; : grid-see ( {i,j} grid -- neighbours ) neighbour-dirs [ (grid-see) ] with with map ; : stepcell2 ( el {i,j} grid -- el' ) rot { { 76 [ grid-see [ 35 = ] count zero? 35 76 ? ] } { 35 [ grid-see [ 35 = ] count 5 >= 76 35 ? ] } [ 2nip ] } case ; : stepgrid ( grid -- grid' ) dup [ stepcell ] curry mmap-index ; : stepgrid2 ( grid -- grid' ) dup [ stepcell2 ] curry mmap-index ; : dbg ( grid -- grid ) "====" print dup [ >string ] map "\n" join print ; : p1 ( -- n ) "/tmp/input" ascii file-lines [ >array ] map dup [ stepgrid dbg [ = not ] keep dup rot ] loop nip concat [ CHAR: # = ] count ; : p2 ( -- n ) "/tmp/input" ascii file-lines [ >array ] map dup [ stepgrid2 dbg [ = not ] keep dup rot ] loop nip concat [ CHAR: # = ] count ; p1 p2