package Ġnl . kel pin . f le ur . ad vent 2 0 1 8 Ċ Ċ sealed Ġclass ĠTurn Ċ object ĠTurn Left Ġ: ĠTurn () Ċ object ĠTurn Right Ġ: ĠTurn () Ċ object ĠS tra ight Ġ: ĠTurn () Ċ Ċ class ĠDay 1 3 ( input : ĠList < String >, Ġprivate Ġval Ġremove Cr ashed Cart s : ĠBoolean Ġ= Ġfalse ) Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġreplace Cart With Track ( cart : ĠChar ): ĠChar Ġ= Ġwhen Ġ( cart ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ'>', Ġ'< ' Ġ-> Ġ'-' ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ'^ ', Ġ' v ' Ġ-> Ġ' |' ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġcart ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġreading Order Ġ= Ġcompare By < Cart >({ Ġit . location . y Ġ}, Ġ{ Ġit . location . x Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġtrack : ĠList < String > Ġ= Ġinput . map Ġ{ Ġit . map ( Companion :: replace Cart With Track ). join ToString ("") Ġ} ĊĠĠĠ Ġval Ġinitial Cart s : ĠSet < Cart > Ġ= Ġinput . map Indexed Ġ{ Ġy , Ġrow Ġ-> ĊĠĠĠĠĠĠĠ Ġrow . map Indexed Ġ{ Ġx , Ġchar Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( char ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ' >' Ġ-> ĠCart ( Point ( x , Ġy ), ĠRight ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ'< ' Ġ-> ĠCart ( Point ( x , Ġy ), ĠLeft ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ'^ ' Ġ-> ĠCart ( Point ( x , Ġy ), ĠUp ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ' v ' Ġ-> ĠCart ( Point ( x , Ġy ), ĠDown ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. filter NotNull () ĊĠĠĠ Ġ}. flatten (). toSet () ĊĊĠĠĠ Ġdata Ġclass ĠCart ( val Ġlocation : ĠPoint , Ġval Ġdirection : ĠDirection , Ġval Ġnext Turn : ĠTurn Ġ= ĠTurn Left ) Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġnew Next Turn ( charAt New Pos : ĠChar ): ĠTurn Ġ= Ġwhen Ġ( charAt New Pos ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ'+' Ġ-> Ġwhen Ġ( next Turn ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTurn Left Ġ-> ĠS tra ight ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠS tra ight Ġ-> ĠTurn Right ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTurn Right Ġ-> ĠTurn Left ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnext Turn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġnew Direction ( charAt New Pos : ĠChar ): ĠDirection Ġ= Ġwhen Ġ( charAt New Pos ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ'\\ ' Ġ-> Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRight Ġ-> ĠDown ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUp Ġ-> ĠLeft ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLeft Ġ-> ĠUp ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDown Ġ-> ĠRight ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ'/' Ġ-> Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUp Ġ-> ĠRight ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLeft Ġ-> ĠDown ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRight Ġ-> ĠUp ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDown Ġ-> ĠLeft ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ'+' Ġ-> Ġwhen Ġ( next Turn ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTurn Left Ġ-> Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLeft Ġ-> ĠDown ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDown Ġ-> ĠRight ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRight Ġ-> ĠUp ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUp Ġ-> ĠLeft ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠS tra ight Ġ-> Ġdirection ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTurn Right Ġ-> Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLeft Ġ-> ĠUp ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUp Ġ-> ĠRight ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRight Ġ-> ĠDown ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDown Ġ-> ĠLeft ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġdirection ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġmove On ( track : ĠList < String >): ĠCart Ġ= Ġwith ( location . move ( direction )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchar At New Pos Ġ= Ġtrack [ y ][ x ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcopy ( location Ġ= Ġthis , Ġdirection Ġ= Ġnew Direction ( charAt New Pos ), Ġnext Turn Ġ= Ġnew Next Turn ( charAt New Pos )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġnext ( cart s : ĠSet < Cart >): ĠPair < Point ?, ĠSet < Cart >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsorted : ĠMutable List < Cart > Ġ= Ġcart s . sorted With ( reading Order ). to Mutable List () ĊĠĠĠĠĠĠĠ Ġval Ġmoved : ĠMutable Set < Cart > Ġ= Ġmutable Set Of () ĊĠĠĠĠĠĠĠ Ġwhile Ġ( sorted . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmoved Cart Ġ= Ġsorted . remove At ( 0 ). move On ( track ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( moved . union ( sorted ). any Ġ{ Ġit . location Ġ== Ġmoved Cart . location Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! remove Cr ashed Cart s ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġmoved Cart . location Ġto Ġempty Set () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmoved . remove If Ġ{ Ġit . location Ġ== Ġmoved Cart . location Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsorted . remove If Ġ{ Ġit . location Ġ== Ġmoved Cart . location Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġmoved . add ( moved Cart ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull Ġto Ġmoved ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġtail rec Ġfun Ġpart 1 ( cart s : ĠSet < Cart > Ġ= Ġinitial Cart s ): ĠPoint Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġ( collision , Ġupdated ) Ġ= Ġnext ( cart s ) ĊĠĠĠĠĠĠĠ Ġreturn Ġcollision Ġ?: Ġpart 1 ( updated ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġtail rec Ġfun Ġpart 2 ( cart s : ĠSet < Cart > Ġ= Ġinitial Cart s ): ĠPoint Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġ(_, Ġupdated ) Ġ= Ġnext ( cart s ) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( updated . size Ġ== Ġ 1 ) Ġupdated . first (). location ĊĠĠĠĠĠĠĠ Ġelse Ġpart 2 ( updated ) ĊĠĠĠ Ġ} Ċ }