package Ġcom . one gravity . s udoku Ċ Ċ import Ġcom . one gravity . s udoku . S udoku Matrix . Companion . getIndex Value Ċ import Ġcom . one gravity . s udoku . S udoku Matrix . Companion . to S udoku Matrix Ċ import Ġcom . one gravity . s udoku . model . Grid Ċ import Ġcom . one gravity . s udoku . model . P uzzle Ċ import Ġorg . junit . jupiter . api . Assertions Ċ import Ġjava . io . File Ċ import Ġjava . text . Decimal Format Ċ Ċ fun Ġtest And Validate S udoku ( ĊĠĠĠ Ġpuzzle : ĠP uzzle , ĊĠĠĠ Ġsolution : ĠInt Array , ĊĠĠĠ Ġsolve : ĠArray < Boolean Array >. ( collect : Ġ( List < Int >) Ġ-> ĠUnit ) Ġ-> ĠUnit Ċ ) Ġ{ ĊĠĠĠ Ġtest S udoku ( pu zzle , Ġsolution , Ġsolve ) Ċ } Ċ Ċ private Ġfun Ġtest S udoku ( ĊĠĠĠ Ġpuzzle : ĠP uzzle , ĊĠĠĠ Ġsolution : ĠInt Array ?, ĊĠĠĠ Ġsolve : ĠArray < Boolean Array >. ( collect : Ġ( List < Int >) Ġ-> ĠUnit ) Ġ-> ĠUnit Ċ ) Ġ{ ĊĠĠĠ Ġvar Ġsolution Found Ġ= Ġfalse ĊĠĠĠ Ġpuzzle . to S udoku Matrix () ĊĠĠĠĠĠĠĠ Ġ. solve Ġ{ Ġrows Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( solution Ġ!= Ġnull ) Ġvalidate Solution ( solution , Ġpuzzle , Ġrows . to Grid ( pu zzle )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsolution Found Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġassert ( solution Found ) Ċ } Ċ Ċ fun Ġvalidate Solution ( expected : ĠInt Array , Ġoriginal : ĠP uzzle , Ġactual : ĠP uzzle ) Ġ{ ĊĠĠĠ Ġexpected . forEach Indexed Ġ{ Ġindex , Ġvalue Ġ-> ĊĠĠĠĠĠĠĠ ĠAssertions . assertEquals ( original . getCell ( index ). is Given , Ġactual . getCell ( index ). is Given ) ĊĠĠĠĠĠĠĠ ĠAssertions . assertEquals ( value , Ġactual . getCell ( index ). value ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠConverts Ġan ĠAlgorithm X Ġsolution Ġ( Collection Ġof Ġrow Ġindices ) Ġinto Ġa ĠS udoku ĠGrid . Ċ Ġ* Ċ Ġ* Ġ@ param Ġoriginal Ġthe Ġoriginal ĠS udoku Ġpuzzle Ġthe Ġalgorithm Ġsolved Ġso Ġthat Ġwe Ġcan Ġset Ġis Given Ġproperly Ċ Ġ*/ Ċ fun ĠList < Int >. to Grid ( original : ĠP uzzle ) Ġ= ĠGrid ( original . extra Region Type , Ġoriginal . is J igsaw ) ĊĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠ Ġsorted (). forEach Ġ{ Ġrow Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( index , Ġvalue ) Ġ= Ġget Index Value ( row ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠsetValue ( index , Ġvalue , Ġoriginal . getCell ( index ). is Given ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ /** Ċ Ġ* ĠConvert Ġvalues Ġfrom Ġthe Ġstandard Ġcsv Ġformat Ġto Ġan ĠInt Array . Ċ Ġ* ĠInput : Ġ Ġ.... ... 1 2 ........ 3 .. 2 3 .. 4 .... 1 8 .... 5 . 6 .. 7 . 8 ....... 9 ..... 8 5 ..... 9 ... 4 . 5 .. 4 7 ... 6 ... Ċ Ġ* ĠOutput : Ġ[ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 3 Ġetc .] Ċ Ġ*/ Ċ fun ĠString . to IntArray () Ġ= Ġthis . map Ġ{ Ġc Ġ-> Ġc . digit ToInt OrNull () Ġ?: Ġ 0 Ġ}. to IntArray () Ċ Ċ /** Ċ Ġ* ĠReads Ġp uzz les Ġfrom Ġa Ġfile Ġin Ġthe Ġstandard Ġcsv Ġformat Ġwith Ġcomma Ġseparated Ġsolution . Ċ Ġ* Ċ Ġ* Ġ@ param ĠfileName ĠThe Ġname Ġof Ġthe Ġfile Ġto Ġread Ċ Ġ* Ġ@ param Ġprocess Ġthe Ġfunction Ġcalled Ġwith Ġeach ĠS udoku Ġpassing Ġin Ġthe Ġpuzzle Ġand Ġthe Ġsolution Ġas ĠInt Arrays Ċ Ġ*/ Ċ fun Ġget P uzz les ( fileName : ĠString , Ġlimit : ĠInt Ġ= ĠInt . MAX _ VALUE , Ġprocess : Ġ( pu zzle : ĠInt Array , Ġsolution : ĠInt Array ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠ Ġvar Ġcount Ġ= Ġ 0 ĊĠĠĠ ĠFile ( ClassLoader . getSystem Resource ( fileName ). file ) ĊĠĠĠĠĠĠĠ Ġ. forEach Line Ġ{ Ġline Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġfind ĠS udoku Ġp uzz les ĊĠĠĠĠĠĠĠĠĠĠĠ Ġs udoku Pattern . findAll ( line ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ Ġmatch Result Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( count ++ Ġ< Ġlimit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġget Ġgroup Ġwith Ġpuzzle Ġvalues ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpuzzle Ġ= Ġmatch Result . group Values [ 1 ]. to IntArray () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsolution Ġ= Ġmatch Result . group Values [ 2 ]. to IntArray () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAssertions . assertEquals ( 8 1 , Ġpuzzle . size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAssertions . assertEquals ( 8 1 , Ġsolution . size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess ( pu zzle , Ġsolution ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ forEach Line ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ċ } Ċ private Ġval Ġs udoku Pattern Ġ= Ġ""" ^ ([\ d . ]{ 8 1 }), (\ d { 8 1 }). *$ """. to Regex () Ċ Ċ fun Ġtest Performance ( test Set : ĠString , Ġpuzzle : ĠInt Array , Ġsolve : Ġ( pu zzle : ĠInt Array ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠ Ġval Ġl Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠ Ġsolve ( pu zzle ) ĊĠĠĠ Ġval Ġtime Ġ= ĠSystem . currentTimeMillis () Ġ- Ġl ĊĠĠĠ Ġval Ġp uzz les Per Sec Ġ= Ġ 1 0 0 0 F . div ( time ) ĊĠĠĠ Ġprintln ("$ test Set Ġtook : Ġ$ time Ġms , Ġp uzz les / sec : Ġ${ pu zz les Per Sec . two Decimal s () }") Ċ } Ċ Ċ fun Ġtest Performance ( test Set : ĠString , Ġfilename : ĠString , Ġlimit : ĠInt Ġ= ĠInt . MAX _ VALUE , Ġsolve : Ġ( pu zzle : ĠInt Array ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠ Ġvar Ġcount Ġ= Ġ 0 ĊĠĠĠ Ġvar Ġtotal Time Ġ= Ġ 0 L ĊĠĠĠ Ġget P uzz les ( filename , Ġlimit ) Ġ{ Ġpuzzle , Ġ_ Ġ-> ĊĠĠĠĠĠĠĠ Ġcount ++ ĊĠĠĠĠĠĠĠ Ġval Ġl Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠĠĠĠĠ Ġsolve ( pu zzle ) ĊĠĠĠĠĠĠĠ Ġtotal Time Ġ+= ĠSystem . currentTimeMillis () Ġ- Ġl ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġaverage Ġ= Ġtotal Time . toFloat (). div ( count ) ĊĠĠĠ Ġval Ġp uzz les Per Sec Ġ= Ġ 1 0 0 0 F . div ( average ) ĊĠĠĠ Ġprintln ("$ filename Ġ- Ġ$ test Set Ġtook : Ġ$ total Time Ġms , Ġaverage : Ġ${ average . two Decimal s ()} Ġms , Ġp uzz les / sec : Ġ${ pu zz les Per Sec . two Decimal s () }") Ċ } Ċ Ċ private Ġval Ġdf Ġ= ĠDecimal Format (" 0 . 0 0 ") Ċ fun ĠFloat . two Decimal s (): ĠString Ġ= Ġdf . format ( this ) Ċ