package Ġnl . jh vh . s udoku . grid . solve Ċ Ċ /* ĠCopyright Ġ 2 0 2 0 ĠJan - H end rik Ġvan ĠHe us den ĊĊĠĠ Ġ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 ĊĊĠĠĠĠĠĠ Ġhttp :// 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 . Ċ Ġ*/ Ċ Ċ import Ġnl . jh vh . s udoku . format . Format table . Format table List Ċ import Ġnl . jh vh . s udoku . format . S udoku Formatter Ċ import Ġnl . jh vh . s udoku . grid . default Grid Formatter Ċ import Ġnl . jh vh . s udoku . grid . event . Value Event Ċ import Ġnl . jh vh . s udoku . grid . event . Value EventListener Ċ import Ġnl . jh vh . s udoku . grid . event . Value EventType Ċ import Ġnl . jh vh . s udoku . grid . event . Value EventType . SET _ CELL _ VALUE Ċ import Ġnl . jh vh . s udoku . grid . event . cell value . Cell Remove Candidates Event Ċ import Ġnl . jh vh . s udoku . grid . event . cell value . Set CellValue Event Ċ import Ġnl . jh vh . s udoku . grid . grid With Candidates Box Formatter Ċ import Ġnl . jh vh . s udoku . grid . model . Grid Ċ import Ġnl . jh vh . s udoku . grid . model . Grid Element Ċ import Ġnl . jh vh . s udoku . grid . model . cell . Cell Ċ import Ġnl . jh vh . s udoku . grid . model . cell . CellValue Ċ import Ġnl . jh vh . s udoku . grid . model . cell . CellValue . Fixed Value Ċ import Ġnl . jh vh . s udoku . grid . model . cell . CellValue . Non Fixed Value Ċ import Ġnl . jh vh . s udoku . grid . model . segment . Block Ċ import Ġnl . jh vh . s udoku . grid . model . segment . Col Ċ import Ġnl . jh vh . s udoku . grid . model . segment . Grid Segment Ċ import Ġnl . jh vh . s udoku . grid . model . segment . Linear Segment Ċ import Ġnl . jh vh . s udoku . grid . model . segment . Row Ċ import Ġnl . jh vh . s udoku . grid . solve . Grid Solver . Sub Segment . Horizontal Sub Segment Ċ import Ġnl . jh vh . s udoku . grid . solve . Grid Solver . Sub Segment . Vertical Sub Segment Ċ import Ġnl . jh vh . s udoku . grid . solve . Grid Sol ving Phase . CHAIN ING _ TE CH NI QUE Ċ import Ġnl . jh vh . s udoku . grid . solve . Grid Sol ving Phase . Companion . first Sol ving Phase Ċ import Ġnl . jh vh . s udoku . grid . solve . Grid Sol ving Phase . GRID _ SOL VED Ċ import Ġnl . jh vh . s udoku . grid . solve . Grid Sol ving Phase . MULTI _ SEGMENT _ COMB IN ATIONS Ċ import Ġnl . jh vh . s udoku . grid . solve . Grid Sol ving Phase . PRE PARE D _ FOR _ SOL V ING Ċ import Ġnl . jh vh . s udoku . grid . solve . Grid Sol ving Phase . SOL VE _ EXCL UDING _ COMB IN ATIONS Ċ import Ġnl . jh vh . s udoku . grid . solve . Grid Sol ving Phase . SOL VE _ POLY MOR PH IC _ COMB IN ATIONS Ċ import Ġnl . jh vh . s udoku . grid . solve . Grid Sol ving Phase . SOL VE _ SINGLE _ C AND ID ATE _ VALUES Ċ import Ġnl . jh vh . s udoku . grid . solve . Grid Sol ving Phase . UN ASS IGNED Ċ import Ġnl . jh vh . s udoku . util . all Combin ations Ċ import Ġnl . jh vh . s udoku . util . check And Log Ċ import Ġnl . jh vh . s udoku . util . concat Each Ċ import Ġnl . jh vh . s udoku . util . log Ċ import Ġnl . jh vh . s udoku . util . require And Log Ċ import Ġjava . util .* Ċ import Ġjava . util . Collections . unmodifiable Map Ċ import Ġjava . util . Collections . unmodifiable Set Ċ import Ġjava . util . concurrent . Linked BlockingQueue Ċ import Ġkotlin . collections . ArrayList Ċ import Ġkotlin . collections . HashMap Ċ import Ġkotlin . collections . HashSet Ċ import Ġkotlin . collections . Linked HashSet Ċ import Ġjava . util . concurrent . Concurrent HashMap . new Key Set Ġas ĠConcurrent HashSet Ċ Ċ /* ĠTODO : ĠThis Ġsolver Ġclass Ġis Ġfar Ġtoo Ġbig , Ġneeds Ġto Ġbe Ġsplit Ġ/ Ġref actored . ĊĠĠĠĠĠĠĠĠ ĠSplit ting : ĠSolver Ġmethods Ġcan Ġbe Ġexpressed Ġals Ġlambda 's Ġthat Ġcan Ġbe Ġpassed Ġinto Ġthe Ġ" main " Ġsolver Ġ( this Ġclass ). ĊĠĠĠĠĠĠĠĠ ĠAlso ĠTODO : Ġadd Ġlack ing Ġunit Ġor Ġintegration Ġtests Ġyet . Ċ Ġ*/ Ċ Ċ /** Ċ Ġ* ĠStateful Ġsolver Ġfor Ġthe Ġ[ grid ToS olve ]. ĠThe Ġclass Ġis Ġdeli ber ately Ġdefined Ġas Ġopen , Ġto Ġallow Ġextension . Ċ Ġ* Ġ Ġ* ĠThe Ġ[ grid ToS olve ] Ġmust Ġbe Ġset Ġbefore Ġany Ġfurther Ġuse Ċ Ġ* Ġ Ġ* ĠThe Ġ[ grid ToS olve ] Ġcan Ġbe Ġset Ġonly Ġonce Ċ Ġ*/ Ċ open Ġclass ĠGrid Solver : ĠGrid Sol vable , ĠValue EventListener , ĠValue Event Hand l able Ġ{ ĊĊĠĠĠ Ġoverride Ġvar Ġgrid ToS olve : ĠGrid ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġset ( grid ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire And Log ( grid Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" The Ġ$ grid ToS olve PropertyName Ġcan Ġbe Ġset Ġto Ġa Ġnon - null Ġ${ Grid :: class . simple Name } Ġvalue Ġonly , Ġbut Ġis Ġset Ġto Ġ` null ` !! " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( field Ġ=== Ġgrid ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (). debug Ġ{ Ġ" This Ġ$ grid ToS olve PropertyName Ġwas Ġset Ġalready Ġto Ġthe Ġsame Ġ${ Grid :: class . simple Name } :" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ grid ToS olve PropertyName =${ grid !!. toString Compact () }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck And Log Ġ( field Ġ== Ġnull ) Ġ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" A Ġ$ grid ToS olve PropertyName Ġwas Ġalready Ġset Ġfor Ġthis Ġ${ this . java Class . simple Name }! ĠIt Ġcan Ġbe Ġset Ġonly Ġonce , Ġthe Ġnew Ġvalue Ġis Ġrejected !" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ĠExisting Ġvalue Ġof Ġ$ grid ToS olve PropertyName Ġ= Ġ${ field !!. toString Compact ()}; Ġnew Ġvalue Ġ= Ġ${ grid !!. toString Compact () }" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ= Ġgrid !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprepare For Sol ving () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġfor Ġinternal Ġuse , Ġnot Ġnullable , Ġso Ġwe Ġneed Ġnot Ġuse Ġ` grid ToS olve !! ` Ġeverywhere ĊĠĠĠ Ġprivate Ġval Ġgrid : ĠGrid ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġ Ġgrid ToS olve Ġ?: Ġthrow ĠGrid Not Set Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ grid ToS olve PropertyName Ġmust Ġbe Ġset Ġbefore Ġfurther Ġusage Ġof Ġ${ Grid Solver :: class . simple Name }") ĊĊĠĠĠ Ġ@ Volatile ĊĠĠĠ Ġvar Ġsolving Phase : ĠGrid Sol ving Phase Ġ= ĠUN ASS IGNED ĊĠĠĠĠĠĠĠ Ġprotected Ġset ĊĊĠĠĠ Ġoverride Ġval Ġis Sol ving : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġsolving Phase . is Sol ving ĊĊĠĠĠ Ġprivate Ġvar Ġis Sol vable Ġ= Ġtrue ĊĊĠĠĠ Ġoverride Ġval Ġun Sol vable : ĠBoolean ? ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġif Ġ(! is Sol vable ) Ġ! is Sol vable Ġelse Ġnull ĊĊĠĠĠ Ġprotected Ġval Ġevent Queue : ĠLinked BlockingQueue < Value Event > Ġ= ĠLinked BlockingQueue < Value Event >() ĊĊĠĠĠ Ġprotected Ġval Ġsegments : ĠSet < Grid Segment > Ġby Ġlazy Ġ{ Ġwith ( grid ) Ġ{ Ġ( this . row List Ġ+ Ġthis . col List Ġ+ Ġthis . blockList ). toSet () Ġ} Ġ} ĊĊĠĠĠ Ġprotected Ġval Ġhorizontal Sub Segments : ĠSet < Horizontal Sub Segment > Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsub Segment Set : ĠMutable Set < Horizontal Sub Segment > Ġ= ĠHashSet ( grid . grid Size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( 0 Ġuntil Ġgrid . grid Size ). forEach Ġ{ ĠrowIndex Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( 0 Ġuntil Ġgrid . grid Size Ġstep Ġgrid . block Size ). forEach Ġ{ left Col Index Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsub Segment Set . add ( Horizontal Sub Segment ( grid , ĠrowIndex , Ġleft Col Index )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġun modifiable Set ( sub Segment Set ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġval Ġvertical Sub Segments : ĠSet < Vertical Sub Segment > Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsub Segment Set : ĠMutable Set < Vertical Sub Segment > Ġ= ĠHashSet ( grid . grid Size ) ĊĠĠĠĠĠĠĠ Ġ( 0 Ġuntil Ġgrid . grid Size ). forEach Ġ{ Ġcol Index Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( 0 Ġuntil Ġgrid . grid Size Ġstep Ġgrid . block Size ). forEach Ġ{ top RowIndex Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsub Segment Set . add ( Vertical Sub Segment ( grid , Ġcol Index , Ġtop RowIndex )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġun modifiable Set ( sub Segment Set ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġval Ġhorizontal Sub Segments By Block : ĠMap < Block , ĠSet < Horizontal Sub Segment >> Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsub Segments By Block Map Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhorizontal Sub Segments ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. groupBy { Ġsub Segment Ġ-> Ġsub Segment . enc lo sing Block Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Values Ġ{ Ġentry Ġ-> Ġentry . value . toSet () Ġ} ĊĠĠĠĠĠĠĠ Ġun modifiable Map ( sub Segments By Block Map ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġval Ġvertical Sub Segments By Block : ĠMap < Block , ĠSet < Vertical Sub Segment >> Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsub Segments By Block Map Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvertical Sub Segments ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. groupBy { Ġsub Segment Ġ-> Ġsub Segment . enc lo sing Block Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Values Ġ{ Ġentry Ġ-> Ġentry . value . toSet () Ġ} ĊĠĠĠĠĠĠĠ Ġun modifiable Map ( sub Segments By Block Map ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġval Ġsegments By CellValue : ĠMap < CellValue , ĠSet < Grid Segment >> Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġse gs By CellValue : ĠMutable Map < CellValue , ĠMutable Set < Grid Segment >> Ġ= ĠHashMap ( grid . cell List . size ) ĊĠĠĠĠĠĠĠ Ġsegments . forEach Ġ{ Ġsegment Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsegment . cells . forEach Ġ{ Ġcell Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġinitial Capacity Ġ= Ġ 3 : Ġone Ġfor Ġeach Ġrow , Ġcolumn Ġand Ġblock Ġa Ġcell Ġis Ġpart Ġof ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġse gs By CellValue . put If Absent ( cell . cell Value , ĠHashSet ( 3 )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġse gs By CellValue [ cell . cell Value ] !!. add ( segment ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġun modifiable Map ( se gs By CellValue ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġval Ġun S olved Numbers By Segment : ĠMap < Grid Segment , ĠMutable Set < Int >> Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcell Val sBy Segment : ĠMutable Map < Grid Segment , ĠMutable Set < Int >> Ġ= ĠHashMap ( segments . size ) ĊĠĠĠĠĠĠĠ Ġsegments . forEach Ġ{ Ġsegment Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun solved Numbers Ġ= ĠConcurrent HashSet < Int >( grid . grid Size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġun solved Numbers . addAll (( 1 .. grid . grid Size ) Ġ- ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsegment . cells ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġcell Ġ-> Ġcell . isSet Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġcell Ġ-> Ġcell . cell Value . value !! Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcell Val sBy Segment [ segment ] Ġ= Ġun solved Numbers ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġun modifiable Map ( cell Val sBy Segment ) ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprotected Ġval Ġcell Values By Segment : ĠMap < Grid Segment , ĠSet < CellValue >> Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcell Val sBy Segment : ĠMutable Map < Grid Segment , ĠSet < CellValue >> Ġ= ĠHashMap ( segments . size ) ĊĠĠĠĠĠĠĠ Ġsegments . forEach Ġ{ Ġsegment Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcell Values Ġ= ĠHashSet < CellValue >( grid . grid Size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcell Values . addAll ( segment . cells ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġcell Ġ-> Ġcell . cell Value Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcell Val sBy Segment [ segment ] Ġ= Ġcell Values ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġun modifiable Map ( cell Val sBy Segment ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġval Ġnon Fixed By Segment : ĠMap < Grid Segment , ĠSet < Non Fixed Value >> Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcell Val sBy Segment : ĠMutable Map < Grid Segment , ĠSet < Non Fixed Value >> Ġ= ĠHashMap ( segments . size ) ĊĠĠĠĠĠĠĠ Ġsegments . forEach Ġ{ Ġsegment Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnon Fixed Ġ= ĠHashSet < Non Fixed Value >( grid . grid Size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnon Fixed . addAll ( segment . cells ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġcell Ġ-> Ġcell . cell Value Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Is Instance < Non Fixed Value >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcell Val sBy Segment [ segment ] Ġ= Ġnon Fixed ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġun modifiable Map ( cell Val sBy Segment ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUn solved Ġvalues , Ġinitialized Ġon Ġfirst Ġaccess . ĊĠĠĠĠ Ġ* ĠAfter Ġ 1 st Ġinitialization , Ġvalues Ġare Ġto Ġbe Ġremoved Ġby Ġthe Ġsolving Ġalgorithm Ġwhen Ġsolved ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġun S olved Non Fixed Values : ĠMutable Set < Non Fixed Value > Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmap Ġ= Ġgrid . cell List ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġcell Ġ-> Ġcell . cell Value Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġcell Value Ġ-> Ġ! cell Value . is Fixed Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit Ġas ĠNon Fixed Value Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġconcurrent HashSet Ġ= ĠConcurrent HashSet < Non Fixed Value >( map . size ) ĊĠĠĠĠĠĠĠ Ġconcurrent HashSet . addAll ( map ) ĊĠĠĠĠĠĠĠ Ġconcurrent HashSet ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Un S olved Cell Values (): ĠSet < Non Fixed Value > Ġ= Ġun modifiable Set ( un S olved Non Fixed Values ) ĊĊĠĠĠ Ġprotected Ġfun Ġsubscribe To Events ( exclude Fixed : ĠBoolean Ġ= Ġtrue , Ġvar arg Ġvalue Event Types : ĠValue EventType Ġ= ĠValue EventType . values ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġvalue Event Types . forEach Ġ{ ĠeventType Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgrid . cell List ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġcell Ġ-> Ġcell . cell Value Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġcell Value Ġ-> Ġ! exclude Fixed Ġ|| Ġ! cell Value . is Fixed Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ Ġcell Value Ġ-> Ġcell Value . subscribe ( this , ĠeventType ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġhandle Set CellValue Event ( event : ĠSet CellValue Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog (). trace Ġ{ Ġ"$ event Ġhandled Ġby Ġ${ Grid Solver :: class . simple Name }" Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġevent Source Ġ= Ġevent . event Source ĊĠĠĠĠĠĠĠ Ġun S olved Non Fixed Values . remove ( event Source ) ĊĠĠĠĠĠĠĠ Ġsegments By CellValue [ event Source ] !!. forEach Ġ{ Ġsegment Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġun S olved Numbers By Segment [ segment ] !!. ĊĠĠĠĠĠĠĠĠĠĠĠ Ġremove ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevent Source . value !! ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠOnce Ġset , Ġthe Ġcell Value Ġshould Ġnot Ġproduce Ġany Ġevents Ġanymore , Ġso Ġwe Ġare Ġnot Ġinterested Ġanymore : Ġunsubscribe ĊĠĠĠĠĠĠĠ Ġevent Source . unsubscribe ( this , Ġevent . type ) ĊĠĠĠĠĠĠĠ Ġval Ġevent Source Segments : ĠSet < Grid Segment > Ġ= Ġsegments By CellValue [ event Source ] !! ĊĠĠĠĠĠĠĠ Ġif Ġ( event Source Ġis ĠNon Fixed Value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġevent Source . clear Value Candidates On Value Set () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġevent Source Segments . forEach Ġ{ Ġgrid Segment Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgrid Segment . cells . forEach Ġ{ Ġcell Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cell . cell Value Ġ!== Ġevent Source ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cell . cell Value Ġis ĠNon Fixed Value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFor Ġcells Ġthat Ġare Ġin Ġthe Ġsame ĠBlock ĠAND Ġin Ġeither Ġthe Ġsame ĠRow Ġor Ġsame ĠCol ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġas Ġthe Ġevent Source , Ġmethod Ġremove Value Candidate Ġwill Ġbe Ġcalled Ġmore Ġthan Ġonce . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMaking Ġcells Ġunique Ġbefore hand Ġwould Ġprobably Ġbe Ġmore Ġcost ly Ġ( in Ġterms Ġof Ġmemory ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġand / or Ġperformance ) Ġthan Ġjust Ġcalling Ġthis Ġmethod Ġmore Ġthan Ġonce . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMethod Ġremove Value Candidate Ġshould Ġbe Ġlen ient Ġfor Ġthis , Ġand Ġignore Ġredundant Ġcalls . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcell . cell Value . remove Value Candidate ( event . newValue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġhandle Remove Candidates Event ( event : ĠCell Remove Candidates Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog (). trace Ġ{ Ġ"$ event Ġhandled Ġby Ġ${ Grid Solver :: class . simple Name }" Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( event . event Source . getValue Candidates (). size Ġ<= Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġeither Ġthe Ġcell Ġwill Ġbe Ġsolved Ġ( value Ġwill Ġbe Ġset ), Ġor Ġthere Ġis Ġno Ġsolution . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġin Ġboth Ġcases Ġwe Ġwant Ġto Ġunsubscribe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġevent . event Source . unsubscribe ( this , Ġevent . type ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġfun Ġprepare For Sol ving () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( sol ving Phase Ġ>= ĠPRE PARE D _ FOR _ SOL V ING ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog (). warn Ġ{ Ġ" Grid Ġwas Ġalready Ġprepared Ġfor Ġsolving Ġ- Ġcall Ġto Ġprepare Ġit Ġagain Ġis Ġignored " Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsubscribe To Events ( exclude Fixed Ġ= Ġfalse , ĠSET _ CELL _ VALUE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgrid . cell List ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġcell Ġ-> Ġcell . cell Value Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġcell Value Ġ-> Ġcell Value . is Fixed Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit Ġas ĠFixed Value Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ Ġfixed Value Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠPublish ing Ġhere Ġcauses Ġinitial Ġelim ination Ġof Ġimpossible Ġcandidate Ġvalues . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠE . g . Ġa Ġfixed Ġvalue Ġof Ġ 4 Ġwill Ġremove Ġall Ġ 4 s Ġin Ġits Ġrow Ġ/ Ġcolumn Ġ/ Ġblock . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThis Ġis Ġdone Ġbefore Ġthis ĠGrid Solver Ġhas Ġsubscribed Ġto Ġ[ Cell Remove Candidate Event ] s , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġso Ġit Ġshould Ġhave Ġno Ġside Ġeffects Ġlike Ġpre limin arily Ġstarting Ġto Ġsolve Ġthe ĠS udoku ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfixed Value . publish ( Set CellValue Event ( event Source Ġ= Ġfixed Value , ĠnewValue Ġ= Ġfixed Value . value !! )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsolving Phase Ġ= ĠPRE PARE D _ FOR _ SOL V ING ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġassert Correct Grid () Ġ{ ĊĠĠĠĠĠĠĠ Ġsegments . forEach Ġ{ Ġsegment Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue List Ġ= Ġsegment . cells . filter Ġ{ Ġcell Ġ-> Ġcell . isSet Ġ}. map Ġ{ Ġcell Ġ-> Ġcell . cell Value . value !! Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Set Ġ= Ġvalue List . toSet () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( value List . size Ġ> Ġvalue Set . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġformatted Segment Ġ= Ġsegment . format ( default Grid Formatter ). toString () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠAssertionError (" Duplicate Ġvalue Ġin Ġ$ grid \ n \ n Ġin Ġ$ segment :\ n $ formatted Segment \ n ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIf Ġa Ġcell Ġhas Ġ`[ 5 ]` Ġas Ġit 's Ġonly Ġremaining Ġcandidate Ġvalue , Ġno Ġother Ġcells Ġin Ġthe Ġ[ Grid Segment ] s Ġthe Ġcell Ġis Ġpart Ġof ĊĠĠĠĠ Ġ* Ġcan Ġhave Ġthat Ġvalue , Ġso Ġ`[ 5 ]` Ġcan Ġbe Ġelim inated Ġfrom Ġthe Ġother Ġcells . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprotected Ġfun Ġsolve Sing ular Candidates ( non Fixed Value : ĠNon Fixed Value ) Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġsynchronized ( grid ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Candidates Ġ= Ġnon Fixed Value . getValue Candidates () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( value Candidates . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! non Fixed Value . isSet ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠGrid Not Sol vable Exception (" Grid Ġis Ġnot Ġsol vable : Ġvalue Ġnot Ġset , Ġand Ġno Ġcandidate Ġvalues Ġanymore Ġin Ġ$ non Fixed Value ! Ġcell Value =$ non Fixed Value ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġallow Ġnull Ġbecause Ġthe Ġvalue Candidates Ġmight Ġbe Ġcleared Ġby Ġa Ġconcurrent Ġthread Ġ/ Ġcoroutine ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġint Value Ġ= Ġvalue Candidates . first OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( intValue Ġ!= Ġnull Ġ&& Ġ! non Fixed Value . isSet ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnon Fixed Value . setValue ( intValue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġhandle Events () Ċ assert Correct Grid () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIf Ġa Ġcell Ġhas Ġ`[ 5 ]` Ġas Ġit 's Ġonly Ġremaining Ġcandidate Ġvalue , Ġno Ġother Ġcells Ġin Ġthe Ġ[ Grid Segment ] s Ġthe Ġcell Ġis Ġpart Ġof ĊĠĠĠĠ Ġ* Ġcan Ġhave Ġthat Ġvalue , Ġso Ġ`[ 5 ]` Ġcan Ġbe Ġelim inated Ġfrom Ġthe Ġother Ġcells . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġopen Ġfun Ġsolve Sing ular Candidates () Ġ{ ĊĠĠĠĠĠĠĠ Ġun S olved Non Fixed Values ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . getValue Candidates (). size Ġ<= Ġ 1 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ Ġsolve Sing ular Candidates ( it ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIf Ġcells Ġin Ġa Ġ[ Grid Segment ] Ġhave Ġdifferent Ġcombinations Ġof Ġvalues , ĊĠĠĠĠ Ġ* Ġe . g . Ġ`[ 1 , Ġ 3 , Ġ 6 ] `, Ġ`[ 2 , Ġ 3 , Ġ 7 ] `, Ġ`[ 1 , Ġ 3 , Ġ 7 , Ġ 9 ] `, Ġ`[ 2 , Ġ 4 , Ġ 5 , Ġ 8 , Ġ 9 ]` ĊĠĠĠĠ Ġ* Ġand Ġonly Ġ 1 Ġof Ġthose Ġhas Ġ`[ 6 ]` Ġas Ġa Ġcandidate Ġvalue , Ġthat Ġcell 's Ġvalue Ġcan Ġbe Ġset Ġto Ġ`[ 6 ] `. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġopen Ġfun Ġsolve Single Value In Segments () Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġsynchronized ( grid ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġsegment Cell Values With Candidate : ĠList < CellValue > ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsegments . forEach Ġ{ Ġsegment Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġun S olved Numbers By Segment [ segment ] !!. forEach Ġ{ Ġvalue Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsegment Cell Values Ġ= Ġcell Values By Segment [ segment ] !! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsegment Cell Values With Candidate Ġ= Ġsegment Cell Values ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit Ġis ĠNon Fixed Value Ġ&& Ġit . getValue Candidates (). contains ( value ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( segment Cell Values With Candidate . size Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsegment Cell Values With Candidate [ 0 ]. setValue ( value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġhandle Events () Ċ assert Correct Grid () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġif Ġin Ġa Ġ[ Block ] Ġa Ġcombination Ġof Ġvalues , Ġsay , Ġ`[ 2 , Ġ 6 ] `, Ġonly Ġexists Ġin Ġa Ġsingle Ġrow Ġpart Ġ([ Sub Segment ]) Ġof Ġthe Ġ[ Block ], ĊĠĠĠĠ Ġ* Ġ( so Ġthese Ġall Ġhave , Ġsay , Ġ[ Block . rowIndex ] Ġ= Ġ 4 , Ġthus Ġthe Ġcells Ġwith Ġ[ Block . rowIndex ] Ġ 4 Ġhave Ġcandidates Ġ`[ 2 , Ġ 4 , Ġ 7 ] `, Ġ`[ 2 , Ġ 6 , Ġ 7 ]` ĊĠĠĠĠ Ġ* Ġand Ġ`[ 3 , Ġ 6 ] `, Ġand Ġno Ġother Ġcells Ġin Ġthat Ġblock Ġhave Ġcandidate Ġ`[ 2 ]` Ġor Ġ`[ 6 ] `), Ġthan Ġthese Ġvalues Ġ 2 Ġand Ġ 6 Ġcan Ġbe Ġremoved Ġfrom ĊĠĠĠĠ Ġ* Ġall Ġother Ġcells Ġin Ġthe Ġ[ Row ] Ġwith Ġ[ Row . rowIndex ] Ġ= Ġ 4 . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprotected Ġfun Ġsolve Ex cluding Subset Candidates ( sub Segment : ĠSub Segment < Linear Segment >, Ġother Block Candidates : ĠSet < Int >) Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġsynchronized ( grid ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsub Segment Cell Values By Candidates Ġ= Ġsub Segment . cells ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġcell Ġ-> Ġ! cell . is Fixed Ġ&& Ġ! cell . isSet Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġcell Ġ-> Ġcell . cell Value Ġas ĠNon Fixed Value Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. groupBy Ġ{ Ġnon Fixed Value Ġ-> Ġnon Fixed Value . getValue Candidates () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsub Segment Candidate Values Ġ= Ġsub Segment Cell Values By Candidates . keys . flatten (). toSet () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremaining Candidate Values Ġ= Ġ( sub Segment Candidate Values Ġ- Ġother Block Candidates ). to IntArray () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( remaining Candidate Values . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġnow Ġhave Ġcandidate Ġvalues Ġthat Ġexist Ġin Ġthe Ġcurrent Ġsub Segment , Ġbut Ġnot Ġanywhere Ġelse Ġin Ġthe ĠBlock ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġso Ġthese Ġcan Ġbe Ġremoved : ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠ 1 . Ġfrom Ġthe Ġcandidate Ġvalues Ġin Ġthe Ġsame Ġlinear Ġsegment Ġ( Row Ġor ĠCol ) Ġthat Ġare Ġnot Ġpart Ġof Ġthis ĠBlock ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġother Cells Of Linear Segment Ġ= Ġsub Segment . enc lo sing Linear Segment . cells . filter Ġ{ Ġ! it . is Fixed Ġ} Ġ- Ġsub Segment . cells ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġother Cells Of Linear Segment . map Ġ{ Ġcell Ġ-> Ġcell . cell Value Ġas ĠNon Fixed Value Ġ}. forEach Ġ{ Ġnon Fixed Value Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnon Fixed Value . remove Value Candidate (* remaining Candidate Values ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠ 2 . Ġfrom Ġthe Ġcandidate Ġvalues Ġin Ġthe Ġsub Ġsegments Ġof Ġthe ĠBlock Ġthat Ġare Ġnot Ġpart Ġof Ġthat Ġlinear Ġsegment ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġother Cells Of Block Ġ= Ġsub Segment . enc lo sing Block . cells . filter Ġ{ Ġ! it . is Fixed Ġ} Ġ- Ġsub Segment . cells ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġother Cells Of Block . map Ġ{ Ġcell Ġ-> Ġcell . cell Value Ġas ĠNon Fixed Value Ġ}. forEach Ġ{ Ġnon Fixed Value Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnon Fixed Value . remove Value Candidate (* remaining Candidate Values ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ assert Correct Grid () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġif Ġin Ġa Ġ[ Block ] Ġa Ġcombination Ġof Ġvalues , Ġsay , Ġ`[ 2 , Ġ 6 ] `, Ġonly Ġexists Ġin Ġa Ġsingle Ġrow Ġpart Ġ([ Sub Segment ]) Ġof Ġthe Ġ[ Block ], ĊĠĠĠĠ Ġ* Ġ( so Ġthese Ġall Ġhave , Ġsay , Ġ[ Row . rowIndex ] Ġ= Ġ 4 , Ġand Ġthe Ġ[ Block ] Ġcells Ġwith Ġ[ Row . rowIndex ] Ġ 4 Ġhave Ġcandidates Ġ`[ 2 , Ġ 4 , Ġ 7 ] `, Ġ`[ 2 , Ġ 6 , Ġ 7 ]` ĊĠĠĠĠ Ġ* Ġand Ġ`[ 3 , Ġ 6 ] `, Ġand Ġno Ġother Ġcells Ġin Ġthat Ġblock Ġhave Ġcandidate Ġ`[ 2 ]` Ġor Ġ`[ 6 ] `), Ġthan Ġthese Ġvalues Ġ 2 Ġand Ġ 6 Ġcan Ġbe Ġremoved Ġfrom ĊĠĠĠĠ Ġ* Ġall Ġother Ġ[ Sub Segment ] s Ġof Ġthe Ġ[ Row ] Ġwith Ġ[ Row . rowIndex ] Ġ= Ġ 4 . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġsolve Ex cluding Subset Candidates ( linear Segments By Block : ĠMap < Block , ĠSet < Sub Segment < Linear Segment >> >, Ġcurrent Block : ĠBlock ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlinear Segments By Block [ current Block ] !!. forEach Ġ{ Ġsub Segment Of Block Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġother Sub Segments Of Block Ġ= Ġlinear Segments By Block [ current Block ] !!. minus ( sub Segment Of Block ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġother Block Candidates Ġ= Ġother Sub Segments Of Block ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. as Sequence () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġsub Segment Ġ-> Ġsub Segment . cells Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatten () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġcell Ġ-> Ġ! cell . is Fixed Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġcell Ġ-> Ġ( cell . cell Value Ġas ĠNon Fixed Value ). getValue Candidates () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatten () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. toSet () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. union ( other Sub Segments Of Block ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġhorizontal Sub Segment Ġ-> Ġhorizontal Sub Segment . cells Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatten () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġcell Ġ-> Ġcell . isSet Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġcell Ġ-> Ġcell . cell Value . value !! Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsolve Ex cluding Subset Candidates ( sub Segment Of Block , Ġother Block Candidates ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġif Ġin Ġa Ġ[ Block ] Ġa Ġcombination Ġof Ġvalues , Ġsay , Ġ`[ 2 , Ġ 6 ] `, Ġonly Ġexists Ġin Ġa Ġsingle Ġrow Ġpart Ġ([ Sub Segment ]) Ġof Ġthe Ġ[ Block ], ĊĠĠĠĠ Ġ* Ġ( so Ġthese Ġall Ġhave , Ġsay , Ġ[ Row . rowIndex ] Ġ= Ġ 4 , Ġand Ġthe Ġ[ Block ] Ġcells Ġwith Ġ[ Row . rowIndex ] Ġ 4 Ġhave Ġcandidates Ġ`[ 2 , Ġ 4 , Ġ 7 ] `, Ġ`[ 2 , Ġ 6 , Ġ 7 ]` ĊĠĠĠĠ Ġ* Ġand Ġ`[ 3 , Ġ 6 ] `, Ġand Ġno Ġother Ġcells Ġin Ġthat Ġblock Ġhave Ġcandidate Ġ`[ 2 ]` Ġor Ġ`[ 6 ] `), Ġthan Ġthese Ġvalues Ġ 2 Ġand Ġ 6 Ġcan Ġbe Ġremoved Ġfrom ĊĠĠĠĠ Ġ* Ġall Ġother Ġ[ Sub Segment ] s Ġof Ġthe Ġ[ Row ] Ġwith Ġ[ Row . rowIndex ] Ġ= Ġ 4 . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġopen Ġfun Ġsolve Ex cluding Subset Candidates () Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġsynchronized ( grid ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġgrid . blockList . forEach Ġ{ Ġblock Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsolve Ex cluding Subset Candidates ( horizontal Sub Segments By Block , Ġblock ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsolve Ex cluding Subset Candidates ( vertical Sub Segments By Block , Ġblock ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġhandle Events () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ Ġ* Ġif Ġ 2 Ġcells Ġin Ġa Ġ[ Grid Segment ] Ġboth Ġhave Ġ`[ 2 , Ġ 4 ]` Ġas Ġcandidates , Ġno Ġother Ġcells Ġin Ġthat Ġsegment Ġcan Ġhave Ġthese ĊĠĠĠĠ Ġ* ĠĠĠ Ġcandidate Ġvalues , Ġso Ġthese Ġcan Ġbe Ġelim inated Ġfrom Ġthe Ġother Ġ[ CellValue ] s Ġin Ġthe Ġ[ Grid Segment ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġopen Ġfun Ġsolve Ident ical Candidate Sets () Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġsynchronized ( grid ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnon Fixed By Segment . forEach Ġ{ Ġsegment , Ġsegment Cell Values Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnon Fixed By Candidates : ĠMap < Set < Int >, ĠList < Non Fixed Value >> Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsegment Cell Values ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. groupBy Ġ{ Ġnon Fixed Value Ġ-> Ġnon Fixed Value . getValue Candidates () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠOnly Ġthose Ġwhere Ġmore Ġthan Ġ 1 Ġcell Value Ġwith Ġidentical Ġcandidates ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġentry Ġ-> Ġentry . value . size Ġ> Ġ 1 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnon Fixed By Candidates . forEach Ġ{ Ġ( candidates , Ġcell Values With Same Candidates ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġif Ġ 2 Ġidentical Ġcandidates Ġ( say , Ġ[ 3 , Ġ 8 ]) Ġoccur Ġin Ġ 2 Ġcells , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġor Ġ 3 Ġidentical Ġcandidates Ġ( say , Ġ[ 2 , Ġ 5 , Ġ 7 ]) Ġoccur Ġin Ġ 3 Ġcells , Ġetc ., ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthese Ġvalues Ġcan Ġnot Ġappear Ġin Ġthe Ġother Ġcells Ġin Ġthe Ġsame Ġsegment , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġso Ġthese Ġcan Ġbe Ġelim inated Ġfrom Ġthe Ġcandidates Ġof Ġthe Ġother Ġcells Ġin Ġthe Ġsegment ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( candidates . size Ġ== Ġcell Values With Same Candidates . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Cells Ġ= Ġsegment Cell Values Ġ- Ġcell Values With Same Candidates ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Cells . forEach Ġ{ Ġnon Fixed Value Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnon Fixed Value . remove Value Candidate (* candidates . to IntArray ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġhandle Events () Ċ // assert Correct Grid () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ Ġ* Ġif Ġ 3 Ġcells Ġin Ġa Ġ[ Grid Segment ] Ġhave Ġcandidates , Ġsay , Ġ`[ 2 , Ġ 8 ] `, Ġ`[ 3 , Ġ 8 ] `, Ġ`[ 2 , Ġ 8 ] `, Ġthen Ġthe Ġvalues Ġ`[ 2 , Ġ 3 , Ġ 8 ]` Ġcan Ġbe Ġremoved ĊĠĠĠĠ Ġ* ĠĠĠ Ġfrom Ġthe Ġcandidates Ġof Ġall Ġother Ġcells Ġin Ġthe Ġsame Ġ[ Grid Segment ]. ĊĠĠĠĠ Ġ* Ġ Ġ* Ġif Ġ 4 Ġcells Ġhave Ġcandidates Ġ`[ 1 , Ġ 2 ] `, Ġ`[ 1 , Ġ 2 , Ġ 3 ] `, Ġ`[ 2 , Ġ 3 ] `, Ġ`[ 1 , Ġ 4 ] `, Ġthen Ġthe Ġvalues Ġ`[ 1 , Ġ 2 , Ġ 3 , Ġ 4 ]` Ġcan Ġbe Ġremoved ĊĠĠĠĠ Ġ* ĠĠĠ Ġfrom Ġthe Ġcandidates Ġof Ġall Ġother Ġcells Ġin Ġthe Ġsame Ġ[ Grid Segment ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġsolve Pol ymorphic Ex clusions () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġgrid Size Ġdivided Ġby Ġ 2 : ĠIn Ġa Ġgrid Ġof Ġn ine Ġyou Ġmay Ġhave Ġexcluding Ġcombinations Ġof Ġ 1 .. 8 . ĊĠĠĠĠĠĠĠ Ġ// ĠBut Ġif Ġyou Ġhave Ġa Ġcombination Ġof , Ġsay Ġ[ 1 , Ġ 4 , Ġ 5 , Ġ 6 , Ġ 7 , Ġ 9 ], Ġthen Ġthere Ġmust Ġalso Ġbe Ġa Ġsmaller Ġcombination , ĊĠĠĠĠĠĠĠ Ġ// Ġin Ġthis Ġcase Ġ[ 1 , Ġ 3 , Ġ 8 ]. ĠSo Ġit Ġmakes Ġno Ġsense Ġto Ġlook Ġfor Ġcombinations Ġof Ġgrid Size Ġ/ Ġ 2 Ġor Ġlarger , Ġfinding ĊĠĠĠĠĠĠĠ Ġ// Ġlarger Ġcombinations Ġis Ġmuch Ġmore Ġcost ly Ġin Ġterms Ġof Ġcomputing Ġpower Ġ& Ġmemory ĊĠĠĠĠĠĠĠ Ġvar Ġgo Next Combination Size Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ( 1 .. ( grid . grid Size / 2 )). forEach Ġcom bi Length Loop @ Ġ{ Ġcombination Length Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! go Next Combination Size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġwe Ġhave Ġfound Ġcombinations Ġof , Ġsay , Ġ 3 , Ġwe Ġdo Ġnot Ġproceed Ġwith Ġcombinations Ġof Ġ 4 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġbetter Ġhandle Ġevents Ġfirst Ġ( with Ġless Ġcomplicated Ġsolution Ġmethods ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsegments . forEach Ġsegment Loop @ Ġ{ Ġsegment Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġfind Ġall Ġcandidate Ġvalues Ġof Ġun solved Ġcells Ġof Ġthe Ġsegment Ġthat Ġhave Ġat Ġmost Ġ` combin ation Length ` Ġcandidates ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Candidates : ĠSorted Set < Int > Ġ= Ġcell Values By Segment [ segment ] !! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. as Sequence () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġcell Value Ġ-> Ġ! cell Value . is Fixed Ġ&& Ġ! cell Value . isSet Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġcell Value Ġ-> Ġ( cell Value Ġas ĠNon Fixed Value ). getValue Candidates ()} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġvalue Candidates Ġ-> Ġvalue Candidates . size Ġ<= Ġcombination Length Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatten () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. to Sorted Set () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( target Candidates . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ segment Loop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġfind Ġthe Ġcells Ġin Ġthe Ġsegment Ġwhose Ġcandidates Ġare Ġequal Ġto Ġor Ġa Ġsubset Ġof Ġthe Ġtarget Candidates ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Un solved : ĠList < Non Fixed Value > Ġ= Ġcell Values By Segment [ segment ] !! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġcell Value Ġ-> Ġ! cell Value . is Fixed Ġ&& ! cell Value . isSet Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġcell Value Ġ-> Ġ( cell Value Ġas ĠNon Fixed Value )} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġnon Fixed Value Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnon Fixed Value . getValue Candidates (). size Ġ<= Ġcombination Length ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġtarget Candidates . contains All ( non Fixed Value . getValue Candidates ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( target Un solved . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ segment Loop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcreate Ġall Ġpossible Ġcombinations Ġof Ġn Ġtarget Un solved Ġcell Values , Ġwhere Ġn Ġ= Ġcombination Length ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun solved CellValue Combin ations Ġ= Ġall Combin ations ( target Un solved , Ġcombination Length ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġun solved CellValue Combin ations . forEach Ġ{ Ġnon Fixed Value Combination Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġfor Ġeach Ġcombination Ġfound , Ġremove Ġvalue Ġcandidates Ġin Ġthe Ġcombination Ġfrom Ġother Ġsegment Ġcells Ġin Ġthe Ġsegment ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcombination Candidates : ĠSet < Int > Ġ= Ġnon Fixed Value Combination . map Ġ{ Ġit . getValue Candidates () Ġ}. flatten (). toSet () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( combin ation Candidates . size Ġ== Ġcombination Length ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcell Values ToRemove Candidates ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ= Ġ( segment . cells . filter Ġ{ Ġcell Ġ-> Ġ! cell . is Fixed Ġ&& Ġ! cell . isSet Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġcell Ġ-> Ġcell . cell Value Ġas ĠNon Fixed Value Ġ}) Ġ- Ġnon Fixed Value Combination ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cell Values ToRemove Candidates . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcandidates IntArray Ġ= Ġcombination Candidates . to IntArray () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcell Values ToRemove Candidates . forEach Ġ{ Ġnon Fixed Value Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( non Fixed Value . remove Value Candidate (* candidates IntArray )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgo Next Combination Size Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġsynchronized ( grid ) Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠ Ġhandle Events () Ċ // assert Correct Grid () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ* Ġif Ġ 3 Ġcells Ġin Ġa Ġ[ Grid Segment ] Ġhave Ġcandidates , Ġsay , Ġ`[ 4 , Ġ 7 ] `, Ġ`[ 1 , Ġ 4 , Ġ 7 , Ġ 8 ] `, Ġ`[ 2 , Ġ 4 , Ġ 7 , Ġ 8 , Ġ 9 ] `, ĊĠĠĠĠ Ġ* ĠĠ Ġand Ġnone Ġof Ġthe Ġvalues Ġ`[ 4 , Ġ 7 , Ġ 8 ]` Ġis Ġa Ġcandidate Ġvalue Ġof Ġthe Ġother Ġcells Ġin Ġthe Ġsame Ġ[ Grid Segment ], ĊĠĠĠĠ Ġ* ĠĠ Ġthe Ġother Ġvalues Ġcan Ġbe Ġremoved Ġfrom Ġthese Ġcells . ĊĠĠĠĠ Ġ* ĠĠ ĠSo Ġin Ġthese Ġ 3 Ġcells , Ġthe Ġcandidate Ġvalues Ġare Ġreduced Ġlike Ġthis : Ġ`[ 4 , Ġ 7 ]` Ġ-> Ġ`[ 4 , Ġ 7 ] `; Ġ Ġ`[ 1 , Ġ 4 , Ġ 7 , Ġ 8 ]` Ġ-> Ġ`[ 4 , Ġ 7 , Ġ 8 ] `; Ġ`[ 2 , Ġ 4 , Ġ 7 , Ġ 8 , Ġ 9 ]` Ġ-> Ġ`[ 4 , Ġ 7 , Ġ 8 ]` ĊĠĠĠĠ Ġ* Ġ* Ġif Ġ 4 Ġcells Ġhave Ġcandidates Ġ`[ 1 , Ġ 2 ] `, Ġ`[ 1 , Ġ 3 , Ġ 4 , Ġ 5 , Ġ 9 ] `, Ġ`[ 1 , Ġ 2 , Ġ 5 , Ġ 9 ] `, Ġ`[ 1 , Ġ 2 , Ġ 4 , Ġ 5 , Ġ 8 ] `, Ġand Ġno Ġother Ġcells Ġin Ġthe Ġsame ĊĠĠĠĠ Ġ* ĠĠ Ġ[ Grid Segment ] Ġhave Ġany Ġof Ġthe Ġvalues Ġ`[ 1 , Ġ 2 , Ġ 5 , Ġ 9 ] `, Ġthe Ġother Ġvalues Ġcan Ġbe Ġelim inated Ġfrom Ġthese Ġcells . ĊĠĠĠĠ Ġ* ĠĠ ĠSo Ġin Ġthese Ġ 4 Ġcells , Ġthe Ġremaining Ġcandidate Ġvalues Ġof Ġthose Ġ 4 Ġcells Ġwill Ġbe Ġ`[ 1 , Ġ 2 ] `, Ġ`[ 1 , Ġ 5 , Ġ 9 ] `, Ġ`[ 1 , Ġ 2 , Ġ 5 , Ġ 9 ] `, Ġ`[ 1 , Ġ 2 , Ġ 5 ] `. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġsolve Pol ymorphic Combin ations () Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġsynchronized ( grid ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġgrid Size Ġdivided Ġby Ġ 2 : ĠIn Ġa Ġgrid Ġof Ġn ine Ġyou Ġmay Ġhave Ġexcluding Ġcombinations Ġof Ġ 1 .. 8 . ĊĠĠĠĠĠĠĠ Ġ// ĠBut Ġif Ġyou Ġhave Ġa Ġcombination Ġof , Ġsay Ġ[ 1 , Ġ 4 , Ġ 5 , Ġ 6 , Ġ 7 , Ġ 9 ], Ġthen Ġthere Ġmust Ġalso Ġbe Ġa Ġsmaller Ġcombination , ĊĠĠĠĠĠĠĠ Ġ// Ġin Ġthis Ġcase Ġ[ 1 , Ġ 3 , Ġ 8 ]. ĠSo Ġit Ġmakes Ġno Ġsense Ġto Ġlook Ġfor Ġcombinations Ġof Ġgrid Size Ġ/ Ġ 2 Ġor Ġlarger , Ġfinding ĊĠĠĠĠĠĠĠ Ġ// Ġlarger Ġcombinations Ġis Ġmuch Ġmore Ġcost ly Ġin Ġterms Ġof Ġcomputing Ġpower Ġ& Ġmemory ĊĠĠĠĠĠĠĠ Ġvar Ġgo Next Combination Size Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ( 1 .. ( grid . grid Size / 2 )). forEach Ġcom bi Length Loop @ Ġ{ Ġcombination Length Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! go Next Combination Size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġwe Ġhave Ġfound Ġcombinations Ġof , Ġsay , Ġ 3 , Ġwe Ġdo Ġnot Ġproceed Ġwith Ġcombinations Ġof Ġ 4 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġbetter Ġhandle Ġevents Ġfirst Ġ( with Ġless Ġcomplicated Ġsolution Ġmethods ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsegments . forEach Ġsegment Loop @{ Ġsegment Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġfind Ġall Ġcandidate Ġvalues Ġof Ġun solved Ġcells Ġof Ġthe Ġsegment Ġthat Ġhave Ġat Ġmost Ġ` combin ation Length ` Ġcandidates ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Candidates : ĠSorted Set < Int > Ġ= Ġcell Values By Segment [ segment ] !! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. as Sequence () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġcell Value Ġ-> Ġ! cell Value . is Fixed Ġ&& Ġ! cell Value . isSet Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġcell Value Ġ-> Ġ( cell Value Ġas ĠNon Fixed Value ). getValue Candidates () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġvalue Candidates Ġ-> Ġvalue Candidates . size Ġ<= Ġcombination Length Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatten () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. to Sorted Set () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( target Candidates . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ segment Loop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcandidate Combination Stream Ġ= Ġall Combin ations ( target Candidates , Ġcombination Length ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFind Ġall Ġcell Values Ġthat Ġhave Ġone Ġor Ġmore Ġcandidates Ġof Ġthe Ġgiven Ġcombination ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcandidate Combination Stream . forEach Ġ{ Ġc and icate Combination Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcell Values With Candidate From Com bi Ġ= Ġcell Values By Segment [ segment ] !! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġcell Value Ġ-> Ġ! cell Value . is Fixed Ġ&& Ġ! cell Value . isSet Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit Ġas ĠNon Fixed Value Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . getValue Candidates (). intersect ( cand icate Combination ). isNotEmpty () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cell Values With Candidate From Com bi . size Ġ== Ġcombination Length ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġif Ġonly Ġn Ġcell Values Ġhave Ġcandidates Ġwithin Ġa Ġgiven Ġcombination Ġof Ġn Ġvalues , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġall Ġother Ġcandidate Ġvalues Ġcan Ġbe Ġremoved Ġfrom Ġthese Ġcells ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcell Values With Candidate From Com bi . forEach Ġ{ Ġnon Fixed Value Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalues ToRemove Ġ= Ġnon Fixed Value . getValue Candidates () Ġ- Ġc and icate Combination ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( values ToRemove . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( non Fixed Value . remove Value Candidate (* values ToRemove . to IntArray ())) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgo Next Combination Size Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġsynchronized ( grid ) Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠ Ġhandle Events () Ċ // assert Correct Grid () Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠ Ġhandle Events () Ċ // assert Correct Grid () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsolve Grid Phase () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Sol ving Ġ|| Ġis S olved ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġwhen Ġ( sol ving Phase ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSOL VE _ SINGLE _ C AND ID ATE _ VALUES Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsolve Sing ular Candidates () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Events () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSOL VE _ EXCL UDING _ COMB IN ATIONS Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsolve Ident ical Candidate Sets () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsolve Single Value In Segments () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Events () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSOL VE _ POLY MOR PH IC _ COMB IN ATIONS Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsolve Ex cluding Subset Candidates () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsolve Pol ymorphic Ex clusions () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsolve Pol ymorphic Combin ations () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Events () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMULTI _ SEGMENT _ COMB IN ATIONS Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCH AIN ING _ TE CH NI QUE Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Sol ving ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠNotImplementedError ("$ sol ving Phase Ġis Ġnot Ġimplemented !") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġval Ġis S olved : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġsolving Phase Ġ== ĠGR ID _ SOL VED ĊĊĠĠĠ Ġfun Ġcheck Grid S olved (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is S olved ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( un S olved Non Fixed Values . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsolving Phase Ġ= ĠGR ID _ SOL VED ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġsolve Grid () Ġ{ ĊĠĠĠĠĠĠĠ Ġlog (). info Ġ{ Ġ" Grid Ġto Ġsolve : Ġ$ grid " Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( sol ving Phase Ġ== ĠPRE PARE D _ FOR _ SOL V ING ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsubscribe To Events () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsolving Phase Ġ= Ġsolving Phase . next Sol ving Phase () !! ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġcell Count Ġ= Ġgrid . grid Size Ġ* Ġgrid . grid Size ĊĠĠĠĠĠĠĠ Ġval Ġfixed Count Ġ= Ġgrid . cell List . filter Ġ{ Ġit . is Fixed Ġ}. size ĊĠĠĠĠĠĠĠ Ġvar Ġun S olved Count : ĠInt Ġ= Ġun S olved Non Fixed Values . size ĊĠĠĠĠĠĠĠ Ġvar Ġsolved Count Ġ= Ġcell Count Ġ- Ġfixed Count Ġ- Ġun S olved Count ĊĊĠĠĠĠĠĠĠ Ġfun Ġcheck Cell Counts () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cell Count Ġ!= Ġfixed Count Ġ+ Ġsolved Count Ġ+ Ġun S olved Count ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcheck Ġit , Ġjust Ġto Ġbe Ġsure ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith Ġ( IllegalStateException (" Error Ġin Ġcell Ġcounts ! ĠTotal Ġcells Ġ= Ġ$ cell Count Ġshould Ġbe Ġequal Ġto : ĠFixed Ġcells Ġ[$ fixed Count ] Ġ+ ĠS olved Ġcells Ġ[$ solved Count ] Ġ+ ĠUn solved Ġcells Ġ[$ un S olved Count ] ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (). error Ġ{ Ġthis Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdo Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (). info Ġ{ Ġ" Sol ving Ġgrid Ġ${ grid . toString Compact ()}, Ġphase Ġ= Ġ$ sol ving Phase " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsolve Grid Phase () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġun S olved Count Ġ= Ġ Ġun S olved Non Fixed Values . size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsolved Count Ġ= Ġcell Count Ġ- Ġfixed Count Ġ- Ġun S olved Count ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( event Queue . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsolving Phase Ġ= Ġsolving Phase . next Sol ving Phase () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠGrid Not Sol vable Exception (" Grid Ġis Ġnot Ġsolved !") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġwhile Ġ(! check Grid S olved ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog (). info Ġ{ Ġ" Grid Ġsolved ! ĠS olved Ġgrid Ġ= Ġ$ grid " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert Correct Grid () ĊĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( gn se : ĠGrid Not Sol vable Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Sol vable Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog (). info Ġ{ Ġ"${ gn se . message }. Ġ$ this " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"\ n Total Ġcells Ġ= Ġ$ cell Count ; ĠFixed Ġcells Ġ= Ġ$ fixed Count ; ĠS olved Ġcells Ġ= Ġ$ solved Count ; ĠUn solved Ġcells Ġ= Ġ$ un S olved Count " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( log (). isDebugEnabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun S olved Ġ= ĠArrayList ( un S olved Non Fixed Values ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġun S olved . sortBy Ġ{ Ġnon Fixed Value Ġ-> Ġnon Fixed Value . cell . rowIndex * grid . grid Size Ġ+ Ġnon Fixed Value . cell . col Index Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun solved Output Ġ= ĠFormat table List ( un S olved . map Ġ{ Ġnon Fixed Value Ġ-> Ġnon Fixed Value . toString () Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (). debug Ġ{ Ġ" Un solved Cells : Ġ\ n $ un solved Output " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Cell Counts () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġfun Ġhandle Event ( value Event : ĠValue Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is S olved ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġlog (). trace Ġ{ Ġ" Handling Ġevent : Ġ$ value Event " Ġ} Ċ // ĠĠĠĠĠĠĠ Ġsynchronized ( grid ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( value Event ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠSet CellValue Event Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Set CellValue Event ( value Event ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠCell Remove Candidates Event Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Remove Candidates Event ( value Event ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnot Ġexpected Ġto Ġbe Ġcalled , Ġso Ġwarning : ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġit Ġwould Ġmean Ġwe Ġsubscribed Ġto Ġan Ġevent Ġtype Ġthat Ġwe Ġare Ġnot Ġwilling Ġto Ġhandle ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (). warn Ġ{ Ġ" Unhandled Ġevent Ġtype : Ġ${ value Event . java Class . simple Name }; Ġevent =$ value Event " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( is Sol ving ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsolving Phase Ġ= Ġfirst Sol ving Phase () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsolve Grid Phase () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġfun Ġhandle Events () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is S olved ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġvar Ġevent : ĠValue Event ĊĠĠĠĠĠĠĠ Ġlog (). trace Ġ{ Ġ" Event Ġcount Ġto Ġhandle : Ġ${ event Queue . size }" Ġ} ĊĠĠĠĠĠĠĠ Ġdo Ġ{ Ġevent Ġ= Ġevent Queue . poll () Ġ?: Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Event ( event ) ĊĠĠĠĠĠĠĠ Ġ} Ġwhile Ġ( true ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Event ( value Event : ĠValue Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is S olved ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġlog (). trace Ġ{ Ġ"$ this Ġreceived Ġevent : Ġ$ value Event " Ġ} ĊĠĠĠĠĠĠĠ Ġevent Queue . put ( value Event ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġnot Ġsolved Ġyet , Ġfor Ġnot Ġtoo Ġbig Ġgrids Ġwe Ġdisplay Ġthe Ġgrid Ġwith Ġcandidates , Ġfor Ġeasier Ġdebugging Ġetc . ĊĠĠĠĠĠĠĠ Ġval Ġgrid ToString Ġ= Ġif Ġ( grid ToS olve Ġ== Ġnull ) Ġ" null " Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is S olved Ġ|| Ġgrid . grid Size Ġ> Ġ 9 ) Ġgrid . toString () Ġelse Ġgrid With Candidates Box Formatter . format ( grid ). toString () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġ"${ this . java Class . simple Name }: Ġis Sol ving =$ is Sol ving , Ġsolving Phase =$ sol ving Phase , Ġgrid =\ n $ grid ToString " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ[ Sub Segment ] s Ġare Ġartifacts Ġthat Ġare Ġused Ġfor Ġsolving Ġonly . ĊĠĠĠĠ Ġ* ĠThey Ġhave Ġquite Ġsome Ġsimilar ities Ġwith Ġ[ Row ] s Ġand Ġ[ Col ] s , Ġand Ġalso Ġwith Ġ[ Block ] s , Ġbut Ġconstructed Ġfor Ġsolving Ġpurposes Ġonly , ĊĠĠĠĠ Ġ* Ġnot Ġas Ġan Ġintegral Ġpart Ġof Ġthe ĠS udoku 's Ġ[ Grid ] Ġmodel . ĊĠĠĠĠ Ġ* Ġ[ Sub Segment ] s Ġmay Ġhave Ġreferences Ġto Ġ[ Row ] s , Ġ[ Col ] s Ġand Ġ[ Block ] s , Ġbut Ġnot Ġthe Ġother Ġway Ġaround : Ġ[ Row ] s , Ġ[ Col ] s Ġand ĊĠĠĠĠ Ġ* Ġ[ Block ] s Ġare Ġnot Ġaware Ġof Ġ[ Sub Segment ] s . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprotected Ġsealed Ġclass ĠSub Segment < out ĠS : ĠLinear Segment >( grid : ĠGrid ): ĠGrid Element ( grid ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġabstract Ġval Ġcells : ĠSet < Cell > ĊĠĠĠĠĠĠĠ Ġabstract Ġval Ġen closing Block : ĠBlock ĊĠĠĠĠĠĠĠ Ġabstract Ġval Ġen closing Linear Segment : ĠS ĊĊĠĠĠĠĠĠĠ Ġclass ĠHorizontal Sub Segment ( grid : ĠGrid , Ġval ĠrowIndex : ĠInt , Ġval Ġleft Col Index : ĠInt ): ĠSub Segment < Row >( grid ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġright Col Index : ĠInt Ġ= Ġleft Col Index Ġ+ Ġgrid . block Size Ġ- Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġen closing Row : ĠRow Ġ= Ġgrid . row List . first Ġ{ Ġit . rowIndex Ġ== ĠrowIndex Ġ} Ġ// Ġfilter Ġreturns Ġ 1 Ġrow Ġonly ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġen closing Linear Segment : ĠRow Ġ= Ġen closing Row ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġen closing Block : ĠBlock Ġ= Ġgrid . blockList . first Ġ{ ĠrowIndex Ġin Ġit . top RowIndex .. it . bottom RowIndex Ġ&& Ġleft Col Index Ġ== Ġit . left Col Index Ġ} Ġ// Ġfilter Ġreturns Ġ 1 Ġrow Ġonly ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġcells : ĠSet < Cell > Ġ= ĠLinked HashSet ( enc lo sing Row . cells . filter Ġ{ Ġit . col Index Ġin Ġleft Col Index .. right Col Index Ġ}) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ"${ this . java Class . simple Name }: Ġ[ rowIndex =$ rowIndex ] Ġ[ left Col Index =$ left Col Index ] Ġ[ right Col Index =$ right Col Index ]" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( grid . block Size Ġ<= Ġ 4 ) Ġ(" \ n " Ġ+ Ġformat ( default Grid Formatter )) Ġelse Ġ"" ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĠConcat en ates Ġthe Ġformatted Ġ[ Cell ] s Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġformat ( formatter : ĠS udoku Formatter ): ĠFormat table List Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġformatted Cells Ġ= Ġcells . map Ġ{ Ġformatter . format ( it ) Ġ}. to Typed Array () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠFormat table List ( concat Each (* formatted Cells )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġclass ĠVertical Sub Segment ( grid : ĠGrid , Ġval Ġcol Index : ĠInt , Ġval Ġtop RowIndex : ĠInt ): ĠSub Segment < Col >( grid ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbot t tom RowIndex : ĠInt Ġ= Ġtop RowIndex Ġ+ Ġgrid . block Size Ġ- Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġen closing Col : ĠCol Ġ= Ġgrid . col List . first Ġ{ Ġit . col Index Ġ== Ġcol Index Ġ} Ġ// Ġfilter Ġreturns Ġ 1 Ġcol Ġonly ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġen closing Linear Segment : ĠCol Ġ= Ġen closing Col ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġen closing Block : ĠBlock Ġ= Ġgrid . blockList . first Ġ{ Ġcol Index Ġin Ġit . left Col Index .. it . right Col Index Ġ&& Ġtop RowIndex Ġ== Ġit . top RowIndex Ġ} Ġ// Ġfilter Ġreturns Ġ 1 Ġrow Ġonly ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġcells : ĠSet < Cell > Ġ= ĠLinked HashSet ( enc lo sing Col . cells . filter Ġ{ Ġit . rowIndex Ġin Ġtop RowIndex .. bot t tom RowIndex Ġ}) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ"${ this . java Class . simple Name }: Ġ[ col Index =$ col Index ] Ġ[ top RowIndex =$ top RowIndex ] Ġ[ bot t tom RowIndex =$ bot t tom RowIndex ]" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( grid . block Size Ġ<= Ġ 4 ) Ġ(" \ n " Ġ+ Ġformat ( default Grid Formatter )) Ġelse Ġ"" ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĠReturns Ġthe Ġformatted Ġ[ Cell ] s Ġbelow Ġeach Ġother Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġformat ( formatter : ĠS udoku Formatter ): ĠFormat table List Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġformatted Cells Ġ= Ġcells . map Ġ{ Ġformatter . format ( it ). toString () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠFormat table List ( formatted Cells . fold ( listOf (), Ġ{ current , Ġnext Ġ-> Ġcurrent Ġ+ Ġnext })) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ } Ċ Ċ /** Ċ Ġ* ĠEnum er ates Ġphases Ġin Ġthe Ġ[ Grid ] Ġsolving Ġprocess . ĠThe Ġorder Ġof Ġthe Ġenum Ġvalues Ġis Ġstrictly Ġrelevant , Ġwith Ġascending Ġcomplexity . Ċ Ġ* ĠSee Ġalso Ġmethods Ġ[ next Phase ] Ġand Ġ[ next Sol ving Phase ]. Ċ Ġ* Ġ@ param Ġis Sol ving Ġindication Ġwhether Ġthe Ġ[ Grid ] Ġis Ġactually Ġsolved Ġin Ġthis Ġphase Ċ Ġ*/ Ċ enum Ġclass ĠGrid Sol ving Phase ( val Ġis Sol ving : ĠBoolean ) Ġ{ ĊĠĠĠ Ġ/** ĠIndicates Ġthat Ġthe Ġ[ Grid Solver ] Ġwas Ġnot Ġassigned Ġa Ġgrid Ġyet . Ġ[ is Sol ving ] Ġ= Ġ` false ` Ġ*/ ĊĠĠĠ ĠUN ASS IGNED ( is Sol ving Ġ= Ġfalse ), ĊĠĠĠ Ġ/** ĠIndicates Ġthat Ġthe Ġ[ Grid Solver ] Ġis Ġready Ġto Ġstart Ġprocessing Ġ( a Ġ[ Grid ] Ġhas Ġbeen Ġassigned ). Ġ[ is Sol ving ] Ġ= Ġ` false ` Ġ*/ ĊĠĠĠ ĠPRE PARE D _ FOR _ SOL V ING ( is Sol ving Ġ= Ġfalse ), ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠPhase Ġ[ SOL VE _ SINGLE _ C AND ID ATE _ VALUES ] Ġindicates Ġthat Ġthe Ġ[ Grid Solver ] Ġis Ġprocessing , Ġsearching Ġfor Ġsingle Ġcandidate Ġvalues Ġwithin Ġ[ Grid Segment ] s . Ġ[ is Sol ving ] Ġ= Ġ` true `. ĊĠĠĠĠ Ġ* Ġ* ĠE . g . Ġif Ġa Ġcell Ġhas Ġ`[ 5 ]` Ġas Ġit 's Ġonly Ġremaining Ġcandidate Ġvalue , Ġno Ġother Ġcells Ġin Ġthe Ġ[ Grid Segment ] s Ġthe Ġcell Ġis Ġpart Ġof ĊĠĠĠĠ Ġ* ĠĠ Ġcan Ġhave Ġthat Ġvalue , Ġso Ġ`[ 5 ]` Ġcan Ġbe Ġelim inated Ġfrom Ġthe Ġother Ġcells . ĊĠĠĠĠ Ġ* Ġ> ĠA ka Ġ[ S ud op edia : ĠN aked ĠSingle ]( http :// s ud op edia . en jo ys udoku . com / N aked _ Single . html ), ĊĠĠĠĠ Ġ* ĠĠ Ġ[ Dec abit : ĠN aked ĠSingle ]( http :// www . dec abit . com / S udoku / N aked Single ), Ġor ĠFor ced ĠDig it . ĊĠĠĠĠ Ġ* Ġ> ĠSee : Ġ[ Grid Solver . solve Sing ular Candidates ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ ĠSOL VE _ SINGLE _ C AND ID ATE _ VALUES ( is Sol ving Ġ= Ġtrue ), ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠPhase Ġ[ SOL VE _ EXCL UDING _ COMB IN ATIONS ] Ġindicates Ġthat Ġthe Ġ[ Grid Solver ] Ġis Ġprocessing , ĊĠĠĠĠ Ġ* Ġsearching Ġfor Ġcombinations Ġof Ġcandidate Ġvalues Ġthat Ġexclude Ġthese Ġvalues Ġfrom Ġother Ġcells ĊĠĠĠĠ Ġ* Ġin Ġthe Ġ[ Grid Segment ]. Ġ[ is Sol ving ] Ġ= Ġ` true `. ĊĠĠĠĠ Ġ* ĠE . g ., ĊĠĠĠĠ Ġ* Ġ* Ġif Ġ 2 Ġcells Ġin Ġa Ġ[ Grid Segment ] Ġboth Ġhave Ġ`[ 2 , Ġ 4 ]` Ġas Ġcandidates , Ġno Ġother Ġcells Ġin Ġthat Ġsegment Ġcan Ġhave Ġthese ĊĠĠĠĠ Ġ* ĠĠ Ġcandidate Ġvalues , Ġso Ġthese Ġcan Ġbe Ġelim inated Ġfrom Ġthe Ġother Ġ[ CellValue ] s Ġin Ġthe Ġ[ Grid Segment ] ĊĠĠĠĠ Ġ* Ġ> ĠSee : Ġ[ Grid Solver . solve Ident ical Candidate Sets ]. ĊĠĠĠĠ Ġ* Ġ> ĠA ka Ġ[ S ud op edia : ĠN aked ĠPair ]( http :// s ud op edia . en jo ys udoku . com / N aked _ Pair . html ), ĊĠĠĠĠ Ġ* ĠĠ Ġwhich Ġis Ġa Ġ[ N aked ĠSub set ]( http :// www . dec abit . com / S udoku / N aked Subset ) Ġof Ġsize Ġ 2 . ĊĠĠĠĠ Ġ* Ġ* Ġif Ġcells Ġin Ġa Ġ[ Grid Segment ] Ġhave Ġdifferent Ġcombinations Ġof Ġvalues , ĊĠĠĠĠ Ġ* ĠĠ Ġe . g . Ġ`[ 1 , Ġ 3 , Ġ 6 ] `, Ġ`[ 2 , Ġ 3 , Ġ 7 ] `, Ġ`[ 1 , Ġ 3 , Ġ 7 , Ġ 9 ] `, Ġ`[ 2 , Ġ 4 , Ġ 5 , Ġ 8 , Ġ 9 ]` ĊĠĠĠĠ Ġ* ĠĠ Ġand Ġonly Ġ 1 Ġof Ġthose Ġhas Ġ`[ 6 ]` Ġas Ġa Ġcandidate Ġvalue , Ġthat Ġcell 's Ġvalue Ġcan Ġbe Ġset Ġto Ġ`[ 6 ] `. ĊĠĠĠĠ Ġ* Ġ> ĠA ka Ġ[ S ud op edia : ĠHidden ĠSingle ]( http :// s ud op edia . en jo ys udoku . com / Hidden _ Single . html ) ĊĠĠĠĠ Ġ* Ġ> ĠSee : Ġ[ Grid Solver . solve Single Value In Segments ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ ĠSOL VE _ EXCL UDING _ COMB IN ATIONS ( is Sol ving Ġ= Ġtrue ), ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠPhase Ġ[ SOL VE _ POLY MOR PH IC _ COMB IN ATIONS ] Ġindicates Ġthat Ġthe Ġ[ Grid Solver ] Ġis Ġprocessing , Ġand Ġsearching Ġfor Ġpol ymorphic Ġcombinations Ġof Ġcandidate Ġvalues . Ġ[ is Sol ving ] Ġ= Ġ` true `. ĊĠĠĠĠ Ġ* ĠE . g . ĊĠĠĠĠ Ġ* Ġ* Ġif Ġin Ġa Ġ[ Block ] Ġa Ġcombination Ġof Ġvalues , Ġsay , Ġ`[ 2 , Ġ 6 ] `, Ġonly Ġexists Ġin Ġa Ġsingle Ġrow Ġpart Ġ( sub - segment ) Ġof Ġthe Ġ[ Block ], ĊĠĠĠĠ Ġ* ĠĠ Ġ( so Ġthese Ġall Ġhave , Ġsay , Ġ[ Block . rowIndex ] Ġ= Ġ 4 , Ġthus Ġthe Ġcells Ġwith Ġ[ Block . rowIndex ] Ġ 4 Ġhave Ġcandidates Ġ`[ 2 , Ġ 4 , Ġ 7 ] `, Ġ`[ 2 , Ġ 6 , Ġ 7 ]` ĊĠĠĠĠ Ġ* ĠĠ Ġand Ġ`[ 3 , Ġ 6 ] `, Ġand Ġno Ġother Ġcells Ġin Ġthat Ġblock Ġhave Ġcandidate Ġ`[ 2 ]` Ġor Ġ`[ 6 ] `), Ġthan Ġthese Ġvalues Ġ 2 Ġand Ġ 6 Ġcan Ġbe Ġremoved Ġfrom ĊĠĠĠĠ Ġ* ĠĠ Ġall Ġother Ġcells Ġin Ġthe Ġ[ Row ] Ġwith Ġ[ Row . rowIndex ] Ġ= Ġ 4 . ĊĠĠĠĠ Ġ* ĠĠ Ġ> ĠA ka ĠBlock ĠLine Ġor Ġ[ S ud op edia : ĠLocked ĠC andidates Ġtype Ġ 1 ]( http :// s ud op edia . en jo ys udoku . com / Locked _ Candidates . html # Type _ 1 _. 2 8 Point ing . 2 9 ) ĊĠĠĠĠ Ġ* Ġ* Ġthe Ġsame Ġcombination Ġof Ġvalues , Ġsay Ġ`[ 2 , Ġ 6 ]` Ġfrom Ġthe Ġabove Ġexample Ġcan Ġalso Ġbe Ġremoved Ġfrom Ġthe Ġcells Ġin Ġthe Ġ[ Block ] ĊĠĠĠĠ Ġ* ĠĠ Ġthat Ġare Ġnot Ġpart Ġof Ġthe Ġsub - segment Ġof Ġthe Ġ[ Block ]. ĊĠĠĠĠ Ġ* ĠĠ Ġ> ĠA ka ĠBlock ĠLine Ġor Ġ[ S ud op edia : ĠLocked ĠC andidates Ġtype Ġ 2 ]( http :// s ud op edia . en jo ys udoku . com / Locked _ Candidates . html # Type _ 2 _. 2 8 Claim ing _ or _ Box - Line _ Reduction . 2 9 ) ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ> ĠSee : Ġ[ Grid Solver . solve Ex cluding Subset Candidates ]. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ* Ġif Ġ 3 Ġcells Ġin Ġa Ġ[ Grid Segment ] Ġhave Ġcandidates , Ġsay , Ġ`[ 2 , Ġ 8 ] `, Ġ`[ 3 , Ġ 8 ] `, Ġ`[ 2 , Ġ 8 ] `, Ġthen Ġthe Ġvalues Ġ`[ 2 , Ġ 3 , Ġ 8 ]` Ġcan Ġbe Ġremoved ĊĠĠĠĠ Ġ* ĠĠ Ġfrom Ġthe Ġcandidates Ġof Ġall Ġother Ġcells Ġin Ġthe Ġsame Ġ[ Grid Segment ]. ĊĠĠĠĠ Ġ* Ġ* Ġif Ġ 4 Ġcells Ġhave Ġcandidates Ġ`[ 1 , Ġ 2 ] `, Ġ`[ 1 , Ġ 2 , Ġ 3 ] `, Ġ`[ 2 , Ġ 3 ] `, Ġ`[ 1 , Ġ 4 ] `, Ġthen Ġthe Ġvalues Ġ`[ 1 , Ġ 2 , Ġ 3 , Ġ 4 ]` Ġcan Ġbe Ġremoved ĊĠĠĠĠ Ġ* ĠĠ Ġfrom Ġthe Ġcandidates Ġof Ġall Ġother Ġcells Ġin Ġthe Ġsame Ġ[ Grid Segment ]. ĊĠĠĠĠ Ġ* Ġ> ĠA ka Ġ[ S ud op edia : ĠN aked ĠSub set ]( http :// s ud op edia . en jo ys udoku . com / N aked _ Subset . html ), Ġ[ Dec abit : ĠN aked ĠSub set ]( http :// www . dec abit . com / S udoku / N aked Subset ); ĊĠĠĠĠ Ġ* ĠĠ Ġdepending Ġon Ġtheir Ġsize Ġalso ĠN aked ĠPair , ĠN aked ĠTrip le , ĠN aked ĠQuad Ġetc . ĊĠĠĠĠ Ġ* Ġ> ĠSee : Ġ[ Grid Solver . solve Pol ymorphic Ex clusions ]. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ* Ġif Ġ 3 Ġcells Ġin Ġa Ġ[ Grid Segment ] Ġhave Ġcandidates , Ġsay , Ġ`[ 4 , Ġ 7 ] `, Ġ`[ 1 , Ġ 4 , Ġ 7 , Ġ 8 ] `, Ġ`[ 2 , Ġ 4 , Ġ 7 , Ġ 8 , Ġ 9 ] `, ĊĠĠĠĠ Ġ* Ġ Ġand Ġnone Ġof Ġthe Ġvalues Ġ`[ 4 , Ġ 7 , Ġ 8 ]` Ġis Ġa Ġcandidate Ġvalue Ġof Ġthe Ġother Ġcells Ġin Ġthe Ġsame Ġ[ Grid Segment ], Ġthe Ġother Ġvalues Ġcan Ġbe ĊĠĠĠĠ Ġ* Ġ Ġremoved Ġfrom Ġthese Ġcells . ĊĠĠĠĠ Ġ* Ġ ĠSo Ġin Ġthese Ġ 3 Ġcells , Ġthe Ġcandidate Ġvalues Ġare Ġreduced Ġlike Ġthis : Ġ`[ 4 , Ġ 7 ]` Ġ-> Ġ`[ 4 , Ġ 7 ] `; Ġ Ġ`[ 1 , Ġ 4 , Ġ 7 , Ġ 8 ]` Ġ-> Ġ`[ 4 , Ġ 7 , Ġ 8 ] `; Ġ`[ 2 , Ġ 4 , Ġ 7 , Ġ 8 , Ġ 9 ]` Ġ-> Ġ`[ 4 , Ġ 7 , Ġ 8 ]` ĊĠĠĠĠ Ġ* Ġ* Ġif Ġ 4 Ġcells Ġhave Ġcandidates Ġ`[ 1 , Ġ 2 ] `, Ġ`[ 1 , Ġ 3 , Ġ 4 , Ġ 5 , Ġ 9 ] `, Ġ`[ 1 , Ġ 2 , Ġ 5 , Ġ 9 ] `, Ġ`[ 1 , Ġ 2 , Ġ 4 , Ġ 5 , Ġ 8 ] `, Ġand Ġno Ġother Ġcells Ġin Ġthe Ġsame ĊĠĠĠĠ Ġ* ĠĠ Ġ[ Grid Segment ] Ġhave Ġany Ġof Ġthe Ġvalues Ġ`[ 1 , Ġ 2 , Ġ 5 , Ġ 9 ] `, Ġthe Ġother Ġvalues Ġcan Ġbe Ġelim inated Ġfrom Ġthese Ġcells . ĊĠĠĠĠ Ġ* ĠĠ ĠSo Ġin Ġthese Ġ 4 Ġcells , Ġthe Ġremaining Ġcandidate Ġvalues Ġof Ġthose Ġ 4 Ġcells Ġwill Ġbe Ġ`[ 1 , Ġ 2 ] `, Ġ`[ 1 , Ġ 5 , Ġ 9 ] `, Ġ`[ 1 , Ġ 2 , Ġ 5 , Ġ 9 ] `, Ġ`[ 1 , Ġ 2 , Ġ 5 ] `. ĊĠĠĠĠ Ġ* Ġ> ĠA ka Ġ[ S ud op edia : ĠHidden ĠSub set ]( http :// s ud op edia . en jo ys udoku . com / Hidden _ Subset . html ), Ġ[ Dec abit : ĠHidden ĠSub set ]( http :// www . dec abit . com / S udoku / Hidden Subset ). ĊĠĠĠĠ Ġ* ĠĠ ĠDep ending Ġon Ġtheir Ġsize Ġalso ĠN aked ĠPair , ĠN aked ĠTrip le , ĠN aked ĠQuad Ġetc . ĊĠĠĠĠ Ġ* Ġ> ĠSee : Ġ[ Grid Solver . solve Pol ymorphic Combin ations ]. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠRe Ġthe Ġ' pol ymorphic ' Ġin Ġ[ SOL VE _ POLY MOR PH IC _ COMB IN ATIONS ], Ġthis Ġis Ġbecause Ġnone Ġof Ġthe Ġcells Ġmay Ġhave Ġthe ĊĠĠĠĠ Ġ* Ġexact Ġcombination Ġof Ġvalues Ġsearched Ġfor , Ġsome Ġcandidate Ġvalues Ġof Ġthe Ġcombination Ġsearched Ġfor Ġmay Ġnot Ġbe ĊĠĠĠĠ Ġ* Ġpresent Ġin Ġthe Ġtouched Ġcells , Ġand Ġcells Ġmay Ġhave Ġcandidate Ġvalues Ġthat Ġare Ġnot Ġpart Ġof Ġthe Ġcombination Ġsearched Ġfor . ĊĠĠĠĠ Ġ* ĠThis Ġis Ġcomputation ally Ġrelatively Ġcost ly , Ġso Ġthis Ġmethod Ġshould Ġbe Ġthe Ġlast Ġone Ġbefore Ġstarting Ġwith Ġ[ MULTI _ SEGMENT _ COMB IN ATIONS ] ĊĠĠĠĠ Ġ* Ġif Ġun solved Ġcandidates Ġremain Ġafter Ġall Ġprevious Ġmethods Ġhave Ġbeen Ġapplied . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ ĠSOL VE _ POLY MOR PH IC _ COMB IN ATIONS ( is Sol ving Ġ= Ġtrue ), ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġprevious Ġ( less Ġadvanced ) Ġtechniques Ġcan Ġeasily Ġbe Ġde duced Ġfrom Ġthe Ġsimple ĠS udoku Ġrules . ĊĠĠĠĠ Ġ* ĠBut Ġmany Ġmany ĠS udoku Ġp uzz les Ġappear Ġto Ġexist Ġthat Ġcan 't Ġbe Ġsolved Ġby Ġthese Ġtechniques Ġ( in Ġfact , Ġwhen Ġtrying Ġto ĊĠĠĠĠ Ġ* Ġsolve Ġsome Ġof Ġthe Ġhar dest Ġp uzz les Ġavailable Ġ[ e . g . Ġthe Ġhar dest Ġever ĠS udoku Ġ" Gold en ĠN ug get "]( http :// www . s ud ok us n ake . com / images / Gold en N ug get . PNG ), ĊĠĠĠĠ Ġ* Ġ_ none _ Ġof Ġthe Ġcells Ġare Ġsolved Ġwith Ġthese Ġprevious Ġtechniques ! Ġ( see ĠGrid Solver IT ) ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThe Ġfollowing Ġmore Ġadvanced Ġtechniques Ġare Ġless Ġobvious ; Ġundo ub ted ly Ġthey Ġcan Ġbe Ġmathematic ally Ġpro ven , ĊĠĠĠĠ Ġ* Ġbut Ġhere Ġthey Ġare Ġtaken Ġ" as Ġis ". ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠT BD ! ĊĠĠĠĠ Ġ* Ġ* Ġ[ X - W ing ]( http :// www . dec abit . com / S udoku / X W ing ), Ġ[ S word fish ]( http :// www . dec abit . com / S udoku / S word fish ), ĊĠĠĠĠ Ġ* ĠĠ Ġ[ J el ly fish ]( http :// www . dec abit . com / S udoku / J el ly fish ), Ġ[ S quir mb ag ]( http :// s ud op edia . en jo ys udoku . com / S quir mb ag . html ) ĊĠĠĠĠ Ġ* ĠĠ Ġessentially , Ġthese Ġare Ġequal Ġtechniques Ġbut Ġon Ġdifferent Ġnumbers Ġof Ġsegments ; ĊĠĠĠĠ Ġ* Ġ* Ġ[ XY - W ing ]( http :// www . dec abit . com / S udoku / XY W ing ) Ġand Ġ[ XYZ - W ing ]( http :// www . dec abit . com / S udoku / XY ZW ing ); ĊĠĠĠĠ Ġ* ĠĠ Ġthese Ġare Ġequal Ġtechniques Ġbut Ġwith Ġdifferent Ġnumbers Ġof Ġcandidate Ġvalues ; ĊĠĠĠĠ Ġ* ĠĠ Ġ* ĠMaybe Ġalso : Ġ[ XY - Chain ]( http :// www . dec abit . com / S udoku / XY Chain ), Ġwhich Ġis Ġan Ġextension Ġof Ġthe ĠXY - W ing Ġtechnique ĊĠĠĠĠ Ġ* Ġ* ĠMaybe : Ġ[ Colo uring - tech nique ]( http :// www . dec abit . com / S udoku / Colo uring ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ ĠMULTI _ SEGMENT _ COMB IN ATIONS ( is Sol ving Ġ= Ġtrue ), ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠEven Ġmore Ġadvanced Ġtechniques , Ġmaybe Ġincluding Ġ[ Almost ĠLocked ĠSets ]( http :// s ud op edia . en jo ys udoku . com / Almost _ Locked _ Set . html ) ĊĠĠĠĠ Ġ* Ġ> ĠT BD Ġ! ĊĠĠĠĠ Ġ*/ ĊĠĠĠ ĠCH AIN ING _ TE CH NI QUE ( is Sol ving Ġ= Ġtrue ), ĊĊĠĠĠ Ġ/** ĠIndicates Ġthat Ġthe Ġ[ Grid ] Ġwas Ġsolved Ġsuccessfully ; Ġ[ is Sol ving ] Ġ= Ġ` false ` Ġ*/ ĊĠĠĠ ĠGR ID _ SOL VED ( is Sol ving Ġ= Ġfalse ); ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGiven Ġ` this ` Ġ[ Grid Sol ving Phase ], Ġget Ġthe Ġnext Ġone Ġfrom Ġ[ values ]; ĊĠĠĠĠ Ġ* Ġif Ġ` this ` Ġis Ġalready Ġthe Ġlast Ġone , Ġthen Ġnull ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġnext Phase (): ĠGrid Sol ving Phase ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( ordinal Ġ< Ġlast Index ) Ġvalues ()[ ordinal + 1 ] Ġelse Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGiven Ġ` this ` Ġ[ Grid Sol ving Phase ], Ġget Ġthe Ġnext Ġone Ġfrom Ġ[ values ] Ġwhere Ġ[ is Sol ving ] Ġ` == Ġtrue `, ĊĠĠĠĠ Ġ* Ġif Ġany ; Ġotherwise Ġ` null ` ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġnext Sol ving Phase (): ĠGrid Sol ving Phase ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġphase Ġ= Ġthis . next Phase () ĊĠĠĠĠĠĠĠ Ġwhile Ġ( phase Ġ!= Ġnull Ġ&& Ġ! phase . is Sol ving ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġphase Ġ= Ġphase . next Phase () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( phase Ġ!= Ġnull Ġ&& Ġphase . is Sol ving ) Ġphase Ġelse Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġlast Index Ġ= Ġvalues (). last Index ĊĠĠĠĠĠĠĠ Ġfun Ġfirst Sol ving Phase (): ĠGrid Sol ving Phase Ġ= Ġvalues (). first Ġ{ Ġit . is Sol ving Ġ} ĊĠĠĠĠĠĠĠ Ġ@ Suppress (" unused ") Ġ// Ġleft Ġthere Ġas Ġa Ġcounter part Ġof Ġfirst Sol ving Phase () ĊĠĠĠĠĠĠĠ Ġfun Ġlast Sol ving Phase (): ĠGrid Sol ving Phase Ġ= Ġvalues (). last Ġ{ Ġit . is Sol ving Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ class ĠGrid Not Set Exception ( message : ĠString ) Ġ: ĠIllegalStateException ( message ) Ċ Ċ const Ġval Ġgrid ToS olve PropertyName : ĠString Ġ= Ġ" grid ToS olve " Ċ