package Ġde . sk yr ising . a oc Ċ Ċ import Ġde . sk yr ising . a oc 2 0 1 5 . register 2 0 1 5 Ċ import Ġde . sk yr ising . a oc 2 0 2 0 . register 2 0 2 0 Ċ import Ġde . sk yr ising . a oc 2 0 2 1 . register 2 0 2 1 Ċ import Ġjava . nio . ByteBuffer Ċ import Ġjava . nio . Char Buffer Ċ import Ġjava . nio . charset . StandardCharsets Ċ import Ġjava . util .* Ċ import Ġkotlin . math . sqrt Ċ import Ġkotlin . random . Random Ċ Ċ interface ĠP uzzle < T > Ġ: ĠComparable < P uzzle < T >> Ġ{ ĊĠĠĠ Ġfun ĠgetName (): ĠString ĊĠĠĠ Ġfun Ġget Year (): ĠInt ĊĠĠĠ Ġfun Ġget Day (): ĠInt ĊĠĠĠ Ġfun Ġget Real Input () Ġ= Ġget Input ( get Year (), Ġget Day ()) ĊĠĠĠ Ġfun Ġgenerate Input ( rand : ĠRandom ): ĠPair < ByteBuffer , ĠT >? ĊĠĠĠ Ġfun Ġrun P uzzle ( input : ĠByteBuffer ): ĠT ĊĊĠĠĠ Ġoverride Ġfun Ġcompare To ( other : ĠP uzzle < T >): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġyear Cmp Ġ= Ġget Year (). compareTo ( other . get Year ()) ĊĠĠĠĠĠĠĠ Ġif Ġ( year Cmp Ġ!= Ġ 0 ) Ġreturn Ġyear Cmp ĊĠĠĠĠĠĠĠ Ġval Ġday Cmp Ġ= Ġget Day (). compareTo ( other . get Day ()) ĊĠĠĠĠĠĠĠ Ġif Ġ( day Cmp Ġ!= Ġ 0 ) Ġreturn Ġday Cmp ĊĠĠĠĠĠĠĠ Ġval Ġpart Ġ= Ġif Ġ( getName (). startsWith (" Part ĠTwo ")) Ġ 2 Ġelse Ġ 1 ĊĠĠĠĠĠĠĠ Ġval Ġother Part Ġ= Ġif Ġ( other . getName (). startsWith (" Part ĠTwo ")) Ġ 2 Ġelse Ġ 1 ĊĠĠĠĠĠĠĠ Ġif Ġ( part Ġ!= Ġother Part ) Ġreturn Ġpart Ġ- Ġother Part ĊĠĠĠĠĠĠĠ Ġreturn ĠgetName (). compareTo ( other . getName ()) ĊĠĠĠ Ġ} Ċ } Ċ Ċ val Ġall P uzz les Ġ= ĠTreeMap < Int , ĠTreeMap < Int , ĠMutable List < P uzzle <* >>>> () Ċ Ċ fun Ġregister ( pu zzle : ĠP uzzle <* >) Ġ{ ĊĠĠĠ Ġall P uzz les . compute If Absent ( pu zzle . get Year ()) Ġ{ ĠTreeMap () Ġ}. compute If Absent ( pu zzle . get Day ()) Ġ{ Ġmutable ListOf () Ġ}. add ( pu zzle ) Ċ } Ċ Ċ @ Suppress (" Le aking This ") Ċ abstract Ġclass ĠAbstract P uzzle < T >( private Ġval Ġyear : ĠInt , Ġprivate Ġval Ġday : ĠInt , Ġprivate Ġval Ġname : ĠString ) Ġ: ĠP uzzle < T > Ġ{ ĊĠĠĠ Ġoverride Ġfun ĠgetName () Ġ= Ġname ĊĠĠĠ Ġoverride Ġfun Ġget Year () Ġ= Ġyear ĊĠĠĠ Ġoverride Ġfun Ġget Day () Ġ= Ġday ĊĠĠĠ Ġoverride Ġfun Ġgenerate Input ( rand : ĠRandom ): ĠPair < ByteBuffer , ĠT >? Ġ= Ġnull ĊĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= Ġ" P uzzle ( year =$ year , day =$ day , name =$ name })" Ċ } Ċ Ċ inline Ġfun Ġ< T > Ġpuzzle B ( year : ĠInt , Ġday : ĠInt , Ġname : ĠString , Ġcross inline Ġrun : Ġ( ByteBuffer ) Ġ-> ĠT ): ĠP uzzle < T > Ġ{ ĊĠĠĠ Ġval Ġp Ġ= Ġobject Ġ: ĠAbstract P uzzle < T >( year , Ġday , Ġname ) Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġrun P uzzle ( input : ĠByteBuffer ) Ġ= Ġrun ( input ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġregister ( p ) ĊĠĠĠ Ġreturn Ġp Ċ } Ċ Ċ inline Ġfun Ġ< T > Ġget Input ( input : ĠByteBuffer , Ġlast Input : ĠMutable Box < Pair < ByteBuffer , ĠT >? >, Ġno inline Ġfn : Ġ( ByteBuffer ) Ġ-> ĠT ): ĠT Ġ{ ĊĠĠĠ Ġval Ġvalue Ġ= Ġlast Input . value ĊĠĠĠ Ġif Ġ( value Ġ== Ġnull Ġ|| Ġvalue . first Ġ!== Ġinput ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġfn ( input ) ĊĠĠĠĠĠĠĠ Ġlast Input . value Ġ= ĠPair ( input , Ġresult ) ĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġvalue . second Ċ } Ċ Ċ var Ġlast Input LB Ġ= ĠMutable Box < Pair < ByteBuffer , ĠList < ByteBuffer >> ? >( null ) Ċ inline Ġfun Ġ< T > Ġpuzzle LB ( year : ĠInt , Ġday : ĠInt , Ġname : ĠString , Ġcross inline Ġrun : Ġ( List < ByteBuffer >) Ġ-> ĠT ): ĠP uzzle < T > Ġ{ ĊĠĠĠ Ġval Ġp Ġ= Ġobject Ġ: ĠAbstract P uzzle < T >( year , Ġday , Ġname ) Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġrun P uzzle ( input : ĠByteBuffer ) Ġ= Ġrun ( getInput ( input , Ġlast Input LB , Ġ:: line List )) ĊĠĠĠ Ġ} ĊĠĠĠ Ġregister ( p ) ĊĠĠĠ Ġreturn Ġp Ċ } Ċ Ċ var Ġlast Input S Ġ= ĠMutable Box < Pair < ByteBuffer , ĠChar Buffer >? >( null ) Ċ fun Ġcalc Input S ( input : ĠByteBuffer ): ĠChar Buffer Ġ= ĠStandard Charsets . US _ ASCII . decode ( input . slice ()) Ċ inline Ġfun Ġ< T > Ġpuzzle S ( year : ĠInt , Ġday : ĠInt , Ġname : ĠString , Ġcross inline Ġrun : Ġ( Char Buffer ) Ġ-> ĠT ): ĠP uzzle < T > Ġ{ ĊĠĠĠ Ġval Ġp Ġ= Ġobject Ġ: ĠAbstract P uzzle < T >( year , Ġday , Ġname ) Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġrun P uzzle ( input : ĠByteBuffer ) Ġ= Ġrun ( getInput ( input , Ġlast Input S , Ġ:: calc Input S ). slice ()) ĊĠĠĠ Ġ} ĊĠĠĠ Ġregister ( p ) ĊĠĠĠ Ġreturn Ġp Ċ } Ċ Ċ var Ġlast Input LS Ġ= ĠMutable Box < Pair < ByteBuffer , ĠList < String >> ? >( null ) Ċ fun Ġcalc Input LS ( input : ĠByteBuffer ) Ġ= Ġline List ( input ). map Ġ{ ĠStandard Charsets . US _ ASCII . decode ( it . slice ()). toString () Ġ} Ċ inline Ġfun Ġ< T > Ġpuzzle LS ( year : ĠInt , Ġday : ĠInt , Ġname : ĠString , Ġcross inline Ġrun : Ġ( List < String >) Ġ-> ĠT ): ĠP uzzle < T > Ġ{ ĊĠĠĠ Ġval Ġp Ġ= Ġobject Ġ: ĠAbstract P uzzle < T >( year , Ġday , Ġname ) Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġrun P uzzle ( input : ĠByteBuffer ) Ġ= Ġrun ( getInput ( input , Ġlast Input LS , Ġ:: calc Input LS )) ĊĠĠĠ Ġ} ĊĠĠĠ Ġregister ( p ) ĊĠĠĠ Ġreturn Ġp Ċ } Ċ Ċ private Ġvar Ġregistered All Ġ= Ġfalse Ċ fun Ġregister All () Ġ{ ĊĠĠĠ Ġif Ġ( registered All ) Ġreturn ĊĠĠĠ Ġregistered All Ġ= Ġtrue ĊĠĠĠ Ġregister 2 0 1 5 () ĊĠĠĠ Ġregister 2 0 2 0 () ĊĠĠĠ Ġregister 2 0 2 1 () Ċ } Ċ Ċ const Ġval ĠRUN S Ġ= Ġ 1 0 Ċ const Ġval ĠWAR M UP Ġ= Ġ 5 Ċ const Ġval ĠME AS URE _ IT ERS Ġ= Ġ 1 0 Ċ const Ġval ĠB EN CH MARK Ġ= Ġfalse Ċ Ċ fun Ġmain ( args : ĠArray < String >) Ġ{ ĊĠĠĠ Ġregister All () ĊĠĠĠ Ġval Ġp uzz les To Run Ġ= ĠTree Set < P uzzle <* >>() ĊĠĠĠ Ġif Ġ( args . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġyear P uzz les Ġ= Ġall P uzz les [ args [ 0 ]. toInt ()] Ġ?: Ġthrow ĠIllegalArgumentException ( args [ 0 ]) ĊĠĠĠĠĠĠĠ Ġif Ġ( args . size Ġ> Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( args [ 1 ] Ġ== Ġ" all ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( day Ġin Ġyear P uzz les . values ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġp uzz les To Run . addAll ( day ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġp uzz les To Run . addAll ( year P uzz les [ args [ 1 ]. toInt ()] Ġ?: Ġthrow ĠIllegalArgumentException ( args [ 1 ])) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġp uzz les To Run . addAll ( year P uzz les . last Entry (). value ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ( year Ġin Ġall P uzz les . values ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( day Ġin Ġyear . values ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġp uzz les To Run . addAll ( day ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġvar Ġyear : ĠInt ? Ġ= Ġnull ĊĠĠĠ Ġvar Ġday : ĠInt ? Ġ= Ġnull ĊĠĠĠ Ġfor Ġ( pu zzle Ġin Ġp uzz les To Run ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( pu zzle . get Year () Ġ!= Ġyear ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġyear Ġ= Ġpuzzle . get Year () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġday Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ("$ year :") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( pu zzle . get Day () Ġ!= Ġday ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġday Ġ= Ġpuzzle . get Day () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Day Ġ$ day :") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġinput Ġ= Ġpuzzle . get Real Input () ĊĠĠĠĠĠĠĠ Ġif Ġ( BENCH MARK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrepeat ( WAR M UP ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmeasure ( RUN S ) Ġ{ Ġpuzzle . run P uzzle ( input ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtimes Ġ= ĠDouble Array ( MEAS URE _ IT ERS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmeasure ( RUN S ) Ġ{ Ġpuzzle . run P uzzle ( input ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġavg Ġ= Ġtimes . average () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstd dev Ġ= Ġsqrt ( times . map Ġ{ Ġ( it Ġ- Ġavg ) Ġ* Ġ( it Ġ- Ġavg ) Ġ}. average ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ( String . format ( Locale . ROOT , Ġ"% - 2 6 s : Ġ% 1 6 s , Ġ% s ĠÂ ± Ġ% 4 . 1 f %% ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpuzzle . getName (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpuzzle . run P uzzle ( input ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġformat Time ( avg ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstd dev Ġ* Ġ 1 0 0 Ġ/ Ġavg ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ)) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstart Ġ= ĠSystem . nano Time () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġpuzzle . run P uzzle ( input ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtime Ġ= Ġ( System . nano Time () Ġ- Ġstart ) Ġ/ Ġ 1 0 0 0 . 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ( String . format ( Locale . ROOT , Ġ"% - 2 6 s : Ġ% 1 6 s , Ġ% s ĠÂ ± Ġ?", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpuzzle . getName (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġformat Time ( time ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ)) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġformat Time ( us : ĠDouble ): ĠString Ġ{ ĊĠĠĠ Ġif Ġ( us Ġ< Ġ 1 0 0 0 ) Ġreturn Ġ"% 7 . 3 f Â µ s ". format ( us ) ĊĠĠĠ Ġval Ġms Ġ= Ġus Ġ/ Ġ 1 0 0 0 ĊĠĠĠ Ġif Ġ( ms Ġ< Ġ 1 0 0 0 ) Ġreturn Ġ"% 7 . 3 f ms ". format ( ms ) ĊĠĠĠ Ġreturn Ġ"% 7 . 3 fs Ġ". format ( ms Ġ/ Ġ 1 0 0 0 ) Ċ } Ċ