import Ġkotlinx . coroutines . experimental . async Ċ import Ġkotlinx . coroutines . experimental . run Blocking Ċ Ċ object ĠA o C _ Day 2 1 Ġ{ ĊĊĠĠĠ Ġval Ġstart State Ġ= ĠMatrix ( listOf ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( 0 , 1 , 0 ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( 0 , 0 , 1 ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( 1 , 1 , 1 ) ĊĠĠĠ Ġ)) ĊĊĠĠĠ Ġdata Ġclass ĠMatrix ( val Ġdata : ĠList < List < Int >>) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsize Ġ: ĠInt Ġby Ġlazy Ġ{ Ġdata . size Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġrotate () Ġ= ĠMatrix (( 0 Ġuntil Ġdata . size ). map Ġ{ Ġrow Ġ-> Ġ( 0 Ġuntil Ġdata . size ). map Ġ{ Ġcol Ġ-> Ġdata [ col ][ row ] Ġ} Ġ}. reversed ()) ĊĊĠĠĠĠĠĠĠ Ġfun Ġflip () Ġ= ĠMatrix (( 0 Ġuntil Ġdata . size ). map Ġ{ Ġrow Ġ-> Ġdata [ row ]. reversed () Ġ}) ĊĊĠĠĠĠĠĠĠ Ġval Ġcount Active Ġ: ĠInt Ġby Ġlazy Ġ{ Ġdata . fold ( 0 ) Ġ{ acc , Ġrow Ġ-> Ġacc Ġ+ Ġrow . sum () Ġ} Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġmatches ( other : ĠList < Matrix >) Ġ= Ġthis . count Active Ġ== Ġother . first (). count Active Ġ&& Ġother . contains ( this ) ĊĊĠĠĠĠĠĠĠ Ġfun Ġdivide To Chunks And Transform ( rules : ĠList < Rule >) Ġ: ĠList < List < Matrix >> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchunk Size Ġ= Ġif Ġ( size Ġ% Ġ 2 Ġ== Ġ 0 ) Ġ 2 Ġelse Ġ 3 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġno Chunks Ġ= Ġsize Ġ/ Ġchunk Size ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdeferred Ġ= Ġ( 0 Ġuntil Ġno Chunks ). map Ġ{ Ġchunk Row Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrow Offset Ġ= Ġ Ġchunk Row Ġ* Ġchunk Size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġasync Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( 0 Ġuntil Ġno Chunks ). map Ġ{ Ġchunk Col Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcol Offset Ġ= Ġchunk Col Ġ* Ġchunk Size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbefore Ġ= ĠMatrix ( data . sub List ( row Offset , Ġrow Offset Ġ+ Ġchunk Size ). map Ġ{ Ġit . sub List ( col Offset , Ġcol Offset Ġ+ Ġchunk Size ) Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrules . single Ġ{ Ġrule Ġ-> Ġbefore . matches ( rule . input ) Ġ}. output ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdeferred . map Ġ{ Ġit . await () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġgenerate Possible () Ġ: ĠList < Matrix > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrot One Ġ= Ġrotate () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrot Two Ġ= Ġrot One . rotate () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrot Three Ġ= Ġrot Two . rotate () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠlistOf ( this , Ġthis . flip (), Ġrot One , Ġrot One . flip (), Ġrot Two , Ġrot Two . flip (), Ġrot Three , Ġrot Three . flip ()). distinct () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġtransform ( rules : ĠList < Rule >) Ġ: ĠMatrix Ġ= Ġjoin Chunks ( this . divide To Chunks And Transform ( rules )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġdata Ġclass ĠRule ( val Ġinput : ĠList < Matrix >, Ġval Ġoutput : ĠMatrix ) ĊĊĠĠĠ Ġfun Ġstring To Matrix ( input : ĠString ) Ġ: ĠMatrix Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġinput Split Ġ= Ġinput . split ("/") ĊĠĠĠĠĠĠĠ Ġval Ġmat Ġ: ĠList < List < Int >> Ġ= Ġinput Split . map Ġ{ Ġrow Ġ-> Ġrow . toCharArray (). map Ġ{ Ġc Ġ-> Ġif Ġ( c Ġ== Ġ'# ') Ġ 1 Ġelse Ġ 0 Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠMatrix ( mat ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġparse Rules ( input : ĠList < String >) Ġ: ĠList < Rule > Ġ= ĊĠĠĠĠĠĠĠ Ġinput . map Ġ{ Ġline Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġline Split Ġ= Ġline . split (" Ġ=> Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRule ( string To Matrix ( line Split [ 0 ]). generate Possible (), Ġstring To Matrix ( line Split [ 1 ])) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġjoin AR ow From Chunks ( chunks : ĠList < Matrix >, ĠrowIndex : ĠInt ) Ġ: ĠList < Int > Ġ= ĊĠĠĠĠĠĠĠ Ġchunks . map Ġ{ Ġit . data [ rowIndex ] Ġ}. fold ( emptyList ()) Ġ{ Ġacc , Ġpiece Ġ-> Ġacc Ġ+ Ġpiece } ĊĊĠĠĠ Ġfun Ġjoin Chunks In AR ow ( chunks : ĠList < Matrix >) Ġ: ĠList < List < Int >> Ġ= ĊĠĠĠĠĠĠĠ Ġ( 0 Ġuntil Ġchunks . first (). size ). map Ġ{ Ġindex Ġ-> Ġjoin AR ow From Chunks ( chunks , Ġindex ) Ġ} ĊĊĠĠĠ Ġfun Ġjoin Chunks ( chunks : ĠList < List < Matrix >>) Ġ: ĠMatrix Ġ= ĊĠĠĠĠĠĠĠ ĠMatrix ( chunks . fold ( emptyList ()) Ġ{ Ġrow Acc , Ġrow Chunks Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrow Acc Ġ+ Ġjoin Chunks In AR ow ( row Chunks ) ĊĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠ Ġfun Ġsolve ( input : ĠList < String >, Ġiterations : ĠInt ) Ġ: ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrules Ġ= Ġparse Rules ( input ) ĊĠĠĠĠĠĠĠ Ġreturn Ġgenerate Sequence ( start State ) Ġ{ Ġit . transform ( rules ) Ġ}. take ( iterations Ġ+ Ġ 1 ). last (). count Active ĊĠĠĠ Ġ} Ċ Ċ }