/* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 2 1 Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttps :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġcom . fa endir . z ach tron ics . bot . om Ċ Ċ import Ġcom . fa endir . om . parser . solution . Solution Parser Ċ import Ġcom . fa endir . om . parser . solution . model . Position Ċ import Ġcom . fa endir . om . parser . solution . model . Solution Ċ import Ġcom . fa endir . om . parser . solution . model . S olved Solution Ċ import Ġcom . fa endir . om . parser . solution . model . part . Arm Ċ import Ġcom . fa endir . om . parser . solution . model . part . Arm Type Ċ import Ġcom . fa endir . om . parser . solution . model . part . Con duit Ċ import Ġcom . fa endir . om . parser . solution . model . part . Glyph Ċ import Ġcom . fa endir . om . parser . solution . model . part . IO Ċ import Ġcom . fa endir . om . parser . solution . model . part . IO Type Ċ import Ġcom . fa endir . om . parser . solution . model . part . Part Ċ import Ġcom . fa endir . om . parser . solution . model . part . Track Ċ import Ġcom . fa endir . z ach tron ics . bot . om . discord . plus Ċ import Ġcom . fa endir . z ach tron ics . bot . om . discord . rotate Ċ import Ġcom . fa endir . z ach tron ics . bot . om . model . FULL _ CIR CLE Ċ import Ġcom . fa endir . z ach tron ics . bot . om . model . Om Category Ċ import Ġcom . fa endir . z ach tron ics . bot . om . model . Om P uzzle Ċ import Ġcom . fa endir . z ach tron ics . bot . om . model . Om Record Ċ import Ġcom . fa endir . z ach tron ics . bot . om . model . Om Score Ċ import Ġcom . fa endir . z ach tron ics . bot . om . model . Om Score Part Ċ import Ġcom . fa endir . z ach tron ics . bot . om . model . Om Submission Ċ import Ġcom . fa endir . z ach tron ics . bot . om . model . SINGLE Ċ import Ġcom . fa endir . z ach tron ics . bot . repository . Category Record Ċ import Ġok io . buffer Ċ import Ġok io . sink Ċ import Ġok io . source Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġorg . springframework . http . Http Entity Ċ import Ġorg . springframework . http . HttpHeaders Ċ import Ġorg . springframework . http . MediaType Ċ import Ġorg . springframework . util . Linked Multi Value Map Ċ import Ġorg . springframework . web . client . Rest Template Ċ import Ġjava . io . ByteArray InputStream Ċ import Ġjava . io . File ĊĊ Ċ private Ġval Ġlogger Ġ= ĠLoggerFactory . getLogger (" OM ĠUtils ") Ċ Ċ fun ĠSolution . get Metrics ( pu zzle : ĠOm P uzzle , Ġvar arg Ġmetrics : ĠOm Score Part ): ĠMap < Om Score Part , ĠNumber ?> ? Ġ{ ĊĠĠĠ Ġval Ġpuzzle File Ġ= Ġpuzzle . file ?. take If Ġ{ Ġit . exists () Ġ} Ġ?: Ġreturn Ġnull ĊĠĠĠ Ġval Ġsolution Ġ= ĠFile . create TempFile ( pu zzle . id , Ġ". solution "). also Ġ{ ĠSolution Parser . write ( this , Ġit . output Stream (). sink (). buffer ()) Ġ} ĊĠĠĠ Ġreturn ĠJ N IS olution Verifier . open ( pu zzle File , Ġsolution ). use Ġ{ Ġverifier Ġ-> ĊĠĠĠĠĠĠĠ Ġverifier . get Metrics ( metrics . toList ()) Ġ{ Ġe , Ġ_ Ġ-> Ġlogger . info (" Verifier Ġthrew Ġexception ", Ġe ) Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠJ N IS olution Verifier . get Metrics ( metrics : ĠList < Om Score Part >, Ġhandle Exception : Ġ( Exception , ĠOm Score Part ) Ġ-> ĠUnit ): ĠMap < Om Score Part , ĠNumber ?> Ġ= ĊĠĠĠ Ġmetrics . associate With Ġ{ Ġmetric Ġ-> ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( metric ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOm Score Part . HEIGHT Ġ-> Ġget Metric ( JN IS olution Verifier . Metrics . HEIGHT ). take If Ġ{ Ġit Ġ!= Ġ- 1 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOm Score Part . WIDTH Ġ-> Ġget Metric ( JN IS olution Verifier . Metrics . WIDTH _ TIMES _ TWO ). let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ- 1 Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠInt . MAX _ VALUE Ġ-> ĠInt . MAX _ VALUE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġit . toDouble () Ġ/ Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOm Score Part . CO ST Ġ-> Ġget Metric ( JN IS olution Verifier . Metrics . CO ST ). take If Ġ{ Ġit Ġ!= Ġ- 1 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOm Score Part . CY C LES Ġ-> Ġget Metric ( JN IS olution Verifier . Metrics . CY C LES ). take If Ġ{ Ġit Ġ!= Ġ- 1 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOm Score Part . AREA Ġ-> Ġget Metric ( JN IS olution Verifier . Metrics . AREA ). take If Ġ{ Ġit Ġ!= Ġ- 1 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOm Score Part . INSTR UCTION S Ġ-> Ġget Metric ( JN IS olution Verifier . Metrics . INSTR UCTION S ). take If Ġ{ Ġit Ġ!= Ġ- 1 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOm Score Part . RATE Ġ-> Ġget Metric ( JN IS olution Verifier . Metrics . TH RO UG HP UT _ CY C LES ). let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ- 1 Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠInt . MAX _ VALUE Ġ-> ĠInt . MAX _ VALUE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġit . toDouble () Ġ/ Ġget Metric ( JN IS olution Verifier . Metrics . TH RO UG HP UT _ OUTPUT S ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Exception ( e , Ġmetric ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ fun ĠSolution . is Track less (): ĠBoolean Ġ= Ġparts . none Ġ{ Ġit Ġis ĠTrack Ġ} Ċ Ċ fun ĠSolution . is Overlap ( pu zzle : ĠOm P uzzle ): ĠBoolean Ġ= ĊĠĠĠ Ġparts . flatMap Indexed Ġ{ Ġindex , Ġpart Ġ-> Ġparts . sub List ( 0 , Ġindex ). map Ġ{ Ġit Ġto Ġpart Ġ} Ġ}. any Ġ{ Ġ( p 1 , Ġp 2 ) Ġ-> Ġpuzzle . overlap ( p 1 , Ġp 2 ) Ġ} ĊĊ Ċ private Ġfun ĠOm P uzzle . overlap ( p 1 : ĠPart , Ġp 2 : ĠPart ): ĠBoolean Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġp 1 Ġis ĠArm Ġ&& Ġp 2 Ġis ĠArm Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġs 1 Ġ= Ġshape ( p 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshape ( p 2 ). any Ġ{ Ġs 1 . contains ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġp 1 Ġis ĠArm Ġ&& Ġp 2 Ġis ĠTrack Ġ|| Ġp 2 Ġis ĠArm Ġ&& Ġp 1 Ġis ĠTrack Ġ-> Ġfalse ĊĠĠĠĠĠĠĠ Ġp 1 Ġis ĠArm Ġ-> Ġshape ( p 2 ). contains ( p 1 . position ) ĊĠĠĠĠĠĠĠ Ġp 2 Ġis ĠArm Ġ-> Ġshape ( p 1 ). contains ( p 2 . position ) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġs 1 Ġ= Ġshape ( p 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshape ( p 2 ). any Ġ{ Ġs 1 . contains ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠOm P uzzle . shape ( part : ĠPart ): ĠList < Position > Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( part ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠArm Ġ-> Ġif Ġ( part . type Ġ== ĠArm Type . V AN _ BER LO S _ W HE EL ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFULL _ CIR CLE ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠS INGLE ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġis ĠCon duit Ġ-> Ġpart . positions ĊĠĠĠĠĠĠĠ Ġis ĠGlyph Ġ-> Ġpart . type . shape ĊĠĠĠĠĠĠĠ Ġis ĠIO Ġ-> Ġif Ġ( part . type Ġ== ĠIO Type . INPUT ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . get Re agent Shape ( part ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . get Product Shape ( part ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġis ĠTrack Ġ-> Ġpart . positions ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalArgumentException (" Unknown Ġpart Ġtype Ġ${ part . name }") ĊĠĠĠ Ġ}. map Ġ{ Ġit . rotate ( part . rotation ) Ġ}. map Ġ{ Ġit Ġ+ Ġpart . position Ġ} Ċ } Ċ Ċ fun Ġcreate Submission ( gif : ĠString , Ġauthor : ĠString , Ġbytes : ĠByteArray ): ĠOm Submission Ġ{ ĊĠĠĠ Ġval Ġsolution Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠ ĠSolution Parser . parse ( ByteArray InputStream ( bytes ). source (). buffer ()) ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" I Ġcould Ġnot Ġparse Ġyour Ġsolution ") ĊĠĠĠ Ġ} ĊĠĠĠ Ġif Ġ( solution Ġ! is ĠS olved Solution ) Ġthrow ĠIllegalArgumentException (" only Ġsolved Ġsolutions Ġare Ġaccepted ") ĊĠĠĠ Ġval Ġpuzzle Ġ= ĠOm P uzzle . values (). find Ġ{ Ġit . id Ġ== Ġsolution . pu zzle Ġ} Ġ?: Ġthrow ĠIllegalArgumentException (" I Ġdo Ġnot Ġknow Ġthe Ġpuzzle Ġ\" ${ solution . pu zzle }\" ") ĊĠĠĠ Ġval Ġcomputed Ġ= Ġsolution . get Metrics ( pu zzle , ĠOm Score Part . WIDTH , ĠOm Score Part . HEIGHT , ĠOm Score Part . RATE ) ĊĠĠĠ Ġval Ġscore Ġ= ĠOm Score ( ĊĠĠĠĠĠĠĠ Ġcost Ġ= Ġsolution . cost , ĊĠĠĠĠĠĠĠ Ġcycles Ġ= Ġsolution . cycles , ĊĠĠĠĠĠĠĠ Ġarea Ġ= Ġsolution . area , ĊĠĠĠĠĠĠĠ Ġinstructions Ġ= Ġsolution . instructions , ĊĠĠĠĠĠĠĠ Ġheight Ġ= Ġcomputed ?. get ( Om Score Part . HEIGHT )?. toInt (), ĊĠĠĠĠĠĠĠ Ġwidth Ġ= Ġcomputed ?. get ( Om Score Part . WIDTH )?. toDouble (), ĊĠĠĠĠĠĠĠ Ġrate Ġ= Ġcomputed ?. get ( Om Score Part . RATE )?. toDouble (), ĊĠĠĠĠĠĠĠ Ġtrack less Ġ= Ġsolution . is Track less (), ĊĠĠĠĠĠĠĠ Ġoverlap Ġ= Ġsolution . is Overlap ( pu zzle ), ĊĠĠĠ Ġ) ĊĠĠĠ Ġreturn ĠOm Submission ( pu zzle , Ġscore , Ġauthor , Ġgif , Ġbytes ) Ċ } Ċ Ċ private Ġval Ġrest Template Ġ= ĠRest Template () Ċ Ċ fun Ġshort en Github Link ( github Link : ĠString ): ĠString Ġ{ ĊĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠHttp Entity ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLinked Multi Value Map ( map Of (" url " Ġto ĠlistOf ( github Link ))), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHttp Headers (). apply Ġ{ ĠcontentType Ġ= ĠMediaType . APPLICATION _ FORM _ URL ENCODE D Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġrest Template . post For Location (" https :// git . io ", Ġrequest )?. toString () Ġ?: Ġgithub Link ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . warn (" Failed Ġto Ġshort en Ġlink Ġ$ github Link ", Ġe ) ĊĠĠĠĠĠĠĠ Ġgithub Link ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠOm Record . with Category ( category : ĠOm Category ) Ġ= ĠCategory Record ( this , Ġset Of ( category ))