package Ġday 1 8 Ċ Ċ import Ġjava . io . File Ċ import Ġjava . lang . Integer . max Ċ Ċ fun Ġmain () Ġ{ ĊĠĠĠ Ġval Ġdata Ġ= Ġparse (" src / main / kotlin / day 1 8 / Day 1 8 . txt ") ĊĊĠĠĠ Ġval Ġanswer 1 Ġ= Ġpart 1 ( data ) ĊĠĠĠ Ġval Ġanswer 2 Ġ= Ġpart 2 ( data ) ĊĊĠĠĠ Ġprintln (" ðŁ İ Ħ ĠDay Ġ 1 8 ĠðŁİ Ħ ") ĊĊĠĠĠ Ġprintln () ĊĊĠĠĠ Ġprintln ("[ Part Ġ 1 ]") ĊĠĠĠ Ġprintln (" Answer : Ġ$ answer 1 ") ĊĊĠĠĠ Ġprintln () ĊĊĠĠĠ Ġprintln ("[ Part Ġ 2 ]") ĊĠĠĠ Ġprintln (" Answer : Ġ$ answer 2 ") Ċ } Ċ Ċ /* Ċ Ġ* ĠAST Ċ Ġ*/ Ċ Ċ private Ġsealed Ġinterface ĠElement Ġ{ ĊĠĠĠ Ġ@ Jvm Inline ĊĠĠĠ Ġvalue Ġclass ĠNumber ( val Ġvalue : ĠInt ) Ġ: ĠElement Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= Ġvalue . toString () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġdata Ġclass ĠPair ( val Ġlhs : ĠElement , Ġval Ġrhs : ĠElement ) Ġ: ĠElement Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= Ġ" [$ lhs ,$ rhs ]" ĊĠĠĠ Ġ} Ċ } Ċ Ċ /* Ċ Ġ* ĠParsing Ċ Ġ*/ Ċ Ċ private Ġfun Ġparse ( path : ĠString ): ĠList < Element > Ġ= ĊĠĠĠ ĠFile ( path ) ĊĠĠĠĠĠĠĠ Ġ. read Lines () ĊĠĠĠĠĠĠĠ Ġ. map ( String :: to Element ) Ċ Ċ private Ġfun ĠString . to Element (): ĠElement Ġ= ĊĠĠĠ ĠParser State ( source Ġ= Ġthis ). element () Ċ Ċ private Ġdata Ġclass ĠParser State ( ĊĠĠĠ Ġval Ġsource : ĠString , ĊĠĠĠ Ġvar Ġcurrent : ĠInt Ġ= Ġ 0 , Ċ ) Ċ Ċ /* ĠParsing ĠPri mitives Ġ*/ Ċ Ċ private Ġfun ĠParser State . peek (): ĠChar Ġ= ĊĠĠĠ Ġsource [ current ] Ċ Ċ private Ġfun ĠParser State . next (): ĠChar Ġ= ĊĠĠĠ Ġsource [ current ++] Ċ Ċ /* ĠSyntax ĠRules Ġ*/ Ċ Ċ /* Ċ Ġ* Ġelement Ġ::= Ġpair Ġ| Ġnumber Ċ Ġ*/ Ċ private Ġfun ĠParser State . element (): ĠElement Ġ{ ĊĠĠĠ Ġreturn Ġif Ġ( peek () Ġ== Ġ'[ ') Ġ{ ĊĠĠĠĠĠĠĠ Ġpair () ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġnumber () ĊĠĠĠ Ġ} Ċ } Ċ Ċ /* Ċ Ġ* Ġpair Ġ::= Ġ'[' Ġelement Ġ',' Ġelement Ġ' ]' Ċ Ġ*/ Ċ private Ġfun ĠParser State . pair (): ĠElement Ġ{ ĊĠĠĠ Ġnext () Ġ// Ġskip Ġ[ ĊĠĠĠ Ġval Ġlhs Ġ= Ġelement () ĊĠĠĠ Ġnext () Ġ// Ġskip Ġ, ĊĠĠĠ Ġval Ġrhs Ġ= Ġelement () ĊĠĠĠ Ġnext () Ġ// Ġskip Ġ] ĊĠĠĠ Ġreturn ĠElement . Pair ( lhs , Ġrhs ) Ċ } Ċ Ċ /* Ċ Ġ* Ġnumber Ġ::= Ġ[ 0 - 9 ]+ Ċ Ġ*/ Ċ private Ġfun ĠParser State . number (): ĠElement Ġ{ ĊĠĠĠ Ġvar Ġresult Ġ= Ġ 0 ĊĠĠĠ Ġwhile Ġ( peek (). is Digit ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġresult Ġ= Ġresult Ġ* Ġ 1 0 Ġ+ Ġnext (). digit ToInt () ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn ĠElement . Number ( result ) Ċ } Ċ Ċ /* Ċ Ġ* ĠRed uction Ċ Ġ*/ Ċ Ċ /* Ċ Ġ* ĠEvery Ġreduction Ġattempt Ġmay Ġeither Ġsucceed Ġand Ġyield Ġa Ġnew Ġsimplified Ġtree , Ċ Ġ* Ġor Ġfail Ġin Ġcase Ġthe Ġtree Ġcould Ġnot Ġbe Ġsimplified Ġany Ġfurther . Ċ Ġ*/ Ċ private Ġsealed Ġinterface ĠRed uction Ġ{ ĊĠĠĠ Ġ@ Jvm Inline ĊĠĠĠ Ġvalue Ġclass ĠSuccess ( val Ġvalue : ĠElement ) Ġ: ĠRed uction ĊĊĠĠĠ Ġobject ĠFailure Ġ: ĠRed uction Ċ } Ċ Ċ /* Ċ Ġ* ĠFull y Ġreduces Ġan Ġelement Ġby Ġrepeatedly Ġperforming Ġreduction Ġsteps Ġuntil Ċ Ġ* Ġthere Ġis Ġnothing Ġmore Ġto Ġreduce . ĠAt Ġthe Ġpoint Ġwhen Ġno Ġfurther Ġreduction Ċ Ġ* Ġmay Ġhappen , Ġthis Ġfunction Ġreturns Ġthe Ġoriginal Ġelement . Ċ Ġ*/ Ċ private Ġtail rec Ġfun Ġreduce ( element : ĠElement ): ĠElement Ġ= ĊĠĠĠ Ġwhen Ġ( val Ġresult Ġ= Ġstep ( element )) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠRed uction . Success Ġ-> Ġreduce ( result . value ) ĊĠĠĠĠĠĠĠ Ġis ĠRed uction . Failure Ġ-> Ġelement ĊĠĠĠ Ġ} Ċ Ċ /* Ċ Ġ* ĠAt tempts Ġto Ġperform Ġa Ġsingle Ġreduction Ġstep . ĠAccording Ġto Ġthe Ġrules , Ċ Ġ* Ġexplo ding Ġhas Ġhigher Ġpriority Ġthan Ġsplitting , Ġso Ġeach Ġaction Ġis Ġtried Ċ Ġ* Ġin Ġorder Ġuntil Ġone Ġof Ġthem Ġsucceeds . Ċ Ġ*/ Ċ private Ġfun Ġstep ( element : ĠElement ): ĠRed uction Ġ{ ĊĠĠĠ Ġval Ġactions Ġ= ĠarrayOf (:: explode , Ġ:: split ) ĊĠĠĠ Ġfor Ġ( action Ġin Ġactions ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġaction ( element ) ĊĠĠĠĠĠĠĠ Ġif Ġ( result Ġis ĠRed uction . Success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn ĠRed uction . Failure Ċ } Ċ Ċ /* Ċ Ġ* ĠExplo ding Ċ Ġ*/ Ċ Ċ /* Ċ Ġ* ĠAt tempts Ġto Ġreduce Ġthe Ġtree Ġby Ġexplo ding Ġits Ġleft most Ġpair Ġnested Ġfour Ċ Ġ* Ġlevels Ġdeep . ĠIf Ġno Ġsuch Ġpair Ġexists , Ġreturns Ġa Ġfailure . Ċ Ġ*/ Ċ private Ġfun Ġexplode ( element : ĠElement ): ĠRed uction Ġ= ĊĠĠĠ Ġexplode At ( element , Ġdepth Ġ= Ġ 0 ). let Ġ{ Ġexplo sion Ġ-> ĊĠĠĠĠĠĠĠ Ġwhen Ġ( explo sion ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠExplo sion . Success Ġ-> ĠRed uction . Success ( explo sion . result ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠExplo sion . Failure Ġ-> ĠRed uction . Failure ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ /* Ċ Ġ* ĠExplo sion s Ġare Ġnot Ġstraightforward Ġreduction s Ġbecause Ġthey Ġrequire Ġthe Ċ Ġ* Ġcontext Ġof Ġthe Ġentire Ġtree : Ġthe Ġnumbers Ġstored Ġin Ġthe Ġ" explo ded " Ġpair Ċ Ġ* Ġmust Ġbe Ġadded Ġto Ġthe Ġnumbers Ġthat Ġare Ġimmediately Ġto Ġthe Ġleft Ġand Ġright , Ċ Ġ* Ġwhich Ġwill Ġbe Ġcontained Ġby Ġother Ġbranches . Ċ Ġ* Ċ Ġ* ĠSince Ġtree Ġelements Ġdo Ġnot Ġhave Ġreferences Ġto Ġtheir Ġparents , Ġthis Ġaddition Ċ Ġ* Ġcannot Ġhappen Ġdirectly . ĠInstead , Ġexplo sion s Ġare Ġhandled Ġrecursively , Ġwith Ċ Ġ* Ġeach Ġparent Ġelement Ġmaking Ġcalls Ġto Ġits Ġchildren . ĠThis Ġmeans Ġthat , Ġin Ġorder Ċ Ġ* Ġto Ġaccess Ġan Ġelement 's Ġparent , Ġwe Ġneed Ġto Ġreturn Ġto Ġthe Ġprevious Ġcall Ġframe . Ċ Ġ* Ċ Ġ* ĠTherefore , Ġall Ġthe Ġinformation Ġnecessary Ġto Ġperform Ġan Ġexplo sion Ġhas Ġto Ċ Ġ* Ġpropagate Ġup Ġthe Ġcall Ġstack , Ġand Ġit Ġis Ġthen Ġthe Ġcall ers ' Ġresponsibility Ġto Ċ Ġ* Ġ" finish " Ġthe Ġwork . ĠThis Ġtype Ġis Ġused Ġto Ġencode Ġan Ġexplo sion Ġin - progress . Ċ Ġ*/ Ċ private Ġsealed Ġinterface ĠExplo sion Ġ{ ĊĠĠĠ Ġdata Ġclass ĠSuccess ( ĊĠĠĠĠĠĠĠ Ġval Ġresult : ĠElement , ĊĠĠĠĠĠĠĠ Ġval Ġdelta : ĠDelta ĊĠĠĠ Ġ) Ġ: ĠExplo sion ĊĊĠĠĠ Ġobject ĠFailure Ġ: ĠExplo sion Ċ } Ċ Ċ /* Ċ Ġ* ĠThe Ġexplo sion 's Ġdelta Ġis Ġthe Ġpair Ġof Ġnumbers Ġthat Ġshould Ġbe Ġadded Ġto Ġthe Ċ Ġ* Ġnumbers Ġon Ġthe Ġleft Ġand Ġright Ġfrom Ġthe Ġexplo sion Ġpoint . ĠBecause Ġthis Ġprocess Ċ Ġ* Ġhappens Ġgrad ually Ġas Ġwe Ġmove Ġup Ġthe Ġcall Ġstack , Ġwe Ġneed Ġa Ġway Ġto Ġsign ify Ċ Ġ* Ġthat Ġeither Ġside Ġof Ġthe Ġdelta Ġhas Ġalready Ġbeen Ġhandled , Ġwhich Ġis Ġwhy Ġthey Ċ Ġ* Ġare Ġnullable . Ċ Ġ*/ Ċ private Ġdata Ġclass ĠDelta ( ĊĠĠĠ Ġval Ġlhs : ĠInt ?, ĊĠĠĠ Ġval Ġrhs : ĠInt ?, Ċ ) Ċ Ċ /* Ċ Ġ* ĠAt tempts Ġto Ġexplode Ġan Ġelement Ġat Ġsome Ġdepth . Ċ Ġ*/ Ċ private Ġfun Ġexplode At ( element : ĠElement , Ġdepth : ĠInt ): ĠExplo sion Ġ= ĊĠĠĠ Ġwhen Ġ( element ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠElement . Pair Ġ-> Ġexplode At ( element , Ġdepth ) ĊĠĠĠĠĠĠĠ Ġis ĠElement . Number Ġ-> Ġexplode At ( element , Ġdepth ) ĊĠĠĠ Ġ} Ċ Ċ private Ġfun Ġexplode At ( element : ĠElement . Pair , Ġdepth : ĠInt ): ĠExplo sion Ġ{ ĊĠĠĠ Ġif Ġ( depth Ġ== Ġ 4 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠExplo sion . Success ( Element . Number ( 0 ), Ġelement . to Delta ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġexplode At ( element . lhs , Ġdepth Ġ+ Ġ 1 ). let Ġ{ Ġexplo sion Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( explo sion Ġ! is ĠExplo sion . Success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ let ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġ( result , Ġdelta ) Ġ= Ġexplo sion ĊĠĠĠĠĠĠĠ Ġval Ġright Ġ= Ġwhen Ġ( delta . rhs ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull Ġ-> Ġelement . rhs ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġelement . rhs . addTo Left most ( delta . rhs ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġtree Ġ= ĠElement . Pair ( result , Ġright ) ĊĠĠĠĠĠĠĠ Ġreturn ĠExplo sion . Success ( tree , ĠDelta ( delta . lhs , Ġnull )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġexplode At ( element . rhs , Ġdepth Ġ+ Ġ 1 ). let Ġ{ Ġexplo sion Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( explo sion Ġ! is ĠExplo sion . Success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ let ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġ( result , Ġdelta ) Ġ= Ġexplo sion ĊĠĠĠĠĠĠĠ Ġval Ġleft Ġ= Ġwhen Ġ( delta . lhs ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull Ġ-> Ġelement . lhs ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġelement . lhs . addTo Right most ( delta . lhs ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġtree Ġ= ĠElement . Pair ( left , Ġresult ) ĊĠĠĠĠĠĠĠ Ġreturn ĠExplo sion . Success ( tree , ĠDelta ( null , Ġdelta . rhs )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn ĠExplo sion . Failure Ċ } Ċ Ċ /* Ċ Ġ* ĠA Ġnumber Ġmay Ġnever Ġexplode , Ġtherefore Ġthis Ġis Ġa Ġno - op Ġthat Ġalways Ġfails . Ċ Ġ*/ Ċ private Ġfun Ġexplode At ( element : ĠElement . Number , Ġdepth : ĠInt ): ĠExplo sion Ġ= ĊĠĠĠ ĠExplo sion . Failure Ċ Ċ private Ġfun ĠElement . Pair . to Delta (): ĠDelta Ġ{ ĊĠĠĠ Ġval Ġlhs Ġ= Ġ( lhs Ġas ĠElement . Number ). value ĊĠĠĠ Ġval Ġrhs Ġ= Ġ( rhs Ġas ĠElement . Number ). value ĊĠĠĠ Ġreturn ĠDelta ( lhs , Ġrhs ) Ċ } Ċ Ċ private Ġfun ĠElement . addTo Left most ( delta : ĠInt ): ĠElement Ġ= ĊĠĠĠ Ġwhen Ġ( this ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠElement . Number Ġ-> ĠElement . Number ( value Ġ+ Ġdelta ) ĊĠĠĠĠĠĠĠ Ġis ĠElement . Pair Ġ-> Ġcopy ( lhs Ġ= Ġlhs . addTo Left most ( delta )) ĊĠĠĠ Ġ} Ċ Ċ private Ġfun ĠElement . addTo Right most ( delta : ĠInt ): ĠElement Ġ= ĊĠĠĠ Ġwhen Ġ( this ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠElement . Number Ġ-> ĠElement . Number ( value Ġ+ Ġdelta ) ĊĠĠĠĠĠĠĠ Ġis ĠElement . Pair Ġ-> Ġcopy ( rhs Ġ= Ġrhs . addTo Right most ( delta )) ĊĠĠĠ Ġ} Ċ Ċ /* Ċ Ġ* ĠSplit ting Ċ Ġ*/ Ċ Ċ /* Ċ Ġ* ĠAt tempts Ġto Ġreduce Ġthe Ġtree Ġby Ġsplitting Ġits Ġleft most Ġnumber Ġthat Ġis Ġgreater Ċ Ġ* Ġthan Ġ 9 . ĠIf Ġno Ġsuch Ġnumber Ġexists , Ġreturns Ġa Ġfailure . Ċ Ġ*/ Ċ private Ġfun Ġsplit ( element : ĠElement ): ĠRed uction Ġ= ĊĠĠĠ Ġwhen Ġ( element ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠElement . Pair Ġ-> Ġsplit ( element ) ĊĠĠĠĠĠĠĠ Ġis ĠElement . Number Ġ-> Ġsplit ( element ) ĊĠĠĠ Ġ} Ċ Ċ /* Ċ Ġ* ĠAt tempts Ġto Ġsplit Ġeach Ġbranch Ġof Ġa Ġpair , Ġstarting Ġwith Ġthe Ġleft most Ġand Ċ Ġ* Ġterminating Ġon Ġfirst Ġsuccess . Ċ Ġ*/ Ċ private Ġfun Ġsplit ( element : ĠElement . Pair ): ĠRed uction Ġ{ ĊĠĠĠ Ġsplit ( element . lhs ). let Ġ{ Ġresult Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( result Ġis ĠRed uction . Success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ split ĠRed uction . Success ( element . copy ( lhs Ġ= Ġresult . value )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsplit ( element . rhs ). let Ġ{ Ġresult Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( result Ġis ĠRed uction . Success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ split ĠRed uction . Success ( element . copy ( rhs Ġ= Ġresult . value )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn ĠRed uction . Failure Ċ } Ċ Ċ /* Ċ Ġ* ĠAt tempts Ġto Ġsplit Ġa Ġnumber Ġif Ġit Ġme ets Ġthe Ġreduction Ġcriterion . Ċ Ġ*/ Ċ private Ġfun Ġsplit ( element : ĠElement . Number ): ĠRed uction Ġ= ĊĠĠĠ Ġif Ġ( element . value Ġ> Ġ 9 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlhs Ġ= ĠElement . Number (( element . value Ġ+ Ġ 0 ) Ġ/ Ġ 2 ) ĊĠĠĠĠĠĠĠ Ġval Ġrhs Ġ= ĠElement . Number (( element . value Ġ+ Ġ 1 ) Ġ/ Ġ 2 ) ĊĠĠĠĠĠĠĠ ĠRed uction . Success ( Element . Pair ( lhs , Ġrhs )) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ ĠRed uction . Failure ĊĠĠĠ Ġ} Ċ Ċ /* Ċ Ġ* ĠEvaluation Ċ Ġ*/ Ċ Ċ private Ġoperator Ġfun ĠElement . plus ( other : ĠElement ): ĠElement Ġ= ĊĠĠĠ ĠElement . Pair ( this , Ġother ). run (:: reduce ) Ċ Ċ private Ġfun Ġmagnitude ( element : ĠElement ): ĠInt Ġ= ĊĠĠĠ Ġwhen Ġ( element ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠElement . Pair Ġ-> Ġmagnitude ( element . lhs ) Ġ* Ġ 3 Ġ+ Ġmagnitude ( element . rhs ) Ġ* Ġ 2 ĊĠĠĠĠĠĠĠ Ġis ĠElement . Number Ġ-> Ġelement . value ĊĠĠĠ Ġ} Ċ Ċ private Ġfun Ġpart 1 ( elements : ĠList < Element >) Ġ= ĊĠĠĠ Ġelements ĊĠĠĠĠĠĠĠ Ġ. reduce ( Element :: plus ) ĊĠĠĠĠĠĠĠ Ġ. run (:: magnitude ) Ċ Ċ private Ġfun Ġpart 2 ( elements : ĠList < Element >): ĠInt Ġ{ ĊĠĠĠ Ġvar Ġmax Ġ= Ġ 0 ĊĠĠĠ Ġfor Ġ(( i , Ġx ) Ġin Ġelements . with Index ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ(( j , Ġy ) Ġin Ġelements . with Index ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( i Ġ== Ġj ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġm 1 Ġ= Ġmagnitude ( x Ġ+ Ġy ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġm 2 Ġ= Ġmagnitude ( y Ġ+ Ġx ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Ġ= Ġmax ( m 1 , Ġm 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current Ġ> Ġmax ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmax Ġ= Ġcurrent ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġmax Ċ } Ċ