package Ġcommon Ċ Ċ import Ġjava . util . Stack Ċ Ċ class ĠInt code Computer ( private Ġval Ġtape : ĠMutable List < Long >, Ġno un : ĠLong ? Ġ= Ġnull , Ġverb : ĠLong ? Ġ= Ġnull ) Ġ{ ĊĊĠĠĠ Ġprivate Ġvar Ġhead Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġvar Ġrelative Base Ġ= Ġ 0 ĊĊĠĠĠ Ġvar Ġhal ted Ġ= Ġfalse ĊĠĠĠ Ġvar Ġwaiting Ġ= Ġfalse ĊĊĠĠĠ Ġprivate Ġfun Ġcan Run () Ġ= Ġ! hal ted Ġ&& Ġ! waiting ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġinput : ĠStack < Long > ĊĠĠĠ Ġprivate Ġval Ġoutput Ġ= Ġmutable ListOf < Long >() ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( no un Ġ!= Ġnull Ġ&& Ġverb Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtape [ 1 ] Ġ= Ġno un ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtape [ 2 ] Ġ= Ġverb ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdebug (): ĠList < Long > Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ( can Run ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadvance () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtape ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġrun (): ĠLong Ġ= Ġdebug ()[ 0 ] ĊĊĠĠĠ Ġfun Ġrun With IO ( input : ĠStack < Long >): ĠList < Long > Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . waiting Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġthis . input Ġ= Ġinput ĊĠĠĠĠĠĠĠ Ġdebug () ĊĠĠĠĠĠĠĠ Ġreturn Ġoutput ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġrun With IO ( input : ĠLong ): ĠList < Long > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġthis . run With IO ( stack Of ( input )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadvance () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġinstruction Ġ= ĠInstruction ( tape [ head ]. toString ()) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( instruction . opcode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOpcode . ADD Ġ-> Ġtape [ instruction . getOutput Index ( 3 , Ġtape , Ġhead , Ġrelative Base )] Ġ= Ġinstruction . getParam ( 1 , Ġtape , Ġhead , Ġrelative Base ) Ġ+ Ġinstruction . getParam ( 2 , Ġtape , Ġhead , Ġrelative Base ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOpcode . MUL Ġ-> Ġtape [ instruction . getOutput Index ( 3 , Ġtape , Ġhead , Ġrelative Base )] Ġ= Ġinstruction . getParam ( 1 , Ġtape , Ġhead , Ġrelative Base ) Ġ* Ġinstruction . getParam ( 2 , Ġtape , Ġhead , Ġrelative Base ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOpcode . LESS _ THAN Ġ-> Ġtape [ instruction . getOutput Index ( 3 , Ġtape , Ġhead , Ġrelative Base )] Ġ= Ġif Ġ( instruction . getParam ( 1 , Ġtape , Ġhead , Ġrelative Base ) Ġ< Ġinstruction . getParam ( 2 , Ġtape , Ġhead , Ġrelative Base )) Ġ 1 Ġelse Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOpcode . EQUAL S Ġ-> Ġtape [ instruction . getOutput Index ( 3 , Ġtape , Ġhead , Ġrelative Base )] Ġ= Ġif Ġ( instruction . getParam ( 1 , Ġtape , Ġhead , Ġrelative Base ) Ġ== Ġinstruction . getParam ( 2 , Ġtape , Ġhead , Ġrelative Base )) Ġ 1 Ġelse Ġ 0 ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠOpcode . READ Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( input . empty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . waiting Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtape [ instruction . getOutput Index ( 1 , Ġtape , Ġhead , Ġrelative Base )] Ġ= Ġinput . pop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOpcode . WRITE Ġ-> Ġoutput . add ( instruction . getParam ( 1 , Ġtape , Ġhead , Ġrelative Base )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOpcode . BASE _ OFFSET Ġ-> Ġrelative Base Ġ+= Ġinstruction . getParam ( 1 , Ġtape , Ġhead , Ġrelative Base ). toInt () ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠOpcode . JUMP _ TRUE Ġ-> Ġhead Ġ= Ġif Ġ( instruction . getParam ( 1 , Ġtape , Ġhead , Ġrelative Base ) Ġ!= Ġ 0 L ) Ġinstruction . getParam ( 2 , Ġtape , Ġhead , Ġrelative Base ). toInt () Ġelse Ġhead Ġ+ Ġinstruction . numberOf Args () Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOpcode . JUMP _ FALSE Ġ-> Ġhead Ġ= Ġif Ġ( instruction . getParam ( 1 , Ġtape , Ġhead , Ġrelative Base ) Ġ== Ġ 0 L ) Ġinstruction . getParam ( 2 , Ġtape , Ġhead , Ġrelative Base ). toInt () Ġelse Ġhead Ġ+ Ġinstruction . numberOf Args () Ġ+ Ġ 1 ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠOpcode . HAL T Ġ-> Ġhal ted Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! instruction . mod ifies Instruction Pointer () Ġ&& Ġcan Run ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhead Ġ+= Ġinstruction . numberOf Args () Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠInstruction ( instruction : ĠString ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġopcode : ĠOpcode ĊĠĠĠĠĠĠĠ Ġval Ġparameter Modes : ĠList < Parameter Mode > ĊĊĠĠĠĠĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( instruction . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġopcode Ġ= ĠOpcode . from Value ( instruction . take Last ( 2 ). toInt ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmodes Ġ= Ġinstruction . drop Last ( 2 ). reversed (). take Last ( 3 ). pad End ( numberOf Args (), Ġ' 0 ') ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparameter Modes Ġ= Ġmodes . map Ġ{ ĠParameter Mode . from Value ( it . toString (). toInt ()) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġget Param ( param : ĠInt , Ġtape : ĠMutable List < Long >, Ġhead : ĠInt , Ġrelative Base : ĠInt ): ĠLong Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtape [ getIndex ( param , Ġtape , Ġhead , Ġrelative Base )] ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġget Output Index ( param : ĠInt , Ġtape : ĠMutable List < Long >, Ġhead : ĠInt , Ġrelative Base : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġget Index ( param , Ġtape , Ġhead , Ġrelative Base ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun ĠnumberOf Args (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( opcode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOpcode . ADD , ĠOpcode . MUL , ĠOpcode . LESS _ THAN , ĠOpcode . EQUAL S Ġ-> Ġ 3 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOpcode . JUMP _ TRUE , ĠOpcode . JUMP _ FALSE Ġ-> Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOpcode . READ , ĠOpcode . WRITE , ĠOpcode . BASE _ OFFSET Ġ-> Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġget Index ( param : ĠInt , Ġtape : ĠMutable List < Long >, Ġhead : ĠInt , Ġrelative Base : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġindex Ġ= Ġwhen Ġ( parameter Modes [ param Ġ- Ġ 1 ]) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠParameter Mode . IM MEDI ATE Ġ-> Ġhead Ġ+ Ġparam ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠParameter Mode . POSITION Ġ-> Ġtape [ head Ġ+ Ġparam ]. toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠParameter Mode . REL ATIVE Ġ-> Ġtape [ head Ġ+ Ġparam ]. toInt () Ġ+ Ġrelative Base ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġadd Ġenough Ġblank Ġmemory Ġto Ġend Ġof Ġtape ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( index Ġ> Ġtape . last Index ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtape . addAll ( List (( index Ġ- Ġtape . last Index ) Ġ+ Ġ 1 ) Ġ{ Ġ 0 L Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġindex ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġmod ifies Instruction Pointer () Ġ= Ġopcode Ġ== ĠOpcode . JUMP _ TRUE Ġ|| Ġopcode Ġ== ĠOpcode . JUMP _ FALSE ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġenum Ġclass ĠOpcode ( val Ġvalue : ĠInt ) Ġ{ ĊĊĠĠĠĠĠĠĠ ĠADD ( 1 ), ĠMUL ( 2 ), ĠREAD ( 3 ), ĠWRITE ( 4 ), ĠJ UMP _ TRUE ( 5 ), ĠJ UMP _ FALSE ( 6 ), ĠL ESS _ THAN ( 7 ), ĠEQUAL S ( 8 ), ĠBASE _ OFFSET ( 9 ), ĠHAL T ( 9 9 ); ĊĊĠĠĠĠĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġfrom Value ( value : ĠInt ): ĠOpcode Ġ= Ġvalues (). find Ġ{ Ġit . value Ġ== Ġvalue Ġ} Ġ?: Ġthrow ĠIllegalArgumentException (" Bad Ġopcode : Ġ$ value ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġenum Ġclass ĠParameter Mode ( val Ġvalue : ĠInt ) Ġ{ ĊĊĠĠĠĠĠĠĠ ĠPOSITION ( 0 ), ĠIM MEDI ATE ( 1 ), ĠREL ATIVE ( 2 ); ĊĊĠĠĠĠĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġfrom Value ( value : ĠInt ): ĠParameter Mode Ġ= Ġvalues (). find Ġ{ Ġit . value Ġ== Ġvalue Ġ} Ġ?: Ġthrow ĠIllegalArgumentException (" Bad Ġmode : Ġ$ value ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ