/* Ċ Ġ* ĠCopyright Ġ 2 0 1 6 - 2 0 2 1 ĠJetBrains Ġs . r . o . ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense . Ċ Ġ*/ Ċ Ċ package Ġbenchmarks . flow . scr ab ble Ċ Ċ import Ġkotlinx . coroutines .* Ċ import Ġkotlinx . coroutines . flow .* Ċ import Ġkotlinx . coroutines . flow . Flow Ċ import Ġorg . openjdk . j mh . annotations .* Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent .* Ċ import Ġkotlin . math .* Ċ Ċ @ W arm up ( iterations Ġ= Ġ 7 , Ġtime Ġ= Ġ 1 , Ġtime Unit Ġ= ĠTimeUnit . SECONDS ) Ċ @ Measurement ( iterations Ġ= Ġ 7 , Ġtime Ġ= Ġ 1 , Ġtime Unit Ġ= ĠTimeUnit . SECONDS ) Ċ @ Fork ( value Ġ= Ġ 1 ) Ċ @ Benchmark Mode ( Mode . Average Time ) Ċ @ Output TimeUnit ( TimeUnit . MILLISECONDS ) Ċ @ State ( Scope . Benchmark ) Ċ open Ġclass ĠFlow Play s Scr ab ble Opt Ġ: ĠSh akes pe are Play s Scr ab ble () Ġ{ ĊĊĠĠĠ Ġ@ Benchmark ĊĠĠĠ Ġpublic Ġoverride Ġfun Ġplay (): ĠList < Map . Entry < Int , ĠList < String >>> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġh isto Of Letters Ġ= Ġ{ Ġword : ĠString Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflow Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( word . as Flow (). fold ( HashMap < Int , ĠMutable Long >()) Ġ{ Ġaccumulator , Ġvalue Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar ĠnewValue : ĠMutable Long ? Ġ= Ġaccumulator [ value ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( newValue Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠnewValue Ġ= ĠMutable Long () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaccumulator [ value ] Ġ= ĠnewValue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠnewValue . inc AndSet () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaccumulator ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġblank Ġ= Ġ{ Ġentry : ĠMap . Entry < Int , ĠMutable Long > Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmax ( 0 L , Ġentry . value . get () Ġ- Ġscr ab ble Available Letters [ entry . key Ġ- Ġ' a '. toInt ()]) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġn Bl anks Ġ= Ġ{ Ġword : ĠString Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflow Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( h isto Of Letters ( word ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Concat Iterable Ġ{ Ġit . entries Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map ({ Ġblank ( it ) Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. sum () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġcheck Bl anks Ġ= Ġ{ Ġword : ĠString Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġn Bl anks ( word ). map Ġ{ Ġit Ġ<= Ġ 2 L Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġletter Score Ġ= Ġ{ Ġentry : ĠMap . Entry < Int , ĠMutable Long > Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġletter Scores [ entry . key Ġ- Ġ' a '. toInt ()] Ġ* ĠInteger . min ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry . value . get (). toInt (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscr ab ble Available Letters [ entry . key Ġ- Ġ' a '. toInt ()] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġscore 2 Ġ= Ġ{ Ġword : ĠString Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflow Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( h isto Of Letters ( word ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Concat Iterable Ġ{ Ġit . entries Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġletter Score ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. sum ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġfirst 3 Ġ= Ġ{ Ġword : ĠString Ġ-> Ġword . as Flow ( end Index Ġ= Ġ 3 ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġlast 3 Ġ= Ġ{ Ġword : ĠString Ġ-> Ġword . as Flow ( startIndex Ġ= Ġ 3 ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġto Be Max ed Ġ= Ġ{ Ġword : ĠString Ġ-> Ġconcat ( first 3 ( word ), Ġlast 3 ( word )) Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġbonus For Double Letter Ġ= Ġ{ Ġword : ĠString Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflow Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( toBe Max ed ( word ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġletter Scores [ it . toInt () Ġ- Ġ' a '. toInt ()] Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. max ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġscore 3 Ġ= Ġ{ Ġword : ĠString Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflow Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsum Ġ= Ġscore 2 ( word ). single () Ġ+ Ġbonus For Double Letter ( word ). single () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( sum Ġ* Ġ 2 Ġ+ Ġif Ġ( word . length Ġ== Ġ 7 ) Ġ 5 0 Ġelse Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġbuild H isto On Score : Ġ((( String ) Ġ-> ĠFlow < Int >) Ġ-> ĠFlow < TreeMap < Int , ĠList < String >> >) Ġ= Ġ{ Ġscore Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflow Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( sh akes pe are Words . as Flow () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter ({ Ġscr ab ble Words . contains ( it ) Ġ&& Ġcheck Bl anks ( it ). single () Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. fold ( TreeMap < Int , ĠList < String >>( Collections . reverse Order ())) Ġ{ Ġacc , Ġvalue Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġscore ( value ). single () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġlist Ġ= Ġacc [ key ] Ġas ĠMutable List < String >? ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( list Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlist Ġ= ĠArrayList () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġacc [ key ] Ġ= Ġlist ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlist . add ( value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġacc ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuild H isto On Score ( score 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Concat Iterable Ġ{ Ġit . entries Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. take ( 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. toList () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ public Ġfun ĠString . as Flow () Ġ= Ġflow Ġ{ ĊĠĠĠ ĠforEach Ġ{ ĊĠĠĠĠĠĠĠ Ġemit ( it . toInt ()) ĊĠĠĠ Ġ} Ċ } Ċ Ċ public Ġfun ĠString . as Flow ( startIndex : ĠInt Ġ= Ġ 0 , Ġend Index : ĠInt Ġ= Ġlength ) Ġ= ĊĠĠĠ ĠString By Char Flow ( this , ĠstartIndex , Ġend Index . coerce At Most ( this . length )) Ċ Ċ public Ġsuspend Ġinline Ġfun ĠFlow < Int >. sum (): ĠInt Ġ{ ĊĠĠĠ Ġval Ġcollector Ġ= Ġobject Ġ: ĠFlow Collector < Int > Ġ{ ĊĠĠĠĠĠĠĠ Ġpublic Ġvar Ġsum Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġoverride Ġsuspend Ġfun Ġemit ( value : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsum Ġ+= Ġvalue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġcollect ( collector ) ĊĠĠĠ Ġreturn Ġcollector . sum Ċ } Ċ Ċ public Ġsuspend Ġinline Ġfun ĠFlow < Int >. max (): ĠInt Ġ{ ĊĠĠĠ Ġval Ġcollector Ġ= Ġobject Ġ: ĠFlow Collector < Int > Ġ{ ĊĠĠĠĠĠĠĠ Ġpublic Ġvar Ġmax Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġoverride Ġsuspend Ġfun Ġemit ( value : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmax Ġ= Ġmax ( max , Ġvalue ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġcollect ( collector ) ĊĠĠĠ Ġreturn Ġcollector . max Ċ } Ċ Ċ @ Jvm Name (" long Sum ") Ċ public Ġsuspend Ġinline Ġfun ĠFlow < Long >. sum (): ĠLong Ġ{ ĊĠĠĠ Ġval Ġcollector Ġ= Ġobject Ġ: ĠFlow Collector < Long > Ġ{ ĊĠĠĠĠĠĠĠ Ġpublic Ġvar Ġsum Ġ= Ġ 0 L ĊĊĠĠĠĠĠĠĠ Ġoverride Ġsuspend Ġfun Ġemit ( value : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsum Ġ+= Ġvalue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġcollect ( collector ) ĊĠĠĠ Ġreturn Ġcollector . sum Ċ } Ċ Ċ public Ġclass ĠString By Char Flow ( private Ġval Ġsource : ĠString , Ġprivate Ġval ĠstartIndex : ĠInt , Ġprivate Ġval Ġend Index : ĠInt ): ĠFlow < Char > Ġ{ ĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġcollect ( collector : ĠFlow Collector < Char >) Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin ĠstartIndex Ġuntil Ġend Index ) Ġcollector . emit ( source [ i ]) ĊĠĠĠ Ġ} Ċ } Ċ Ċ public Ġfun Ġ< T > Ġconcat ( first : ĠFlow < T >, Ġsecond : ĠFlow < T >): ĠFlow < T > Ġ= Ġflow Ġ{ ĊĠĠĠ Ġfirst . collect Ġ{ Ġvalue Ġ-> ĊĠĠĠĠĠĠĠ Ġreturn @ collect Ġemit ( value ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsecond . collect Ġ{ Ġvalue Ġ-> ĊĠĠĠĠĠĠĠ Ġreturn @ collect Ġemit ( value ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ public Ġfun Ġ< T , ĠR > ĠFlow < T >. flatMap Concat Iterable ( transformer : Ġ( T ) Ġ-> ĠIterable < R >): ĠFlow < R > Ġ= Ġflow Ġ{ ĊĠĠĠ Ġcollect Ġ{ Ġvalue Ġ-> ĊĠĠĠĠĠĠĠ Ġtransformer ( value ). forEach Ġ{ Ġr Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( r ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ public Ġinline Ġfun Ġ< T > Ġflow (@ Builder Inference Ġcross inline Ġblock : Ġsuspend ĠFlow Collector < T >. () Ġ-> ĠUnit ): ĠFlow < T > Ġ{ ĊĠĠĠ Ġreturn Ġobject Ġ: ĠFlow < T > Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġsuspend Ġfun Ġcollect ( collector : ĠFlow Collector < T >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcollector . block () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ