! Copyright (C) 2022 Keldan Chapman. ! See http://factorcode.org/license.txt for BSD license. USING: kernel AOC prettyprint splitting sequences.extras math math.vectors math.parser sequences sets ; IN: AOC.2022.14 CONSTANT: sand-origin { 500 0 } : build-path ( map a b -- map ) [ "," split [ dec> ] map ] bi@ 2dup v- [ sgn ] map rot '[ dup _ = not ] swap '[ [ over adjoin ] keep _ v+ ] while drop ; : build-map ( input -- hashmap ) HS{ } clone swap split-lines [ " -> " split-subseq [ 1 f 1 reach [ build-path ] 2each ] keep first "," split [ dec> ] map over adjoin ] each ; : sand ( hashmap limit -- pos ) sand-origin [ 2dup second > [ { { 0 1 } { -1 1 } { 1 1 } } over '[ _ v+ [ reach in? not ] keep and ] map sift [ nip f ] [ first nip ] if-empty ] [ nip f ] if ] [ ] while* nip ; : sand-fall ( input limitquot islimit notlimit -- result ) [ build-map [ cardinality ] keep ] 3dip [ call ] 2dip '[ 2dup sand 2dup second = _ _ if ] [ ] while drop cardinality swap - ; inline : part-1 ( input -- result ) [ dup members [ second ] map supremum ] [ drop f ] [ pick adjoin t ] sand-fall ; : part-2 ( input -- result ) [ dup members [ second ] map supremum 1 + ] [ pick adjoin t ] [ [ pick adjoin ] keep sand-origin = not ] sand-fall ; MAIN: [ 14 read-day-input [ part-1 . ] [ part-2 . ] bi ]