Paste: aoc24 p1
Author: | jonens |
Mode: | factor |
Date: | Mon, 24 Dec 2018 13:58:45 |
Plain Text |
TUPLE: armygroup army id units hp attack initiative attack-type immunes weaknesses ;
C: <armygroup> armygroup
: parse-parens ( str -- immunes/f weakness/f )
"()" split dup length 3 = [
second ";" split [ [ CHAR: space = ] trim-head ] map
[ " " split 1 swap remove-nth [ [ CHAR: , = ] trim-tail ] map ] map
dup length 1 =
[ dup first first "immune" = [ f suffix ] [ f prefix ] if ]
[ dup first first "weak" = [ reverse ] when ] if
[ [ rest ] [ f ] if* ] map first2
] [ drop f f ] if ;
: parse-nums ( str -- units hp attack initiative attack-type )
" " split
[ { 0 4 } swap nths ]
[ 6 tail* { 0 5 } swap nths append [ string>number ] map first4 ]
[ 5 tail* first ] tri ;
: effective-power ( group -- power ) [ units>> ] [ attack>> ] bi * ;
: damage ( group1 group2 -- damage )
[ [ effective-power ] [ attack-type>> ] bi ]
[ [ immunes>> ] [ weaknesses>> ] bi ] bi*
{
{ [ swap pick swap member? ] [ 3drop 0 ] }
{ [ member? ] [ 2 * ] }
[ ]
} cond ;
: (select-target) ( enemyarmy armygroup -- enemyarmy' from to )
[
over empty? [ f ] [
2dup [ swap [ damage ] [ effective-power ] [ initiative>> ] tri 3array ] curry supremum-by
2dup damage zero? [ drop f ] when
] if
[ nip swap remove ] keep
] keep swap ;
: select-target ( immunearmy infectionarmy armygroup -- immunearmy' infectionarmy' from to )
dup army>> "Immune System" = [ (select-target) ] [ swapd (select-target) [ swap ] 2dip ] if ;
: armygroup-key ( armygroup -- key )
[ army>> ] [ id>> number>string ] bi append ;
: select-targets ( army1 army2 -- targets )
2dup append [ [ effective-power ] [ initiative>> ] bi 2array ] inv-sort-with
[ select-target [ armygroup-key ] dip ] H{ } map>assoc 2nip ;
: remove-deads ( immunearmy infectionarmy dead-target -- immunearmy' infectionarmy' )
dup army>> "Immune System" = [ swapd swap remove swap ] [ swap remove ] if ;
: attack-target ( immunearmy infectionarmy targets armygroup -- immunearmy' infectionarmy' )
swap over armygroup-key of [
[ damage ] keep dup hp>> [ swapd /i - ] curry with change-units
dup units>> 0 <= [ remove-deads ] [ drop ] if
] [ drop ] if* ;
: attack-targets ( army1 army2 targets -- army1' army2' )
2over append [ initiative>> ] inv-sort-with
[ attack-target ] with each ;
: day24-p1 ( -- n )
"/tmp/input" ascii file-lines
{ "" } split
[
unclip but-last swap
[ 1 + rot [ parse-nums ] [ parse-parens ] bi <armygroup> ]
with map-index
] map first2 2dup . .
[ 2dup [ empty? ] bi@ or ] [
2dup select-targets attack-targets
] until
dup empty? [ drop ] [ nip ] if [ units>> ] map-sum ;
day24-p1 .
New Annotation