/** Ċ Ġ* ĠDay Ġ 1 6 : ĠPacket ĠDecoder Ċ Ġ*/ Ċ Ċ package Ġdev . paul shields . a oc Ċ Ċ import Ġdev . paul shields . a oc . common . readFile AsString Ċ Ċ fun Ġmain () Ġ{ ĊĠĠĠ Ġprintln (" Ġ** ĠDay Ġ 1 6 : ĠPacket ĠDecoder Ġ** Ġ\ n ") ĊĊĠĠĠ Ġval Ġpacket Trans mission Ġ= ĠreadFile AsString ("/ Day 1 6 BIT ST rans mission . txt ") ĊĊĠĠĠ Ġval Ġpacket Versions Sum Ġ= Ġsum All Version Numbers In Bits Packets ( packet Trans mission ) ĊĠĠĠ Ġprintln (" Sum Ġof Ġall Ġpacket Ġversions Ġis Ġ$ packet Versions Sum ") ĊĊĠĠĠ Ġval Ġresult From Bits Packet Ġ= Ġcalculate Result From All Bits Packets ( packet Trans mission ). first () ĊĠĠĠ Ġprintln (" The Ġfinal Ġcalculated Ġresult Ġfrom Ġthe ĠB ITS Ġpackets Ġis Ġ$ result From Bits Packet ") Ċ } Ċ Ċ fun Ġsum All Version Numbers In Bits Packets ( packet Trans mission As Hex : ĠString ) Ġ= ĊĠĠĠ Ġsum All Version Numbers In Bits Packets ( decode Packets ( packet Trans mission As Hex )) Ċ Ċ private Ġfun Ġsum All Version Numbers In Bits Packets ( packet Trans mission : ĠList < Packet >): ĠInt Ġ= ĊĠĠĠ Ġpacket Trans mission . sum Of Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠOperator Packet Ġ-> Ġsum All Version Numbers In Bits Packets ( it . sub Packets ) Ġ+ Ġit . packet Version ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLiteral Packet Ġ-> Ġit . packet Version ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ fun Ġcalculate Result From All Bits Packets ( packet Trans mission As Hex : ĠString ) Ġ= Ġcalculate Result From All Bits Packets ( decode Packets ( packet Trans mission As Hex )) Ċ Ċ private Ġfun Ġcalculate Result From All Bits Packets ( packet Trans mission : ĠList < Packet >) Ġ= ĊĠĠĠ Ġpacket Trans mission . filter Is Instance < Operator Packet >(). map (:: calculate Result From Bits Packet ) Ċ Ċ private Ġfun Ġcalculate Result From Bits Packet ( packet : ĠOperator Packet ): ĠLong Ġ{ ĊĠĠĠ Ġval Ġsub Packet Values Ġ= Ġpacket . sub Packets . map NotNull Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠOperator Packet Ġ-> Ġcalculate Result From Bits Packet ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLiteral Packet Ġ-> Ġit . literal ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġwhen Ġ( packet . operator Packet Type ) Ġ{ ĊĠĠĠĠĠĠĠ ĠOperator Packet Type . SUM Ġ-> Ġsub Packet Values . sum () ĊĠĠĠĠĠĠĠ ĠOperator Packet Type . PRODUCT Ġ-> Ġsub Packet Values . fold ( 1 ) Ġ{ Ġaccumulator , Ġvalue Ġ-> Ġaccumulator Ġ* Ġvalue Ġ} ĊĠĠĠĠĠĠĠ ĠOperator Packet Type . MIN IMUM Ġ-> Ġsub Packet Values . min OrNull () Ġ?: Ġ 0 ĊĠĠĠĠĠĠĠ ĠOperator Packet Type . MAXIMUM Ġ-> Ġsub Packet Values . max OrNull () Ġ?: Ġ 0 ĊĠĠĠĠĠĠĠ ĠOperator Packet Type . GRE ATER _ THAN Ġ-> Ġif Ġ( sub Packet Values [ 0 ] Ġ> Ġsub Packet Values [ 1 ]) Ġ 1 Ġelse Ġ 0 ĊĠĠĠĠĠĠĠ ĠOperator Packet Type . LESS _ THAN Ġ-> Ġif Ġ( sub Packet Values [ 0 ] Ġ< Ġsub Packet Values [ 1 ]) Ġ 1 Ġelse Ġ 0 ĊĠĠĠĠĠĠĠ ĠOperator Packet Type . EQUAL _ TO Ġ-> Ġif Ġ( sub Packet Values [ 0 ] Ġ== Ġsub Packet Values [ 1 ]) Ġ 1 Ġelse Ġ 0 ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġdecode Packets ( packet Trans mission As Hex : ĠString ) Ġ= Ġdecode Packets ( binary Buffer From Hex ( packet Trans mission As Hex )) Ċ Ċ private Ġfun Ġdecode Packets ( packet Trans mission : ĠBinary Buffer ): ĠList < Packet > Ġ{ ĊĠĠĠ Ġval Ġpackets Ġ= Ġmutable ListOf < Packet >() ĊĠĠĠ Ġwhile Ġ(! packet Trans mission . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġpackets . add ( decode Packet ( packet Trans mission )) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġpackets Ċ } Ċ Ċ private Ġfun Ġdecode Packet ( packet Trans mission : ĠBinary Buffer ): ĠPacket Ġ{ ĊĠĠĠ Ġval Ġpacket Version Ġ= Ġpacket Trans mission . take Int ( 3 ) ĊĠĠĠ Ġval Ġpacket Type Ġ= Ġpacket Trans mission . take Int ( 3 ) ĊĊĠĠĠ Ġreturn Ġwhen Ġ( packet Type ) Ġ{ ĊĠĠĠĠĠĠĠĠ 4 Ġ-> Ġdecode Literal Packet ( packet Version , Ġpacket Trans mission ) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġdecode Operator Packet ( packet Version , Ġpacket Type , Ġpacket Trans mission ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġdecode Literal Packet ( packet Version : ĠInt , Ġpacket Trans mission : ĠBinary Buffer ): ĠLiteral Packet Ġ{ ĊĠĠĠ Ġval Ġhalf Bytes Ġ= Ġmutable ListOf < String >() ĊĊĠĠĠ Ġdo Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontinue Bit Ġ= Ġpacket Trans mission . take Boolean () ĊĠĠĠĠĠĠĠ Ġhalf Bytes . add ( packet Trans mission . take Bits ( 4 )) ĊĠĠĠ Ġ} Ġwhile Ġ( continue Bit ) ĊĊĠĠĠ Ġval Ġliteral Ġ= Ġhalf Bytes . join ToString (" "). to Long ( 2 ) ĊĠĠĠ Ġreturn ĠLiteral Packet ( packet Version , Ġliteral ) Ċ } Ċ Ċ private Ġfun Ġdecode Operator Packet ( packet Version : ĠInt , Ġpacket Type : ĠInt , Ġpacket Trans mission : ĠBinary Buffer ): ĠOperator Packet Ġ{ ĊĠĠĠ Ġval Ġlength TypeId Ġ= Ġpacket Trans mission . take Bits ( 1 ) ĊĠĠĠ Ġval Ġsub Packets Ġ= Ġwhen Ġ( length TypeId ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" 0 " Ġ-> Ġdecode Operator Sub Packets Using Length Of Packets ( packet Trans mission ) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġdecode Operator Sub Packets Using NumberOf Packets ( packet Trans mission ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn ĠOperator Packet ( packet Version , ĠOperator Packet Type . from Int ( packet Type ), Ġsub Packets ) Ċ } Ċ Ċ private Ġfun Ġdecode Operator Sub Packets Using Length Of Packets ( packet Trans mission : ĠBinary Buffer ): ĠList < Packet > Ġ{ ĊĠĠĠ Ġval Ġlength Of Sub Packets Ġ= Ġpacket Trans mission . take Int ( 1 5 ) ĊĠĠĠ Ġval Ġsub Packet Buffer Ġ= ĠBinary Buffer ( packet Trans mission . take Bits ( length Of Sub Packets )) ĊĠĠĠ Ġreturn Ġdecode Packets ( sub Packet Buffer ) Ċ } Ċ Ċ private Ġfun Ġdecode Operator Sub Packets Using NumberOf Packets ( packet Trans mission : ĠBinary Buffer ): ĠList < Packet > Ġ{ ĊĠĠĠ Ġval ĠnumberOf Sub Packets Ġ= Ġpacket Trans mission . take Int ( 1 1 ) ĊĠĠĠ Ġreturn Ġ( 0 Ġuntil ĠnumberOf Sub Packets ). map Ġ{ Ġdecode Packet ( packet Trans mission ) Ġ} Ċ } Ċ Ċ open Ġclass ĠPacket ( open Ġval Ġpacket Version : ĠInt ) Ċ data Ġclass ĠLiteral Packet ( override Ġval Ġpacket Version : ĠInt , Ġval Ġliteral : ĠLong ) Ġ: ĠPacket ( packet Version ) Ċ data Ġclass ĠOperator Packet ( ĊĠĠĠ Ġoverride Ġval Ġpacket Version : ĠInt , ĊĠĠĠ Ġval Ġoperator Packet Type : ĠOperator Packet Type , ĊĠĠĠ Ġval Ġsub Packets : ĠList < Packet >) Ġ: ĠPacket ( packet Version ) Ċ Ċ enum Ġclass ĠOperator Packet Type ( val Ġoperator Type : ĠInt ) Ġ{ ĊĠĠĠ ĠSUM ( 0 ), ĊĠĠĠ ĠPRODUCT ( 1 ), ĊĠĠĠ ĠMIN IMUM ( 2 ), ĊĠĠĠ ĠMAX IMUM ( 3 ), ĊĠĠĠ ĠG RE ATER _ THAN ( 5 ), ĊĠĠĠ ĠL ESS _ THAN ( 6 ), ĊĠĠĠ ĠEQUAL _ TO ( 7 ); ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġfrom Int ( value : ĠInt ) Ġ= Ġvalues (). first Ġ{ Ġit . operator Type Ġ== Ġvalue Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġclass ĠBinary Buffer ( private Ġval Ġbinary String : ĠString ) Ġ{ ĊĠĠĠ Ġprivate Ġvar Ġbuffer Position Ġ= Ġ 0 ĊĊĠĠĠ Ġfun Ġtake Bits ( bits : ĠInt ) Ġ= ĊĠĠĠĠĠĠĠ Ġbinary String ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. substring ( buffer Position , Ġbuffer Position Ġ+ Ġbits ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. also Ġ{ Ġbuffer Position Ġ+= Ġbits Ġ} ĊĊĠĠĠ Ġfun Ġtake Int ( bits : ĠInt ) Ġ= ĊĠĠĠĠĠĠĠ Ġbinary String ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. substring ( buffer Position , Ġbuffer Position Ġ+ Ġbits ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. toInt ( 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. also Ġ{ Ġbuffer Position Ġ+= Ġbits Ġ} ĊĊĠĠĠ Ġfun Ġtake Boolean () Ġ= Ġbinary String [ buffer Position ++] Ġ== Ġ' 1 ' ĊĊĠĠĠ Ġfun ĠisEmpty () Ġ= Ġ! binary String . substring ( buffer Position ). contains (' 1 ') Ċ } Ċ Ċ private Ġfun Ġbinary Buffer From Hex ( hex String : ĠString ) Ġ= ĠBinary Buffer ( parse Hex ( hex String )) Ċ Ċ private Ġfun Ġparse Hex ( packet Trans mission As Hex : ĠString ) Ġ= ĊĠĠĠ Ġpacket Trans mission As Hex ĊĠĠĠĠĠĠĠ Ġ. toCharArray () ĊĠĠĠĠĠĠĠ Ġ. join ToString ("") Ġ{ Ġit . digit ToInt ( 1 6 ). toString ( 2 ). pad Start ( 4 , Ġ' 0 ') Ġ} Ċ