Paste: AoC 2022 day 7
Author: | zip |
Mode: | factor |
Date: | Wed, 7 Dec 2022 18:27:41 |
Plain Text |
USING: accessors arrays assocs combinators io.encodings.utf8
io.files kernel math math.parser prettyprint regexp sequences
sequences.deep sorting splitting ;
IN: dec-7
TUPLE: directory up name subdirectories files ;
SYMBOL: root
: <directory> ( name subdirectories files -- directory ) [ f ] 3dip clone directory boa ;
: empty-directory ( name -- directory ) f swap { } H{ } clone directory boa ;
: >up-directory ( key directory -- directory ) [ swap '[ name>> _ = ] reject ] change-subdirectories ;
: add-subdirectory ( subdirectory directory -- directory ) swap '[ _ 1array append ] change-subdirectories ;
: add-file ( size name directory -- directory ) [ [ pick set-at ] 2curry ] dip swap change-files ;
: down-directory ( key directory -- directory ) subdirectories>> swap '[ name>> _ = ] find nip ;
: cd-down ( key directory -- directory ) [ >up-directory ] [ dupd down-directory dup [ nip ] [ drop empty-directory ] if ] 2bi swap >>up ;
: cd-up ( directory -- directory ) dup up>> [ f >>up ] dip add-subdirectory ;
: root? ( directory -- bool ) up>> f = ;
: cd-root ( directory -- directory ) [ dup root? not ] [ cd-up ] while ;
: input ( -- array ) "/Users/zip/desktop/aoc2022/dec-7/input.txt" utf8 file-lines ;
: handle-command ( string directory -- directory ) swap {
{ [ dup "$ cd /" = ] [ drop cd-root ] }
{ [ dup "$ cd .." = ] [ drop cd-up ] }
{ [ dup R/ ^\$ cd .*$/ matches? ] [ " " split last swap cd-down ] }
{ [ dup R/ ^\d+ .*$/ matches? ] [ " " split swap [ first2 [ string>number ] dip ] dip add-file ] }
{ [ ] [ ] }
} cond ;
: derive-tree ( string -- directory ) root empty-directory swap [ swap handle-command ] each cd-root ;
: directory-size ( directory -- number ) [ subdirectories>> [ directory-size ] map-sum ] [ files>> values sum ] bi + ;
: walk-tree ( directory quot: ( a -- a ) -- seq ) [ call ] [ [ subdirectories>> ] dip [ walk-tree ] curry map ] 2bi [ 1array ] dip append ; inline recursive
: part1 ( -- number ) input derive-tree [ directory-size ] walk-tree flatten [ 100000 <= ] filter sum ;
: total-free ( -- number ) 30000000 ;
: total-space ( -- number ) 70000000 ;
: needed-space ( number -- number ) total-free total-space - + ;
: part2 ( -- number ) input derive-tree [ directory-size ] walk-tree unclip needed-space [ flatten natural-sort ] dip [ >= ] curry find nip ;
MAIN: [ part1 . part2 . ]
New Annotation