package Ġday 1 3 Ċ Ċ import Ġshared . all Coordinates Ċ import Ġshared . read P uzzle Ċ Ċ enum Ġclass ĠHeading ( val Ġdx : ĠInt , Ġval Ġdy : ĠInt , Ġval Ġsymbol : ĠChar ) Ġ{ ĊĠĠĠ ĠN ( 0 , Ġ- 1 , Ġ'^ '), ĠE ( 1 , Ġ 0 , Ġ'> '), ĊĠĠĠ ĠS ( 0 , Ġ 1 , Ġ' v '), ĠW (- 1 , Ġ 0 , Ġ'< '); ĊĊĠĠĠ Ġval Ġleft Ġget () Ġ= Ġvalues ()[ ( ordinal Ġ- Ġ 1 Ġ+ Ġvalues (). size ) Ġ% Ġvalues (). size ] ĊĠĠĠ Ġval Ġright Ġget () Ġ= Ġvalues ()[ ( ordinal Ġ+ Ġ 1 ) Ġ% Ġvalues (). size ] ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġfrom Char ( c : ĠChar ) Ġ= Ġvalues (). first OrNull Ġ{ Ġit . symbol Ġ== Ġc Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ data Ġclass ĠCart ( var Ġx : ĠInt , Ġvar Ġy : ĠInt , Ġvar Ġheading : ĠHeading ) Ġ: ĠComparable < Cart > Ġ{ ĊĊĠĠĠ Ġvar Ġcr ashed Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġvar Ġturn Cycle Ġ= Ġ 0 ĊĊĠĠĠ Ġfun Ġmove ( tracks : ĠList < List < Char >>) Ġ{ ĊĠĠĠĠĠĠĠ Ġx Ġ+= Ġheading . dx ĊĠĠĠĠĠĠĠ Ġy Ġ+= Ġheading . dy ĊĠĠĠĠĠĠĠ Ġheading Ġ= Ġnew Heading ( tracks ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnew Heading ( tracks : ĠList < List < Char >>) Ġ= Ġwhen Ġ( tracks [ y ][ x ]) Ġ{ ĊĠĠĠĠĠĠĠ Ġ'+' Ġ-> Ġintersection Handlers [ turn Cycle ++ Ġ% Ġ 3 ]( heading ) ĊĠĠĠĠĠĠĠ Ġ'/' Ġ-> Ġwhen Ġ( heading ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHeading . N , ĠHeading . S Ġ-> Ġheading . right ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHeading . E , ĠHeading . W Ġ-> Ġheading . left ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ'\\ ' Ġ-> Ġwhen Ġ( heading ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHeading . N , ĠHeading . S Ġ-> Ġheading . left ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHeading . E , ĠHeading . W Ġ-> Ġheading . right ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġheading ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġcompare To ( other : ĠCart ) Ġ= ĊĠĠĠĠĠĠĠ Ġif Ġ( y Ġ!= Ġother . y ) Ġy . compareTo ( other . y ) Ġelse Ġx . compareTo ( other . x ) ĊĊĠĠĠ Ġin fix Ġfun Ġpos Eq ( other : ĠCart ) Ġ= Ġthis Ġ!== Ġother Ġ&& Ġthis . x Ġ== Ġother . x Ġ&& Ġthis . y Ġ== Ġother . y ĊĊĠĠĠ Ġfun Ġposition () Ġ= Ġ"$ x ,$ y " ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġintersection Handlers Ġ= ĠarrayOf <( Heading ) Ġ-> ĠHeading >( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġh Ġ-> Ġh . left Ġ}, Ġ{ Ġh Ġ-> Ġh Ġ}, Ġ{ Ġh Ġ-> Ġh . right Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} Ċ Ċ } Ċ Ċ fun ĠChar . to Cart ( x : ĠInt , Ġy : ĠInt ) Ġ= ĠHeading . from Char ( this )?. let Ġ{ ĠCart ( x , Ġy , Ġit ) Ġ} Ċ Ċ fun Ġpart 1 ( pu zzle : ĠList < String >, Ġshow : ĠBoolean Ġ= Ġfalse ): ĠAny Ġ{ ĊĠĠĠ Ġval Ġtracks Ġ= Ġextract Tracks ( pu zzle ) ĊĠĠĠ Ġval Ġcart s Ġ= Ġextract Cart s ( pu zzle ) ĊĊĠĠĠ Ġif Ġ( show ) Ġprint Layout ( cart s , Ġtracks ) ĊĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcart s . sorted (). forEach Ġ{ Ġcart Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcart . move ( tracks ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cart s . any Ġ{ Ġit Ġpos Eq Ġcart Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcart . position () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( show ) Ġprint Layout ( cart s , Ġtracks ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġpart 2 ( pu zzle : ĠList < String >, Ġshow : ĠBoolean Ġ= Ġfalse ): ĠAny Ġ{ ĊĠĠĠ Ġval Ġtracks Ġ= Ġextract Tracks ( pu zzle ) ĊĠĠĠ Ġvar Ġcart s Ġ= Ġextract Cart s ( pu zzle ) ĊĊĠĠĠ Ġif Ġ( show ) Ġprint Layout ( cart s , Ġtracks ) ĊĠĠĠ Ġwhile Ġ( cart s . size Ġ> Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcart s . sorted (). forEach Ġ{ Ġcart Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcart . move ( tracks ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcart s . first OrNull Ġ{ Ġ! it . cr ashed Ġ&& Ġcart Ġpos Eq Ġit Ġ} ?. let Ġ{ Ġcr ashed Into Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcart . cr ashed Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcr ashed Into . cr ashed Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcart s Ġ= Ġcart s . filter Ġ{ Ġ! it . cr ashed Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( show ) Ġprint Layout ( cart s , Ġtracks ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġcart s . single (). position () Ċ } Ċ Ċ fun Ġextract Cart s ( pu zzle : ĠList < String >) Ġ= ĊĠĠĠ Ġpuzzle . map Indexed Ġ{ Ġy , Ġs Ġ-> Ġs . map Indexed Ġ{ Ġx , Ġc Ġ-> Ġc . to Cart ( x , Ġy ) Ġ}. filter NotNull () Ġ}. flatten () Ċ Ċ fun Ġextract Tracks ( pu zzle : ĠList < String >) Ġ= ĊĠĠĠ Ġpuzzle . map Ġ{ Ġrow Ġ-> ĊĠĠĠĠĠĠĠ Ġrow . toCharArray (). map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ'<', Ġ' >' Ġ-> Ġ'-' ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ'^ ', Ġ' v ' Ġ-> Ġ' |' ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ fun Ġprint Layout ( cart s : ĠList < Cart >, Ġtracks : ĠList < List < Char >>) Ġ{ ĊĠĠĠ Ġall Coordinates (( tracks . max By Ġ{ Ġit . size Ġ} !!. size ), Ġtracks . size ) ĊĠĠĠĠĠĠĠ Ġ. forEach Ġ{ Ġ( x , Ġy ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( x Ġ== Ġ 0 ) Ġprintln () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġc Ġ= Ġcart s . filter Ġ{ Ġcart Ġ-> Ġ! cart . cr ashed Ġ&& Ġcart . x Ġ== Ġx Ġ&& Ġcart . y Ġ== Ġy Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġc . size Ġ== Ġ 1 Ġ-> Ġprint ( c . single (). heading . symbol ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġc . size Ġ> Ġ 1 Ġ-> Ġprint (' X ') ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġprint ( tracks [ y ]. getOrElse ( x ) Ġ{ Ġ' Ġ' Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġprintln () Ċ } Ċ Ċ fun Ġmain ( args : ĠArray < String >) Ġ{ ĊĠĠĠ Ġval Ġpuzzle Ġ= Ġread P uzzle ( 1 3 ) ĊĊĠĠĠ Ġprintln ( part 1 ( pu zzle )) ĊĠĠĠ Ġprintln ( part 2 ( pu zzle )) Ċ }