package Ġnet . since at . a oc 2 0 2 0 . day 8 Ċ Ċ import Ġjava . util .* Ċ Ċ fun Ġmain () Ġ{ ĊĠĠĠ Ġprintln ( execute Boot Code ( read Boot Code (" test input . txt "))) ĊĊĠĠĠ Ġval Ġun patched Boot Code Ġ= Ġread Boot Code (" input . txt ") ĊĠĠĠ Ġprintln ( execute Boot Code ( un patched Boot Code ). accumulator ) ĊĠĠĠ Ġprintln ( fix Boot Code ( un patched Boot Code )) Ċ } Ċ Ċ data Ġclass ĠExecution Result ( val Ġpath : ĠList < Int >, Ġval Ġaccumulator : ĠInt , Ġval Ġfinished : ĠBoolean ) Ċ Ċ fun Ġexecute Boot Code ( boot Code : ĠList < Boot Code Operation >): ĠExecution Result Ġ{ ĊĠĠĠ Ġvar Ġaccumulator Ġ= Ġ 0 ĊĠĠĠ Ġvar Ġposition Ġ= Ġ 0 ĊĠĠĠ Ġval Ġvisited Positions Ġ= Ġmutable ListOf < Int >() ĊĠĠĠ Ġval Ġend Of Code Ġ= Ġboot Code . size ĊĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġoperation Ġ= Ġboot Code [ position ] ĊĠĠĠĠĠĠĠ Ġval Ġnext Position Ġ= Ġwhen Ġ( operation . instruction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" nop " Ġ-> Ġposition Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" acc " Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaccumulator Ġ+= Ġoperation . operand ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġposition Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" jmp " Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġposition Ġ+ Ġoperation . operand ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalArgumentException (" unknown Ġinstruction Ġ'${ operation . instruction }' ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( next Position Ġin Ġvisited Positions ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠExecution Result ( visited Positions , Ġaccumulator , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġvisited Positions . add ( position ) ĊĠĠĠĠĠĠĠ Ġposition Ġ= Ġnext Position ĊĠĠĠĠĠĠĠ Ġif Ġ( position Ġ>= Ġend Of Code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠExecution Result ( visited Positions , Ġaccumulator , Ġtrue ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġfix Boot Code ( un patched Boot Code : ĠList < Boot Code Operation >): ĠInt Ġ{ ĊĠĠĠ Ġval Ġun patched Execution Ġ= Ġexecute Boot Code ( un patched Boot Code ) ĊĠĠĠ Ġval Ġpossible Patch Lines Ġ= ĠLinkedList ( un patched Execution . path ) ĊĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpatch Line Ġ= Ġpossible Patch Lines . remove First () ĊĠĠĠĠĠĠĠ Ġval Ġoperation To Patch Ġ= Ġun patched Boot Code [ patch Line ] ĊĠĠĠĠĠĠĠ Ġif Ġ( operation To Patch . instruction Ġ== Ġ" acc ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġpatched Operation Ġ= ĠBoot Code Operation ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( operation To Patch . instruction Ġ== Ġ" nop ") Ġ" jmp " Ġelse Ġ" nop ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoperation To Patch . operand ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġpatched Boot Code Ġ= Ġun patched Boot Code . to Mutable List (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis [ patch Line ] Ġ= Ġpatched Operation ĊĠĠĠĠĠĠĠ Ġ}. toList () ĊĠĠĠĠĠĠĠ Ġval Ġpatched Execution Result Ġ= Ġexecute Boot Code ( patched Boot Code ) ĊĠĠĠĠĠĠĠ Ġif Ġ(! patched Execution Result . finished ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġpatched Execution Result . accumulator ĊĠĠĠ Ġ} Ċ } Ċ Ċ data Ġclass ĠBoot Code Operation ( val Ġinstruction : ĠString , Ġval Ġoperand : ĠInt ) Ċ Ċ fun Ġread Boot Code ( fileName : ĠString ): ĠList < Boot Code Operation > Ġ{ ĊĠĠĠ Ġreturn ĠClassLoader . getSystem Resource AsStream ( fileName ) !!. buffered Reader (). use Lines Ġ{ Ġlines Ġ-> ĊĠĠĠĠĠĠĠ Ġlines . filter ( String :: isNotBlank ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġline Ġ-> Ġline . split (" Ġ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġ( instruction , Ġoperand String ) Ġ-> ĠBoot Code Operation ( instruction , Ġoperand String . toInt ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. toList () ĊĠĠĠ Ġ} Ċ }