package Ġru . ale shi . let sp lay cities . base . dictionary Ċ Ċ import Ġio . reactivex . Flow able Ċ import Ġio . reactivex . Maybe Ċ import Ġio . reactivex . Single Ċ import Ġio . reactivex . schedul ers . Schedulers Ċ Ċ /** Ċ Ġ* ĠImplementation Ġof Ġ[ Dictionary Service ] Ċ Ġ* Ġ@ param Ġdictionary Ġ[ HashMap ] Ġwith Ġcity Ġname Ġas Ġkey , Ġand Ġits Ġproperties Ġas Ġvalue Ċ Ġ*/ Ċ class ĠDictionary ServiceImpl Ġconstructor ( ĊĠĠĠ Ġprivate Ġval Ġdictionary : ĠHashMap < String , ĠCity Properties > Ċ ) Ġ: ĠDictionary Service Ġ{ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠInternal Ġdifficulty Ġreference ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġ_ difficulty : ĠByte Ġ= Ġ 1 ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠProperty Ġto Ġaccess Ġ[_ difficulty ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġvar Ġdifficulty : ĠByte ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġ_ difficulty ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ difficulty Ġ= Ġvalue . coerce In ( 1 , Ġ 3 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ see ĠDictionary Service . check City ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġcheck City ( city Provider : Ġ() Ġ-> ĠString ): ĠFlow able < City Result > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠFlow able . from Callable Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcity Ġ= Ġcity Provider () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! dictionary . containsKey ( city )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCity Result . C ITY _ NOT _ FOUND ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( dictionary [ city ] !!. diff Ġ< Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCity Result . AL READY _ USED ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCity Result . OK ĊĠĠĠĠĠĠĠ Ġ}. subscribe On ( Schedulers . computation ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. on Back pressure Latest () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġmark Used ( city : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġdictionary [ city ]?. mark Used () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget CountryCode ( city : ĠString ): ĠShort Ġ= Ġdictionary [ city ]?. country Code Ġ?: Ġ 0 ĊĊĠĠĠ Ġoverride Ġfun ĠgetRandom Word ( first Char : ĠChar ): ĠMaybe < String > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠMaybe . just ( first Char ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. observe On ( Schedulers . computation ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdictionary ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Keys Ġ{ Ġkey Ġ-> Ġkey [ 0 ] Ġ== Ġfirst Char Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Values Ġ{ Ġprop Ġ-> Ġprop . diff Ġ> Ġ 0 Ġ&& Ġprop . country Code Ġ!= Ġ 0 . to Short () Ġ&& Ġprop . diff Ġ<= Ġdifficulty Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. keys ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. take If Ġ{ Ġit . isNotEmpty () Ġ} ?. random ()?. run Ġ{ ĠMaybe . just ( this ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠMaybe . empty () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Correction Variants ( city : ĠString ): ĠSingle < List < String >> Ġ= ĊĠĠĠĠĠĠĠ ĠSingle . create < List < String >> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlist Ġ= Ġedits ( city ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcandidates Ġ= ĠArrayList < String >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( s Ġin Ġlist ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMax Ġ 3 Ġwords ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( candidates . size Ġ== Ġ 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( can Use ( s )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcandidates . add ( s ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( candidates . isNotEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Success ( candidates . distinct ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( s Ġin Ġlist ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( w Ġin Ġedits ( s )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( candidates . size Ġ< Ġ 4 Ġ&& Ġcan Use ( w ) Ġ&& Ġ! candidates . contains ( w )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcandidates . add ( w ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Success ( candidates . distinct ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. subscribe On ( Schedulers . computation ()) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġall Ġcities Ġin Ġdatabase . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun ĠgetAll (): ĠMap < String , ĠCity Properties > Ġ= Ġdictionary ĊĊĠĠĠ Ġprivate Ġfun Ġedits ( word : ĠString ): ĠArrayList < String > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= ĠArrayList < String >() ĊĠĠĠĠĠĠĠ Ġval Ġfirst Char Ġ= Ġword [ 0 ] ĊĠĠĠĠĠĠĠ Ġvar Ġs : ĠString ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġword . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġs Ġ= Ġword . substring ( 0 , Ġi ) Ġ+ Ġword . substring ( i Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( s . isNotEmpty () Ġ&& Ġs [ 0 ] Ġ== Ġfirst Char ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add ( s ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġword . length Ġ- Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġs Ġ= Ġ( word . substring ( 0 , Ġi ) Ġ+ Ġword . substring ( i Ġ+ Ġ 1 , Ġi Ġ+ Ġ 2 ) Ġ+ Ġword . substring ( i , Ġi Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ+ Ġword . substring ( i Ġ+ Ġ 2 )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( s . isNotEmpty () Ġ&& Ġs [ 0 ] Ġ== Ġfirst Char ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add ( s ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġword . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( c Ġin Ġ' Ð° ' Ġuntil Ġ' Ñı ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġs Ġ= Ġword . substring ( 0 , Ġi ) Ġ+ Ġc . toString () Ġ+ Ġword . substring ( i Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( s . isNotEmpty () Ġ&& Ġs [ 0 ] Ġ== Ġfirst Char ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add ( s ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. word . length ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( c Ġin Ġ' Ð° ' Ġuntil Ġ' Ñı ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġs Ġ= Ġword . substring ( 0 , Ġi ) Ġ+ Ġc . toString () Ġ+ Ġword . substring ( i ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( s . isNotEmpty () Ġ&& Ġs [ 0 ] Ġ== Ġfirst Char ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add ( s ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠChecks Ġwhether Ġcity Ġ[ s ] Ġis Ġused Ġbefore Ġor Ġnot ĊĠĠĠĠ Ġ* Ġ@ param Ġs Ġcity Ġfor Ġchecking ĊĠĠĠĠ Ġ* Ġ@ return Ġ` true ` Ġis Ġgiven Ġcity Ġis Ġnot Ġused Ġbefore ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġcan Use ( s : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġs . length Ġ> Ġ 1 Ġ&& Ġdictionary [ s ]?. isNot Used () Ġ?: Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġreset () Ġ{ ĊĠĠĠĠĠĠĠ Ġdictionary . values . forEach Ġ{ Ġit . reset Usage Flag () Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġclear () Ġ{ ĊĠĠĠĠĠĠĠ Ġdictionary . clear () ĊĠĠĠ Ġ} Ċ Ċ }