24
Sudoku Solver Math Research Project By Maansey Rishi

Maansey QED 2015 Sudoku Solver - Math Circles of Chicago€¦ · Each Sudoku puzzle has a unique solution. The smallest number of starting clues a Sudoku puzzle can contain is 17,

  • Upload
    others

  • View
    9

  • Download
    1

Embed Size (px)

Citation preview

Sudoku Solver Math Research Project

By Maansey Rishi

Abstract

ASudokupuzzleisalogic-basednumberplacementpuzzle.Theobjectiveistofilla9by9gridwiththedigits1-9suchthateachcolumn,eachrow,andeachofthenine3by3sub-gridsthatcomposethegridcontainseachnumberonlyonce.EachSudokupuzzlehasauniquesolution.ThesmallestnumberofstartingcluesaSudokupuzzlecancontainis17,andthereareexactly6,670,903,752,021,072,936,960possiblesolutionstoSudoku.ThegoalofmymathresearchprojectwastomakeacomputerprogramthatefficientlysolvestheseSudokupuzzles.Mycomputerprogramsolvesthesepuzzlesbylogicallygoingthroughpossiblesolutionsandeliminatingchoicessequentiallyuntilitreachesasolution.ThisessaywillexplainthecomputerprogramIhavemadeandthereasoningbehindit.

Introduction

WhenIfirststartedridingairplanesInoticedthatseveralofthepassengerswerealwaysengrossedinthebacksectionofthenewspaper.Theywerealwaysstaringatagrid-likefigurewithrandomnumbersscatteredalloverit.IlaterfoundthatthenameofthispuzzlewasSudokubutIstilldidn’tunderstandwhypeoplespentsomuchtimesittingintheirseatslookingsopuzzled.WhenIfoundanoldSudokupuzzlebookinanolddrawerinmyhouse,Idecidedtogettothebottomofthismysterypuzzle.Idecidedtostartwithaneasierpuzzle,andbeforeIknewitIwasfillingoutnumbersintothegridlaidoutinfrontofme.IpickedthenumbersIbelievedtomakethemostsense,whilecloselyfollowingtherulesgiventome.AsIcontinuedIrealizedmostofmyguessescontradictedmyotherguessesasIgotfurtherintothepuzzle.AftertenminutesIgaveup,andmylifecontinuedasifnothinghadeverhappened.

Acoupleyearslater,IwasassignedamathresearchprojectandIwastoldthatIcouldpickanytopicinmaththatinterestedme.Ittookmeawhileformetothinkofsomething,butIfinallyrecalledmynine-year-oldselfgivingupontheSudokupuzzleinmybasement.Ithenrealizedthatthiswouldbeaninterestingdirectionformetotakeformymathproject.AsIresearchedmoreaboutSudokuIlearnedtherulesandsomeveryinterestingfunfacts:

ThewordSudokuisshortfor“Su-fiwadokushinnikagiru”whichmeans“thenumbersmustbesingle”.TherootsoftheSudokupuzzlecomefromSwitzerlandwhereLeonhardEulercreatedLatinsquareswhichisverysimilartoSudokupuzzles.However,thefirstrealSudokuwaspublishedin1979andwasinventedbyHowardGarns,anAmericanarchitect.

ASudokupuzzleconsistsof81cellswhicharedividedintoninecolumns,rows,and3by3minigrids.TheobjectiveofSudokuistofillthe9by9gridwiththedigits1-9suchthateachcolumn,eachrow,andeachofthenine3by3sub-gridsthatcomposethegridcontainseachnumberonlyonce.EachSudokupuzzlehasauniquesolution.Mathematicianshavefoundthatthesmallestnumberofstartingcluesapuzzlecancontainis17,andthereareexactly6,670,903,752,021,072,936,960(About6.5Sextillion)possiblesolutionstoSudoku.

Aftermoreresearch,IdecidedtopursuetheproblemofSudokupuzzlesformymathresearchproject.Ialsodeterminedthatmynew-foundknowledgeofcomputersciencewouldbeagreatwaytoputmyalgorithmtothetest.

ThegoalofmymathresearchprojectwastomakeacomputerprogramthatefficientlysolvesSudokupuzzles.Mycomputerprogramsolvesthesepuzzlesbyeliminatinganswers,andcheckingeachspotonthegridforuniquesolutions.MycomputerprogramisabletosolvethemajorityofSudokupuzzles.

ThisessaywillexplainthecomputerprogramIhavemadeandthereasoningbehindit.Ihavealsomadeseveralflowchartswhichexplainandsimplifymyverycomplicatedcomputercode.EachprogramincludesasimpleexplanationwhichoutlinestheflowchartinsimpleEnglish.

RulesofSudoku

2 8 4 6

6 9 5

7 4 9 2

3 4 7

3 5

4 6 9

1 9 7 4

8 2

5 6 8 1

TheobjectiveofSudokuistofilla9by9gridwiththedigits1-9suchthateachcolumn,eachrow,andeachofthenine3by3sub-gridsthatcomposethegridcontainseachnumberonlyonce.EachSudokupuzzlehasauniquesolution.

ConceptBehindAlgorithmusedintheComputerProgram

ForthesenextcoupleofpagestheconceptbehindthecomputerprogramImadewillbeexplained.

NextFewSteps

1. Thecomputersystematicallyrunsthroughthestepspreviouslyshownforeachoftheemptyindexes.

2. Itfillsintheindexeswithonlyonepossiblechoice.3. Thecomputerrepeatedlyrunsthroughthesestepsuntiltherearenomore

changeslefttobemade.4. Sometimes,thesestepsaloneareenoughtosolveaSudokupuzzle,butthe

laststepisoftenneeded.5. Sinceeachnumber(1-9)mustappearexactlyonceineachrow,column,and

mini-grid,ifoneoftheguessesofanemptyindexdoesnotappearasaguessforanyotherindexesinthesamerow/column/mini-gridthismeansthattheguesshastobethenumberthattakestheplaceoftheindexbecauseifnootherindexcanholdthatnumberinthesamerow/column/mini-gridtherehastobeatleastoneindexthatdoes.

Arrays

JavaArraysaredatastructurescontainingobjectsofthesametype.Thearrayscanbeone,two,orthreedimensional.Mycomputerprogramgeneratesa9by9by9threedimensionalarraytomimicthe9by9by9matrixdescribedpreviously.ItisimportanttounderstandarraysbeforeunderstandingtheflowchartsthatIhavemade.

DescriptionoftheActualComputerCodeMainProgramOverview:solvePuzzle ThecomputerfirstsetsupthewindowwiththeSudokugrid.ThecomputerthenaskstheusertotypeinnumbersintothegridwhicharepartofaSudokupuzzlethattheuserwantsthecomputertosolve.

Thisgridismovedintoa3DarraycalledpuzzleArray,andallofthespotsnotfilledoutbytheuseraregivenavalueofzeroandareputintheseconddimensionofthearray.Thethirddimensionofthearraywilllaterbeusedtostorethecomputer’sguessesofpossiblenumbersthatcouldfitintheSudokugrid.

Tosolvethepuzzle,thecomputerusesthehelpofaprogramcalledsolvePuzzlewhichhasseveralsub-programsthathelpsolvethepuzzletheusertypedintopuzzleArray.

solvePuzzlefirsttakesinpuzzleArrayandgivesitthreedimensions,9by9by9.ThefirsttwodimensionsrepresentthenumbersintheSudokupuzzlethattheuserwilleventuallysee,andthethirddimensionbehindtheseconddimensionwillconsistofthecomputer’sguessesofpossiblenumbersthatcouldfitintoitscorrespondingspotintheseconddimension.

solvePuzzleconsistsofseveralsub-programs,oneofwhichisaBooleancalledcheckArray.Booleansareprogramsthatreturnatrueorfalsevalue.Inthiscase,checkArrayisreturnstrueifallofthespotsintheseconddimensionarefilledinthearray,butifoneoftheindexesequalzerothencheckArraywillreturnfalse.solvePuzzlewillonlycontinueifcheckArrayreturnsfalse,becausethatmeanstheSudokupuzzleisnotcompletedyet.

ThecomputerthenrunsthroughallofthenumbersintheseconddimensionofpuzzleArray.IfoneoftheindexesequalzerothenthecomputercallsonBooleancheckNumberwhichtakesinpuzzleArray,anindexinpuzzleArray,andanumberx(1-9).checkNumberwillcheckifxisapossiblenumberthatcouldrepresenttheindexintheSudokupuzzle.Ifitis,checkNumberwillreturntrueandxwillbestoredasaguessinthethirddimension.checkNumberrunsthrougheachindexwithavalueofzerointheseconddimension,andchecksthenumbers1-9forallofthem.

Afterthecomputerrunsthroughalloftheindexes,solvePuzzlegivespuzzleArraytoanothersub-programcalledfillIn.fillInrunsthroughallofthespotsinpuzzleArraythathaveazerointheseconddimension,andifithasonlyonenumberthatthecomputerplacedinthethirddimensionasaguessthenthatguesswilltaketheplaceofthezerointheseconddimension.

Next,thecomputerwillclearoutallofthenumbersinthethirddimension,andrunthroughcheckNumberandfillInalloveragainuntiltherearenomorechangeslefttobemade.Oncethishappens,thecomputerrunsthroughallofthenumbersinthepuzzleArray,andifoneoftheindexesequalzerothenthecomputercallsontheBooleancheckNumber2.checkNumber2isprogrammedtotakeanindexinpuzzleArrayandoneofitspossiblenumbers/guessesinthethirddimension,andthencheckifitisthecorrectnumberbyrunningthroughalloftheotherguessesinthethirddimensionofthesamerow,column,andminigridoftheindex.Iftheguessisnotequaltoanotherguessinthesamerow,column,orminigridthenthatguesswilltaketheplaceoftheindexintheseconddimension.Forexample,ifindex[2][4][0]hasaguessof2,andnootherindexinitsrow,column,orminigridhasa

possibilityofbeing2thenindex[2][4][0]mustequal2becausetherehastobeatleastoneofeachnumber(1-9)ineachrow,column,andminigridinSudokupuzzles.

OncethecomputerrunscheckNumber2onalloftheindexesintheseconddimensionequaltozero,solvePuzzleclearsalloftheindexesinthethirddimensionandsetsthemtozero.ThensolvePuzzlerunscheckNumberandfillInonpuzzleArray,andthenrunsthroughcheckNumber2againifneeded.Thiswholeprocess,willberepeatedasmanytimesasittakestosolvepuzzleArray.

Finally,whencheckArrayreturnstrue,andallofthenumbersintheseconddimensionarefilledin,thenthemainprogramprintsthenumbersoutintothegridthattheuserisabletoseeonthecomputerscreen.

solvePuzzletakesinpuzzleArray

!checkArray(puzzleArray) ComputerrunscheckArrayon

puzzleArray.The!infrontofcheckArraytellsthecomputeronlytocontinueifcheckArray

returnsfalse.

YES

inti=0intj=0

j<9

intk=1 k<9

puzzleArray[i][j][k]=0

k++

i++

j++

ENDsolvePuzzleends,andreturnsthe

completedpuzzleArraybacktothemainprogramwhichprintsoutthepuzzle

YES

YES

NO

inta=0

a<9intb=0

intcounter=1

puzzleArray[a][b][0]=0

intx=1

checkNumber(puzzleArray,x,a,b)puzzleArray[a][b][counter]=x

counter++YES

x<9x++

NONO

b++

a++

fillIn(puzzleArray)=0 intreally=0 inta=0

a<9

really=0

ENDThecomputerwasnotableto

completetheSudokupuzzle,butprintsoutasmanynumbersasit

can.NOTE:ThisisreallyRARE!

YES

b=0

b<9

puzzleArray[a][b][0]=0intx=1

x<9

really++

checkNumber2(puzzleArray,puzzleArray[a][b[x],a,b)

x++ NO

a++

b++

puzzleArray[a][b][0]=puzzleArray[a][b][x]

puzzleArray[a][b][x]!=0

NO

i<9

NO

YES

NO

YESNO

NOYES

b<9

NO

YES

YES

YES

NO

NO

YES

YES

NO

YESNO

YESYES

YES

NO

NO

NO

solvePuzzleProgram

checkArrayExplanation checkArrayisasub-programofthesolvePuzzleprogram.solvePuzzleusescheckArraytofindoutifthecomputerisdonesolvingthepuzzleoriftherearestillmorepartsoftheprogramlefttobefilled.checkArrayreturnsaBooleanattheendoftheprogram.ABooleanhasatrueorfalsevalue.IfcheckArrayreturnstrue,itmeansthatallofthespotsoftheSudokupuzzlearefilledintheseconddimension.However,ifcheckArrayreturnsfalse,itmeansthatthecomputerstillhasemptyindexes. IncheckArraythecomputerrunsthroughalloftheindexesintheseconddimensionandchecksifanyofthemhaveazerointheirspot.Ifevenonezeroisdetected,thecomputerreturnsfalse.However,ifthecomputerisabletorunthroughthewholeprogramwithoutfindinganyzeros,checkArrayreturnstrue.

checkArrayisasub-program

whichworkswithpuzzleArray.booleanisItDone=true

inti=0

i<9

YES

intj=0

j<9

YES

puzzleArray[i][j][0]=0

YES

ENDTheprogramwillautomatically

returnfalse.

j++

NO

i++

NO

ENDcheckArrayreturns

true(valueofbooleanisItDone)

NO

checkArrayProgram

checkNumberExplanation BooleancheckNumbertakesinoneindexinpuzzleArrayandaninteger.ThegoaloftheprogramistodeterminewhethertheintegerisapossiblecandidatefortheemptyindexinpuzzleArray.Thecomputerdoesthisbyrunningthroughalloftheothernumbersinthesamecolumn,row,andmini-gridintheseconddimensionofpuzzleArrayoftheindexgiven.Iftheintegergivenisalreadypresentinthesamecolumn,row,ormini-gridthencheckNumberreturnsfalse,butifthecomputerdoesnotdetectthesameintegerinthecolumn,row,ormini-gridoftheindexthentheprogramwillreturntrue.

Sub-programcheckNumbertakesinpuzzleArray,intx,int

a,andintb booleancheckNum=true

inti=0

i<9YES

puzzleArray[a][i][0]=xOR

puzzleArray[i][b][0]=x

YES

ENDcheckNumberautomatically

returnsfalse

NOintv=0 intc=3

intk=0v<=9

v=v+3c=3

c<=9

a<vandrow<v

k=v

c=c+3

YES

k=v

YES

NO YES

NO

YES

NO

ints=c-3

s<c

s++

intt=v-3

i++

t<v

t++

YES

NO

YES

ENDcheckNumberreturnstrue(valueofBoolean

checkNum)

YES

NO

ENDcheckNumberautomatically

returnsfalse

puzzleArray[t][s][0]=0

NO

NO

checkNumberProgram

fillInExplanation Thegoalofsub-programfillInistofillinasmanyintegersasitcanintotheseconddimensionofpuzzleArray.fillInfirstrunsthroughalloftheindexesintheseconddimension.Ifoneoftheindexeshasonlyoneguessinthethethirddimension,thenthatguesstakestheplaceofthezerointhatindex.

Thecomputeralsokeepstrackofhowmanytimesazerointheseconddimensionisreplacedbyaguess.IfnochangestopuzzleArrayaremadeafterfillInthenthecomputerwilldecidetomoveontothenextstepinvolvinganothermethodtofillinindexesinpuzzleArray.ButifafewchangesaremadebyfillIninpuzzleArraythenthecomputerwillredocheckNumberandfillInbecausetheremaybemorechangeslefttobemadeusingthismethod.

sub-program/functionfillInusespuzzleArrayandreturns

anintegerw.

intw=0

inti=0

i<9

YES

intj=0

j<9

YES

puzzleArray[i][j][0]=0

YES

j++

i++

NO

ENDfillInreturnsthevalueofw

puzzleArray[i][j][0]=puzzleArray[i][j][1]

w++and

puzzleArray[i][j][2]=0

NO

NO

fillInProgram

checkNumber2Explanation

BooleancheckNumber2issimilartocheckNumberbuthasadifferentmethodinreturningatrueorfalsevalue.checkNumber2alsotakesinpuzzleArray,oneindexintheseconddimensionofpuzzleArray,andaguessofthesameindexinthethirddimension.checkNumber2willtesttoseeifthisguessistheonlypossiblenumbertoreplacethezerointheindexoriginallygiventotheprogram.

checkNumber2isprogrammedtocheckiftheintegeristhecorrectnumberbyrunningthroughalloftheotherguessesinthethirddimensionofthesamerow,column,andminigridoftheindex.Iftheguessisnotequaltoanotherguessinthesamerow,column,orminigridthenthatguesswilltaketheplaceoftheindexintheseconddimension.Forexample,ifindex[2][4][0]hasaguessof2,andnootherindexinitsrow,column,orminigridhasapossibilityofbeing2thenindex[2][4][0]mustequal2becausetherehastobeatleastoneofeachnumber(1-9)ineachrow,column,andminigridinSudokupuzzles.

Sub-programcheckNumber2takesinpuzzleArray,intx,inta,andintb

booleancheckNum=false

inti=0i<9

ENDcheckNumber

automaticallyreturnstrue

intv=0

intc=3

intk=0

v<=9v=v+3

c=3

c<=9

a<vandrow<v

k=v

c=c+3

YES

k=vYES

NO

NO

YES

NOY

ES N

O

ints=c-3

s<c

s++

intt=v-3

i++

NO

t<v

t++

YES

NO

YES

ENDcheckNumberreturnsfalse(valueofBoolean

checkNum)

puzzleArray[t][s][m]=x

intm=0 intn=0

puzzleArray[a][i][j]!=xm=80 intj=0j<9

j++

m++

puzzleArray[i][b][j]!=x

n++

n=80

ENDcheckNumber

automaticallyreturnstrue

YES

intg=0

m<9

intm=1

g++g=80

ENDcheckNumber

automaticallyreturnstrue

NO

m++

YES

NO

YES

YESNO

NO

YES

NO

YES

NO

NO

YES

YES

YES

NO

m++

YES

checkNumber2Program

NewDirectionsandQuestionsforFurtherResearch EventhoughtheSudokuSolversolvesthemajorityofSudokupuzzles,itdoesnotsolveeverysingleone.Mycomputerprogramdoesnotinvolvetheguessingofnumbers,butinsteadthecomputersolvesthepuzzlebyeliminatingpossiblenumbersforeachspotintheSudokugridandthenfindingspotswithonlyonepossiblesolutionuntilallofthespotsinthepuzzlearefilled.EventhoughthisisanefficientandinterestingwaytosolveaSudokupuzzleitdoesnotguaranteeasolution.Therefore,ifIeverhaveachancetofurtherimprovemyprojectandmakemyprogrammoreefficientIwilldefinitelymakesureIaddaguessingcomponentinmyprogramsothatthecomputercansolveallofpuzzlesandnotjustthemajority.

Conclusion TheSudokuSolverisoneofthemanycomputerprogramsthatinvolvestheuseofmathematics.EventhoughtheoriginalalgorithmImadeseemssimple,thecomputerprogrammingittakestomakeithappenisverycomplicatedandthecodeisveryintricatelydesigned.Myprogramalsousesseveralmathematicalconceptssuchasthreedimensionalarrays,Booleans,severalintegers,for-loops,while-loops,andifstatements.

Eventhoughitwaschallengingtomakeallthesmallpiecesfinallyfittogetherbecauseincomputerprogrammingthesmallestmistakecouldtakehourstofindandfix,Ilearnedmanythingsfromtheexperience.FewofthemanythingsIlearnedincludehowtomakeseveralprogramsworktogethertomakeonefinalproduct,howtotakeacomplexproblem/ideaandmakesenseofit,andmostimportantlyIlearnedthatIwanttofurtherstudyandimprovemyknowledgeofcomputerScience.

ComputerCodeimport javax.swing.JFrame; public class solvePuzzle { public static int[][][] puzzleArray = new int[9][9][9]; public static void main(String[] args) { myWindow window = new myWindow("Soduku Solver"); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void solve(){ while (!checkArray(puzzleArray)) { for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { for (int k = 1; k < 9; k++) { puzzleArray[i][j][k] = 0; } } } for (int a = 0; a < 9; a++) { for (int b = 0; b < 9; b++) { int counter = 1; if (puzzleArray[a][b][0] == 0) { for (int x = 9; x >= 1; x--) { if (checkNumber(puzzleArray, x, a, b)) { puzzleArray[a][b][counter] = x; counter++; } } } } } if (fillIn(puzzleArray) == 0) { int really = 0; for (int a = 0; a < 9; a++) { for (int b = 0; b < 9; b++) { if (puzzleArray[a][b][0] == 0) { for (int x = 1; x < 9; x++) { if (puzzleArray[a][b][x] != 0) { if (checkNumber2(puzzleArray, puzzleArray[a][b][x], a, b)) { puzzleArray[a][b][0] = puzzleArray[a][b][x]; really++; } } } }

} } if (really == 0) { break; } } } } public static boolean checkNumber2(int[][][] array, int x, int column, int row) { boolean checkNum = false; int countcolumn = 0; int countrow = 0; for (int i = 0; i < 9; i++) { for(int j = 0; j < 9; j++) { if (array[column][i][j] != x) { countcolumn++; if(countcolumn == 80) { return true; } } if (array[i][row][j] != x) { countrow++; if(countrow == 80) { return true; } } } } int v = 0; int c = 3; int k = 0; int countgrid = 0; while (v <= 9) { v += 3; c = 3; while (c <= 9) { if (column < v && row < c) { k = v; break; } c += 3; } if (k == v) break; } for (int s = c - 3; s < c; s++) { for (int t = v - 3; t < v; t++) { for(int m = 1; m < 9; m++) { if (array[t][s][m] == x) { countgrid++;

if(countgrid == 80) return (true); } } } } return (checkNum); } public static boolean checkArray(int[][][] puzzleArray) { boolean isItDone = true; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (puzzleArray[i][j][0] == 0) { return (false); } } } return (isItDone); } public static boolean checkNumber(int[][][] array, int a, int column, int row) { boolean checkNum = true; for (int i = 0; i < 9; i++) { if (array[column][i][0] == a) { return (false); } if (array[i][row][0] == a) { return (false); } } int v = 0; int c = 3; int k = 0; while (v <= 9) { v += 3; c = 3; while (c <= 9) { if (column < v && row < c) { k = v; break; } c += 3; } if (k == v) break; } for (int s = c - 3; s < c; s++) { for (int t = v - 3; t < v; t++) {

if (array[t][s][0] == a) { return (false); } } } return (checkNum); } public static int fillIn(int[][][] array) { int x = 0; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (array[i][j][0] == 0 && array[i][j][2] == 0) { array[i][j][0] = array[i][j][1]; x++; } } } return (x); } }