Paste: AOC day 18

Author: chunes
Mode: factor
Date: Fri, 18 Dec 2020 10:36:56
Plain Text |
USING: assocs combinators.short-circuit
compiler.tree.propagation.call-effect eval io.encodings.ascii
io.files kernel listener literals make math prettyprint qw
sequences sets splitting.extras ;
IN: aoc.2020.18

CONSTANT: input $[ "input.txt" ascii file-lines ]

CONSTANT: precedence
{
    { "(" 0 }
    { ")" 0 }
    { "+" 2 }
    { "*" 1 }
}

: tokenize ( str -- tokens ) "( )" split* { " " } without ;

: %s ( seq -- ) % " " % ;

: op? ( token -- ? ) qw{ ( ) * + } member? ;

: (valid-stack?) ( stack -- ? )
    { [ last "(" = ] [ last2 [ precedence at ] bi@ < ] } 1|| ;

: valid-stack? ( stack -- ? )
    dup length 2 < [ drop t ] [ (valid-stack?) ] if ;

: slurp ( stack -- stack' )
    dup pop drop [ dup pop dup "(" = ] [ %s ] until drop ;

DEFER: ?op%
: collapse ( stack -- stack' )
    dup [ pop ] [ pop ] bi %s suffix! ?op% ;

: pop-op ( stack -- stack' )
    dup last ")" = [ slurp ] [ collapse ] if ;

: ?op% ( stack -- stack/stack' )
    dup valid-stack? [ pop-op ] unless ;

: handle-token ( stack token -- stack )
    dup op? [ suffix! ?op% ] [ %s ] if ;

: infix>postfix ( str -- newstr )
    V{ } clone swap tokenize [ [ handle-token ] each ] "" make
    swap reverse " " join append ;

: main ( -- )    ! main works for both part 1 and part 2; just change +'s precedence level to 1 for part 1.
    input
    [ infix>postfix [ ( -- n ) (eval) ] with-interactive-vocabs ]
    map-sum . ;

New Annotation

Summary:
Author:
Mode:
Body: