package Ġdays Ċ Ċ import Ġutil . add AndGet Ċ Ċ class ĠDay 7 Ġ: ĠDay ( 7 ) Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġpart One (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsteps Ġ= Ġparse Steps ( input List ) ĊĊĠĠĠĠĠĠĠ Ġval Ġexecution Ġ= Ġ( 0 Ġuntil Ġsteps . size ). map Ġ{ Ġi Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġel igible Steps Ġ= Ġsteps . filter Not Ġ{ Ġit . done Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . dependencies . isEmpty () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. sorted By Ġ{ Ġit . name Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmost El igible Ġ= Ġel igible Steps . first () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmost El igible . complete () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsteps . forEach Ġ{ Ġstep Ġ-> Ġstep . dependencies . remove If Ġ{ Ġit Ġ== Ġmost El igible . name Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmost El igible . name ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġexecution . join ToString ("") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġtodo Ġimprove Ġthis Ġ( remove Ġwhile Ġloop Ġide ally ) ĊĠĠĠ Ġoverride Ġfun Ġpart Two (): ĠAny Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsteps Ġ= Ġparse Steps ( input List ) ĊĠĠĠĠĠĠĠ Ġval Ġworker Pool Ġ= ĠArray ( 5 ) Ġ{ ĠWorker () Ġ} ĊĊĠĠĠĠĠĠĠ Ġvar Ġseconds Ġ= Ġ- 1 ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġworker Pool . forEach Ġ{ Ġit . update () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġseconds ++ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcompleted Steps Ġ= Ġsteps . filter Ġ{ Ġit . done Ġ}. map Ġ{ Ġit . name Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( completed Steps . size Ġ== Ġsteps . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsteps . forEach Ġ{ Ġstep Ġ-> Ġstep . dependencies . remove If Ġ{ Ġcompleted Steps . contains ( it ) Ġ} Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġel igible Steps Ġ= Ġsteps . filter Not Ġ{ Ġit . do ing Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . dependencies . isEmpty () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. sorted By Ġ{ Ġit . name Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( worker Pool . none Ġ{ Ġit . is Free () Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġif Ġ( el igible Steps . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġel igible Steps . zip ( worker Pool . filter Ġ{ Ġit . is Free () Ġ}). forEach Ġ{ Ġ( step , Ġworker ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġworker . start Work ( step ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// println (" Second : Ġ$ seconds ; ĠSteps : Ġ${ steps . filter Ġ{ Ġit . do ing Ġ}}; ĠDone : Ġ${ steps . filter Ġ{ Ġit . done Ġ}} ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġseconds ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġdata Ġclass ĠStep ( val Ġname : ĠChar ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdependencies Ġ= Ġmutable Set Of < Char >() ĊĠĠĠĠĠĠĠ Ġvar Ġseconds Needed Ġ= Ġ 6 0 Ġ+ Ġ(" ABCDEF GH IJ KL MN OP Q RST UV W XYZ ". indexOf ( this . name ) Ġ+ Ġ 1 ) ĊĊĠĠĠĠĠĠĠ Ġvar Ġdone Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġvar Ġdoing Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠ Ġfun Ġcomplete () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdone Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdoing Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġdo Work () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(-- seconds Needed Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . complete () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠWorker Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġvar Ġstep : ĠStep ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġfun Ġis Free () Ġ= Ġstep Ġ== Ġnull ĊĊĠĠĠĠĠĠĠ Ġfun Ġstart Work ( step : ĠStep ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . step Ġ= Ġstep ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstep . do ing Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġupdate () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( this . step Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . step !!. do Work () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( this . step !!. done ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . step Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġfun Ġparse Steps ( input : ĠList < String >): ĠCollection < Step > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġinput . map Ġ{ Ġstr Ġ-> Ġstr [ 3 6 ] Ġto Ġstr [ 5 ] Ġ}. fold ( mutable Set Of ()) Ġ{ Ġsteps , Ġdependency Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( steps . find Ġ{ Ġit . name Ġ== Ġdependency . first Ġ} Ġ?: Ġsteps . add AndGet ( Step ( dependency . first ))). dependencies . add ( dependency . second ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( steps . find Ġ{ Ġit . name Ġ== Ġdependency . second Ġ} Ġ?: Ġsteps . add AndGet ( Step ( dependency . second ))) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsteps ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ