# Sudoku Solver Updated V2.1

## Recommended Posts

This solver can solve any sudoku as long as it is possible. Input the numbers and then click solve. It uses 2 simple solving methods and then a brute force method. Comments and suggestions are welcome.

V2: Can now recognize pairs. For a descritption of pairs

Is faster than the first version for most puzzles.

V2.1: now has naked pairs for cells as well

Now has a updated Gui and a clear button Thx to Piano_man for the gui

CODE

#include <GuiConstants.au3>

Global \$constant[10][10] ;user numbers [row-1][column]

Global \$input[10][10] ;input boxes [row-1][column]

Global \$1

Global \$2

Global \$3

Global \$r

Global \$c

Global \$possibilities[10][10][10] ;[row][column][number] 1 = applicable 0 or "" = not

Global \$change ;change in tests

HotKeySet("{esc}", "_exit")

\$Form1_1 = GUICreate("solver", 610, 374, 189, 173)

\$Button1 = GUICtrlCreateButton("Solve", 260, 338, 75, 25, 0)

\$Button2 = GUICtrlCreateButton("Clear", 32, 336, 75, 25, 0)

GUISetFont(11)

For \$i = 0 To 8

If \$i = 3 Or \$i = 6 Or \$i = 9 Then

EndIf

For \$j = 1 To 9

\$x = 56 * \$j - 60

\$y = 32 * (\$i + 1) - 10

If Mod(\$j - 1, 3) = 0 Then

EndIf

\$input[\$i][\$j] = GUICtrlCreateInput("", \$x + \$XaddAmmount, \$y + \$YaddAmmount, 36, 23, \$ES_CENTER)

Next

Next

GUISetState(@SW_SHOW)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;_sigletoncolumn cell check problem

While 1

\$nMsg = GUIGetMsg()

Switch \$nMsg

Case - 3

Exit

Case \$Button1

_record()

_allpossible()

_testpossible()

_solver2()

MsgBox(0, "Solved", "Puzzle Solved")

Case \$Button2

_clear()

EndSwitch

WEnd

Func _record()

For \$i = 1 To 9

For \$j = 1 To 9

Next

Next

EndFunc ;==>_record

Func _rowcheck(\$row, \$column)

For \$i = 1 To 9

If \$i <> \$column Then

If StringCompare(GUICtrlRead(\$input[\$row - 1][\$column]), GUICtrlRead(\$input[\$row - 1][\$i])) = 0 Then Return 1

EndIf

Next

EndFunc ;==>_rowcheck

Func _columncheck(\$row, \$column)

For \$i = 1 To 9

If \$i <> \$row Then

If StringCompare(GUICtrlRead(\$input[\$row - 1][\$column]), GUICtrlRead(\$input[\$i - 1][\$column])) = 0 Then Return 1

EndIf

Next

EndFunc ;==>_columncheck

Func _brutetest()

For \$r = 1 To 9 ;row

For \$c = 1 To 9 ;column

If \$constant[\$r][\$c] = "" Then

For \$n = 1 To 9 ;number to test

GUICtrlSetData(\$input[\$r - 1][\$c], \$n)

\$1 = _rowcheck(\$r, \$c)

\$2 = _columncheck(\$r, \$c)

\$3 = _cellcheck(\$r, \$c)

If \$1 = 0 And \$2 = 0 And \$3 = 0 Then ExitLoop

Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Back track

If \$1 = 1 Or \$2 = 1 Or \$3 = 1 Then

While 1

GUICtrlSetData(\$input[\$r - 1][\$c], \$constant[\$r][\$c])

\$c = \$c - 1

If \$c < 1 Then

\$c = 9

\$r = \$r - 1

EndIf

If \$constant[\$r][\$c] <> "" Then

Else

While 1

If \$back = "" Then \$back = 0

\$back = \$back + 1

If \$back = 10 Then

ExitLoop

EndIf

GUICtrlSetData(\$input[\$r - 1][\$c], \$back)

\$1 = _rowcheck(\$r, \$c)

\$2 = _columncheck(\$r, \$c)

\$3 = _cellcheck(\$r, \$c)

If \$1 = 0 And \$2 = 0 And \$3 = 0 Then ExitLoop (2)

WEnd

EndIf

WEnd

EndIf

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

EndIf

Next

Next

EndFunc ;==>_brutetest

Func _cellcheck(\$row, \$column)

\$row = \$row - 1

\$cellpos_row = Floor(\$row / 3) ; If \$row= 0, 1, 2 then this=0, if \$row= 3,4,5 then this=1, if \$row= 6,7,8 then this=2

\$cellpos_col = Floor((\$column - 1) / 3) ; If \$column= 1,2,3 then this=0, etc..

For \$i = 3 * \$cellpos_row To 3 * \$cellpos_row + 2 ; (0 to 2) or (3 to 5) or (6 to 8)

For \$j = 3 * \$cellpos_col + 1 To 3 * \$cellpos_col + 3 ; (1 to 3) or (4 to 6) or (7 to 9)

If \$i <> \$row Or \$j <> \$column Then

EndIf

Next

Next

EndFunc ;==>_cellcheck

Func _randomcheck()

While 1

For \$t = 0 To 8

For \$l = 1 To 9

If \$constant[\$t][\$l] = "" Then

GUICtrlSetData(\$input[\$t][\$l], Random(1, 9, 1))

EndIf

Next

Next

For \$q = 1 To 9

For \$z = 1 To 9

If _rowcheck(\$q, \$z) = 1 Or _columncheck(\$q, \$z) = 1 Or _cellcheck(\$q, \$z) = 1 Then ExitLoop (2)

Next

Next

If _rowcheck(\$q, \$z) = 0 And _columncheck(\$q, \$z) = 0 And _cellcheck(\$q, \$z) = 0 Then ExitLoop (1)

WEnd

EndFunc ;==>_randomcheck

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; using possibilites array

Func _possible(\$row, \$column) ;finds possible entries for a given box

For \$k = 1 To 9 ;numbers

If \$constant[\$row][\$column] = "" Then

GUICtrlSetData(\$input[\$row - 1][\$column], \$k)

If _rowcheck(\$row, \$column) = 0 And _columncheck(\$row, \$column) = 0 And _cellcheck(\$row, \$column) = 0 Then

\$possibilities[\$row][\$column][\$k] = 1

Else

\$possibilities[\$row][\$column][\$k] = 0

EndIf

GUICtrlSetData(\$input[\$row - 1][\$column], "")

EndIf

Next

EndFunc ;==>_possible

Func _singlepossible(\$row, \$column)

Dim \$count

\$count = 0

If \$constant[\$row][\$column] = "" Then

For \$d = 1 To 9

If \$possibilities[\$row][\$column][\$d] = 1 Then

\$count = \$count + 1

EndIf

Next

If \$count = 1 Then

Return 1

EndIf

EndIf

EndFunc ;==>_singlepossible

Func _singletoncolumn(\$column)

Dim \$count

Dim \$row

For \$d = 1 To 9 ;number

\$count = 0

For \$a = 1 To 9 ;row

If \$constant[\$a][\$column] = "" Then

If \$possibilities[\$a][\$column][\$d] = 1 Then

\$count = \$count + 1

\$row = \$a

EndIf

EndIf

Next

If \$count = 1 Then

Return \$row

ExitLoop

EndIf

Next

EndFunc ;==>_singletoncolumn

Func _singletonrow(\$row)

Dim \$count

Dim \$column

For \$d = 1 To 9 ;number

\$count = 0

For \$a = 1 To 9 ;column

If \$constant[\$row][\$a] = "" Then

If \$possibilities[\$row][\$a][\$d] = 1 Then

\$count = \$count + 1

\$column = \$a

EndIf

EndIf

Next

If \$count = 1 Then

Return \$column

ExitLoop

EndIf

Next

EndFunc ;==>_singletonrow

Func _possiblerow(\$row1) ;updates possibilites for row

For \$p = 1 To 9 ;column

If \$constant[\$row1][\$p] = "" Then

_possible(\$row1, \$p)

EndIf

Next

EndFunc ;==>_possiblerow

Func _possiblecolumn(\$column1) ; updates possibilities for column

For \$p = 1 To 9 ;row

If \$constant[\$p][\$column1] = "" Then

_possible(\$p, \$column1)

EndIf

Next

EndFunc ;==>_possiblecolumn

Func _possiblecell(\$row1, \$column1) ;updates all possibilities for a cell containging the given box

If \$constant[\$row1][\$column1] = "" Then

\$row1 = \$row1 - 1

\$cellpos_row = Floor(\$row1 / 3) ; If \$row= 0, 1, 2 then this=0, if \$row= 3,4,5 then this=1, if \$row= 6,7,8 then this=2

\$cellpos_col = Floor((\$column1 - 1) / 3) ; If \$column= 1,2,3 then this=0, etc..

For \$q = 3 * \$cellpos_row To 3 * \$cellpos_row + 3 ; (0 to 2) or (3 to 5) or (6 to 8)

For \$j = 3 * \$cellpos_col + 1 To 3 * \$cellpos_col + 3 ; (1 to 3) or (4 to 6) or (7 to 9)

If \$q <> \$row1 Or \$j <> \$column1 Then

_possible(\$q, \$j)

EndIf

Next

Next

EndIf

EndFunc ;==>_possiblecell

Func _allpossible()

For \$i = 1 To 9 ;checks all possibles

For \$y = 1 To 9

_possible(\$i, \$y)

Next

Next

EndFunc ;==>_allpossible

Func _testpossible()

While 1

\$change = 0

For \$i = 1 To 9

For \$y = 1 To 9

If _singlepossible(\$i, \$y) = 1 Then

\$change = 1

_possiblerow(\$i)

_possiblecolumn(\$y)

_possiblecell(\$i, \$y)

_nakedpaircolumn(\$y)

_nakedpairrow(\$i)

_nakedpaircell (\$i, \$y)

EndIf

Next

Next

For \$i = 1 To 9

\$rowtest = _singletoncolumn(\$i)

If \$rowtest <> 0 And \$rowtest <> "" Then

\$change = 1

_possiblecolumn(\$i)

_possiblerow(\$rowtest)

_possiblecell(\$rowtest, \$i)

_nakedpairrow(\$rowtest)

_nakedpaircolumn(\$i)

_nakedpaircell (\$rowtest, \$i)

EndIf

Next

For \$i = 1 To 9

\$columntest = _singletonrow(\$i)

If \$columntest <> 0 And \$columntest <> "" Then

\$change = 1

_possiblerow(\$i)

_possiblecolumn(\$columntest)

_possiblecell(\$i, \$columntest)

_nakedpairrow(\$i)

_nakedpaircolumn(\$columntest)

_nakedpaircell (\$i, \$columntest)

EndIf

Next

If \$change = 0 Then ExitLoop

WEnd

EndFunc ;==>_testpossible

Func _solver2()

For \$i = 1 To 9

_nakedpaircolumn(\$i)

_nakedpairrow(\$i)

Next

For \$i = 1 To 9

For \$y = 1 to 9

_nakedpaircell (\$i, \$y)

Next

Next

_testpossible()

EndFunc ;==>_solver2

Func _nakedpaircolumn(\$column)

Dim \$count ;[number]

Dim \$row[3]

Dim \$match

For \$l = 1 To 9 ;row

\$count = 0

For \$d = 1 To 9 ;number

If \$possibilities[\$l][\$column][\$d] = 1 Then \$count = \$count + 1

Next

If \$count = 2 Then

\$row[1] = \$l

For \$m = \$row[1] + 1 To 9 ;row

\$match = 0

For \$p = 1 To 9 ;number

If \$possibilities[\$m][\$column][\$p] <> \$possibilities[\$row[1]][\$column][\$p] Then \$match = \$match + 1

Next

If \$match = 0 Then

\$row[2] = \$m

ExitLoop (2)

EndIf

Next

EndIf

Next

If \$row[1] <> "" And \$row[2] <> "" Then

For \$d = 1 To 9 ;numbers removed from others

If \$possibilities[\$row[1]][\$column][\$d] = 1 Then

For \$l = 1 To 9 ;row

If \$l <> \$row[1] And \$l <> \$row[2] Then \$possibilities[\$l][\$column][\$d] = 0

Next

EndIf

Next

Return 1

EndIf

EndFunc ;==>_nakedpaircolumn

Func _nakedpairrow(\$row)

Dim \$count ;[number]

Dim \$column[3]

Dim \$match

For \$l = 1 To 9 ;column

\$count = 0

For \$d = 1 To 9 ;number

If \$possibilities[\$row][\$l][\$d] = 1 Then \$count = \$count + 1

Next

If \$count = 2 Then

\$column[1] = \$l

For \$m = \$column[1] + 1 To 9 ;column

\$match = 0

For \$p = 1 To 9 ;number

If \$possibilities[\$row][\$m][\$p] <> \$possibilities[\$row][\$column[1]][\$p] Then \$match = \$match + 1

Next

If \$match = 0 Then

\$column[2] = \$m

ExitLoop (2)

EndIf

Next

EndIf

Next

If \$column[1] <> "" And \$column[2] <> "" Then

For \$d = 1 To 9 ;numbers removed from others

If \$possibilities[\$row][\$column[1]][\$d] = 1 Then

For \$l = 1 To 9 ;column

If \$l <> \$column[1] And \$l <> \$column[2] Then \$possibilities[\$row][\$l][\$d] = 0

Next

EndIf

Next

Return 1

EndIf

EndFunc ;==>_nakedpairrow

Func _nakedpaircell(\$row, \$column)

Dim \$count ;[number]

Dim \$column[3]

Dim \$row[3]

Dim \$match

\$cellpos_row = Floor(\$row / 3) ; If \$row= 0, 1, 2 then this=0, if \$row= 3,4,5 then this=1, if \$row= 6,7,8 then this=2

\$cellpos_col = Floor((\$column - 1) / 3) ; If \$column= 1,2,3 then this=0, etc..

For \$z = 3 * \$cellpos_row To 3 * \$cellpos_row + 2 ; (0 to 2) or (3 to 5) or (6 to 8) row

For \$x = 3 * \$cellpos_col + 1 To 3 * \$cellpos_col + 3 ; (1 to 3) or (4 to 6) or (7 to 9) column

For \$d = 1 To 9 ;number

If \$possibilities[\$z][\$x][\$d] = 1 Then \$count = \$count + 1

Next

If \$count = 2 Then

\$column[1] = \$x

\$row[1] = \$z

\$cellpos_row1 = Floor(\$row / 3) ; If \$row= 0, 1, 2 then this=0, if \$row= 3,4,5 then this=1, if \$row= 6,7,8 then this=2

\$cellpos_col1 = Floor((\$column - 1) / 3) ; If \$column= 1,2,3 then this=0, etc..

For \$u = 3 * \$cellpos_row1 To 3 * \$cellpos_row1 + 2 ; (0 to 2) or (3 to 5) or (6 to 8) row

For \$r = 3 * \$cellpos_col1 + 1 To 3 * \$cellpos_col1 + 3 ; (1 to 3) or (4 to 6) or (7 to 9) column

\$match = 0

For \$p = 1 To 9 ;number

If \$possibilities[\$u][\$r][\$p] <> \$possibilities[\$row[1]][\$column[1]][\$p] Then \$match = \$match + 1

Next

If \$match = 0 Then

\$column[2] = \$r

\$row[2] = \$u

ExitLoop (2)

EndIf

Next

Next

EndIf

Next

Next

If \$column[1] <> "" And \$column[2] <> "" Then

For \$d = 1 To 9 ;numbers removed from others

If \$possibilities[\$row[1]][\$column[1]][\$d] = 1 Then

\$cellpos_row = Floor(\$row / 3) ; If \$row= 0, 1, 2 then this=0, if \$row= 3,4,5 then this=1, if \$row= 6,7,8 then this=2

\$cellpos_col = Floor((\$column - 1) / 3) ; If \$column= 1,2,3 then this=0, etc..

For \$z = 3 * \$cellpos_row To 3 * \$cellpos_row + 2 ; (0 to 2) or (3 to 5) or (6 to 8) row

For \$x = 3 * \$cellpos_col + 1 To 3 * \$cellpos_col + 3 ; (1 to 3) or (4 to 6) or (7 to 9) column

For \$d = 1 To 9 ;number

If \$x <> \$column[1] And \$x <> \$column[2] And \$z <> \$row[1] And \$z <> \$row[2] Then \$possibilities[\$z][\$x][\$d] = 0

Next

Next

Next

EndIf

Next

Return 1

EndIf

EndFunc ;==>_nakedpaircell

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Func _clear()

For \$i = 1 To 9 ;row

For \$j = 1 To 9 ;column

\$constant[\$i][\$j] = ""

GUICtrlSetData(\$input[\$i - 1][\$j], "")

Next

Next

EndFunc ;==>_clear

Func _exit()

Exit

EndFunc ;==>_exit

Edited by sccrstvn93

##### Share on other sites

This solver can solve any sudoku as long as it is possible. Input the numbers and then click solve. It uses 2 simple solving methods and then a brute force method. Comments and suggestions are welcome.

CODE

#include <GUIConstants.au3>

#include <array.au3>

Global \$constant[10][10] ;user numbers [row-1][column]

Global \$input[10][10] ;input boxes [row-1][column]

Global \$1

Global \$2

Global \$3

Global \$r

Global \$c

HotKeySet("{esc}", "_exit")

\$Form1_1 = GUICreate("solver", 633, 374, 189, 173)

\$Button1 = GUICtrlCreateButton("Solve", 264, 336, 75, 25, 0)

For \$i = 0 To 8

For \$j = 1 To 9

\$input[\$i][\$j] = GUICtrlCreateInput("", 56 * \$j, 32 * (\$i + 1), 41, 21)

Next

Next

GUISetState(@SW_SHOW)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;_sigletoncolumn cell check problem

While 1

\$nMsg = GUIGetMsg()

Switch \$nMsg

Case \$GUI_EVENT_CLOSE

Exit

Case \$Button1

_record()

_test ()

EndSwitch

WEnd

Func _test ()

Dim \$change

While 1

While 1

\$change = 0

For \$q = 1 to 9

For \$z = 1 to 9

If \$constant[\$q-1][\$z] = "" Then

If _solver1 (\$q, \$z) = 1 Then \$change = 1

EndIf

Next

Next

If \$change = 0 Then ExitLoop

WEnd

For \$q = 1 to 9

If _Singletonrow (\$q) = 1 then \$change = 1

Next

For \$q = 1 to 9

If _Singletoncolumn(\$q) = 1 Then \$change = 1

Next

If \$change = 0 Then ExitLoop

Wend

_brutetest ()

EndFunc

Func _record()

For \$i = 0 To 9

For \$j = 1 To 9

Next

Next

EndFunc ;==>_record

Func _rowcheck(\$row, \$column)

For \$i = 1 To 9

If \$i <> \$column Then

If StringCompare(GUICtrlRead(\$input[\$row - 1][\$column]), GUICtrlRead(\$input[\$row - 1][\$i])) = 0 Then Return 1

EndIf

Next

EndFunc ;==>_rowcheck

Func _columncheck(\$row, \$column)

For \$i = 1 To 9

If \$i <> \$row Then

If StringCompare(GUICtrlRead(\$input[\$row - 1][\$column]), GUICtrlRead(\$input[\$i - 1][\$column])) = 0 Then Return 1

EndIf

Next

EndFunc ;==>_columncheck

Func _brutetest()

For \$r = 1 To 9 ;row

For \$c = 1 To 9 ;column

If \$constant[\$r - 1][\$c] = "" Then

For \$n = 1 To 9 ;number to test

GUICtrlSetData(\$input[\$r - 1][\$c], \$n)

\$1 = _rowcheck(\$r, \$c)

\$2 = _columncheck(\$r, \$c)

\$3 = _cellcheck(\$r, \$c)

If \$1 = 0 And \$2 = 0 And \$3 = 0 Then ExitLoop

Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Back track

If \$1 = 1 Or \$2 = 1 Or \$3 = 1 Then

While 1

GUICtrlSetData(\$input[\$r - 1][\$c], \$constant[\$r - 1][\$c])

\$c = \$c - 1

If \$c < 1 Then

\$c = 9

\$r = \$r - 1

EndIf

If \$constant[\$r - 1][\$c] <> "" Then

Else

While 1

If \$back = "" Then \$back = 0

\$back = \$back + 1

If \$back = 10 Then

ExitLoop

EndIf

GUICtrlSetData(\$input[\$r - 1][\$c], \$back)

\$1 = _rowcheck(\$r, \$c)

\$2 = _columncheck(\$r, \$c)

\$3 = _cellcheck(\$r, \$c)

If \$1 = 0 And \$2 = 0 And \$3 = 0 Then ExitLoop (2)

WEnd

EndIf

WEnd

EndIf

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

EndIf

Next

Next

EndFunc ;==>_brutetest

Func _cellcheck(\$row, \$column)

\$row = \$row - 1

\$cellpos_row = Floor(\$row/ 3) ; If \$row= 0, 1, 2 then this=0, if \$row= 3,4,5 then this=1, if \$row= 6,7,8 then this=2

\$cellpos_col = Floor((\$column - 1) / 3) ; If \$column= 1,2,3 then this=0, etc..

For \$i = 3 * \$cellpos_row To 3 * \$cellpos_row + 2 ; (0 to 2) or (3 to 5) or (6 to 8)

For \$j = 3 * \$cellpos_col + 1 To 3 * \$cellpos_col + 3 ; (1 to 3) or (4 to 6) or (7 to 9)

If \$i <> \$row Or \$j <> \$column Then

EndIf

Next

Next

EndFunc ;==>_cellcheck

Func _randomcheck ()

While 1

For \$t = 0 to 8

For \$l = 1 to 9

If \$constant[\$t][\$l] = "" then

GUICtrlSetData (\$input[\$t][\$l], Random (1, 9, 1))

EndIf

Next

Next

For \$q = 1 to 9

For \$z = 1 to 9

If _rowcheck(\$q, \$z) = 1 or _columncheck (\$q, \$z) = 1 or _cellcheck (\$q, \$z) = 1 Then ExitLoop (2)

Next

Next

If _rowcheck(\$q, \$z) = 0 and _columncheck (\$q, \$z) = 0 and _cellcheck (\$q, \$z) = 0 Then ExitLoop (1)

WEnd

EndFunc

Func _solver1 (\$row, \$column) ;fills in all single choices

Dim \$count = 0

Dim \$solution

For \$l = 1 to 9 ;number

GUICtrlSetData (\$input[\$row-1][\$column], \$l)

If _rowcheck (\$row, \$column) = 0 and _columncheck (\$row, \$column) = 0 and _cellcheck (\$row, \$column) = 0 Then

\$count = \$count + 1

\$solution = \$l

EndIf

Next

GUICtrlSetData (\$input[\$row-1][\$column], "")

If \$count = 1 Then

GUICtrlSetData (\$input[\$row-1][\$column], \$solution)

\$constant[\$row-1][\$column] = \$solution

Return 1

EndIf

EndFunc

Func _Singletoncolumn (\$column) ;checks for singletone in given column

Dim \$solution[10]

Dim \$solutionrow[10]

For \$t = 1 to 9 ;row

For \$l = 1 to 9 ;number

If \$constant[\$t - 1][\$column] = "" Then

GUICtrlSetData (\$input[\$t-1][\$column], \$l)

If _rowcheck (\$t, \$column) = 0 and _columncheck (\$t, \$column) = 0 and _cellcheck (\$t, \$column) = 0 Then ;cell check not eliminating numbers

\$solution[\$l] = \$solution[\$l] + 1 ; freq

\$solutionrow[\$l] = \$t

EndIf

GUICtrlSetData (\$input[\$t-1][\$column], "")

EndIf

Next

Next

For \$t = 1 to 9 ;checks frenquency

If \$solution[\$t] = 1 Then

GUICtrlSetData (\$input[\$solutionrow[\$t] -1][\$column], \$t)

\$constant[\$solutionrow[\$t] -1][\$column] = \$t

Return 1

EndIf

Next

EndFunc

Func _Singletonrow (\$row) ;checks for singletone in given row

Dim \$solution[10]

Dim \$solutioncolumn[10]

For \$t = 1 to 9 ;column

For \$l = 1 to 9 ;number

If \$constant[\$row - 1][\$t] = "" Then

GUICtrlSetData (\$input[\$row-1][\$t], \$l)

If _rowcheck (\$row, \$t) = 0 and _columncheck (\$row, \$t) = 0 and _cellcheck (\$row, \$t) = 0 Then

\$solution[\$l] = \$solution[\$l] + 1

\$solutioncolumn[\$l] = \$t

EndIf

GUICtrlSetData (\$input[\$row-1][\$t], "")

EndIf

Next

Next

For \$t = 1 to 9 ;checks frenquency

If \$solution[\$t] = 1 Then

GUICtrlSetData (\$input[\$row - 1][\$solutioncolumn[\$t]], \$t)

\$constant[\$row - 1][\$solutioncolumn[\$t]] = \$t

Return 1

EndIf

Next

EndFunc

Func _exit()

Exit

EndFunc ;==>_exit

I haven't looked at how you do it , but I'm impressed how quickly it found a solution to the one attempt I've made so far. It would be interesting to see what Shevilie makes of it wouldn't it?

Well done, I didn't feel too confident you would succeed when you started but I'm glad to see I was wrong.

Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

##### Share on other sites

Thx, im currently making a faster version that uses possibilities rather than jsut checking every number because possibilities allow for more complex algorithms before the brute test.

##### Share on other sites

Looks and works good. Thanks a bunch

1 little comment (suggestion).

Change Case \$GUI_EVENT_CLOSE to Case -3 and remove the #include <GuiConstants.au3>

Unless I missed something (it happens) that seems to be the only place where you used a constant from The GUIConstants file so you have #included a lot of extra constants (and lines) in your script when they are not needed.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

##### Share on other sites

Thx geosoft the does work.

Now Version 2: has pair logic

##### Share on other sites

fixed the bug with brute test

##### Share on other sites

I like this!!! I tried it on the hardest one in my big "Sudoku" book and it worked after about 40 seconds. I have a few suggestions:

• Have a clear button to clear all input boxes
• Have it disable the inputs so that the user can't interfere with your program
• Make the GUI a little more user friendly, for example, add some sort of line to let it be easily seen where the 3x3 boxes start/end
I looked at your code and noticed you don't use and indentation (at least that's how I got it...). See if this helps you see the logic of your loops more clearly:

```Global \$constant[10][10];user numbers [row-1][column]
Global \$input[10][10];input boxes [row-1][column]
Global \$1
Global \$2
Global \$3
Global \$r
Global \$c
Global \$possibilities[10][10][10];[row][column][number] 1 = applicable 0 or "" = not
Global \$change;change in tests
HotKeySet("{esc}", "_exit")

StringCompare('Hello', 'Hella')

\$Form1_1 = GUICreate("solver", 633, 374, 189, 173)
\$Button1 = GUICtrlCreateButton("Solve", 264, 336, 75, 25, 0)

For \$i = 0 To 8
For \$j = 1 To 9
\$input[\$i][\$j] = GUICtrlCreateInput("", 56 * \$j, 32 * (\$i + 1), 41, 21)
Next
Next

GUISetState(@SW_SHOW)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;_sigletoncolumn cell check problem

While 1
Switch GUIGetMsg()
Case - 3
Exit
Case \$Button1
_record()
_allpossible ()
_testpossible ()
_solver2 ()
_brutetest ()
MsgBox(0, "Solved", "Puzzle Solved")
EndSwitch
WEnd

Func _record()
For \$i = 1 To 9
For \$j = 1 To 9
Next
Next
EndFunc;==>_record

Func _rowcheck(\$row, \$column)
For \$i = 1 To 9
If \$i <> \$column Then
If StringCompare(GUICtrlRead(\$input[\$row - 1][\$column]), GUICtrlRead(\$input[\$row - 1][\$i])) = 0 Then Return 1
EndIf
Next
EndFunc;==>_rowcheck

Func _columncheck(\$row, \$column)
For \$i = 1 To 9
If \$i <> \$row Then
If StringCompare(GUICtrlRead(\$input[\$row - 1][\$column]), GUICtrlRead(\$input[\$i - 1][\$column])) = 0 Then Return 1
EndIf
Next
EndFunc;==>_columncheck

Func _brutetest()
For \$r = 1 To 9;row
For \$c = 1 To 9;column
If \$constant[\$r][\$c] = "" Then
For \$n = 1 To 9;number to test
GUICtrlSetData(\$input[\$r - 1][\$c], \$n)
\$1 = _rowcheck(\$r, \$c)
\$2 = _columncheck(\$r, \$c)
\$3 = _cellcheck(\$r, \$c)
If \$1 = 0 And \$2 = 0 And \$3 = 0 Then ExitLoop
Next

If \$1 = 1 Or \$2 = 1 Or \$3 = 1 Then
While 1
GUICtrlSetData(\$input[\$r - 1][\$c], \$constant[\$r][\$c])
\$c = \$c - 1
If \$c < 1 Then
\$c = 9
\$r = \$r - 1
EndIf

If \$constant[\$r][\$c] <> "" Then

Else

While 1
If \$back = "" Then \$back = 0
\$back = \$back + 1
If \$back = 10 Then
ExitLoop
EndIf

GUICtrlSetData(\$input[\$r - 1][\$c], \$back)
\$1 = _rowcheck(\$r, \$c)
\$2 = _columncheck(\$r, \$c)
\$3 = _cellcheck(\$r, \$c)
If \$1 = 0 And \$2 = 0 And \$3 = 0 Then ExitLoop (2)
WEnd
EndIf
WEnd
EndIf
EndIf
Next
Next
EndFunc;==>_brutetest

Func _cellcheck(\$row, \$column)
\$row = \$row - 1
\$cellpos_row = Floor(\$row / 3); If \$row= 0, 1, 2 then this=0, if \$row= 3,4,5 then this=1, if \$row= 6,7,8 then this=2
\$cellpos_col = Floor((\$column - 1) / 3); If \$column= 1,2,3 then this=0, etc..

For \$i = 3 * \$cellpos_row To 3 * \$cellpos_row + 2; (0 to 2) or (3 to 5) or (6 to 8)
For \$j = 3 * \$cellpos_col + 1 To 3 * \$cellpos_col + 3; (1 to 3) or (4 to 6) or (7 to 9)
If \$i <> \$row Or \$j <> \$column Then
EndIf
Next
Next
EndFunc;==>_cellcheck

Func _randomcheck()
While 1
For \$t = 0 To 8
For \$l = 1 To 9
If \$constant[\$t][\$l] = "" Then
GUICtrlSetData(\$input[\$t][\$l], Random(1, 9, 1))
EndIf
Next
Next

For \$q = 1 To 9
For \$z = 1 To 9
If _rowcheck(\$q, \$z) = 1 Or _columncheck(\$q, \$z) = 1 Or _cellcheck(\$q, \$z) = 1 Then ExitLoop (2)
Next
Next

If _rowcheck(\$q, \$z) = 0 And _columncheck(\$q, \$z) = 0 And _cellcheck(\$q, \$z) = 0 Then ExitLoop (1)
WEnd

EndFunc;==>_randomcheck

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; using possibilites array
Func _possible(\$row, \$column);finds possible entries for a given box
For \$k = 1 To 9;numbers
If \$constant[\$row][\$column] = "" Then
GUICtrlSetData(\$input[\$row - 1][\$column], \$k)
If _rowcheck(\$row, \$column) = 0 And _columncheck(\$row, \$column) = 0 And _cellcheck(\$row, \$column) = 0 Then
\$possibilities[\$row][\$column][\$k] = 1
Else
\$possibilities[\$row][\$column][\$k] = 0
EndIf

GUICtrlSetData(\$input[\$row - 1][\$column], "")
EndIf
Next
EndFunc;==>_possible

Func _singlepossible(\$row, \$column)
Dim \$count
\$count = 0
If \$constant[\$row][\$column] = "" Then
For \$d = 1 To 9
If \$possibilities[\$row][\$column][\$d] = 1 Then
\$count = \$count + 1
EndIf
Next

If \$count = 1 Then
Return 1
EndIf
EndIf
EndFunc;==>_singlepossible

Func _singletoncolumn(\$column)
Dim \$count
Dim \$row

For \$d = 1 To 9;number
\$count = 0
For \$a = 1 To 9;row
If \$constant[\$a][\$column] = "" Then
If \$possibilities[\$a][\$column][\$d] = 1 Then
\$count = \$count + 1
\$row = \$a
EndIf
EndIf
Next

If \$count = 1 Then
Return \$row
ExitLoop
EndIf
Next
EndFunc;==>_singletoncolumn

Func _singletonrow(\$row)
Dim \$count
Dim \$column

For \$d = 1 To 9;number
\$count = 0
For \$a = 1 To 9;column
If \$constant[\$row][\$a] = "" Then
If \$possibilities[\$row][\$a][\$d] = 1 Then
\$count = \$count + 1
\$column = \$a
EndIf
EndIf
Next

If \$count = 1 Then
Return \$column
ExitLoop
EndIf
Next
EndFunc;==>_singletonrow

For \$p = 1 To 9;column
If \$constant[\$row1][\$p] = "" Then
_possible(\$row1, \$p)
EndIf
Next
EndFunc;==>_possiblerow

Func _possiblecolumn(\$column1); updates possibilities for column
For \$p = 1 To 9;row
If \$constant[\$p][\$column1] = "" Then
_possible(\$p, \$column1)
EndIf
Next
EndFunc;==>_possiblecolumn

Func _possiblecell(\$row1, \$column1);updates all possibilities for a cell containging the given box
If \$constant[\$row1][\$column1] = "" Then
\$row1 = \$row1 - 1
\$cellpos_row = Floor(\$row1 / 3); If \$row= 0, 1, 2 then this=0, if \$row= 3,4,5 then this=1, if \$row= 6,7,8 then this=2
\$cellpos_col = Floor((\$column1 - 1) / 3); If \$column= 1,2,3 then this=0, etc..

For \$q = 3 * \$cellpos_row To 3 * \$cellpos_row + 3; (0 to 2) or (3 to 5) or (6 to 8)
For \$j = 3 * \$cellpos_col + 1 To 3 * \$cellpos_col + 3; (1 to 3) or (4 to 6) or (7 to 9)
If \$q <> \$row1 Or \$j <> \$column1 Then
_possible(\$q, \$j)
EndIf
Next
Next
EndIf
EndFunc;==>_possiblecell

Func _allpossible ()
For \$i = 1 To 9;checks all possibles
For \$y = 1 To 9
_possible(\$i, \$y)
Next
Next
EndFunc

Func _testpossible()
While 1
\$change = 0
For \$i = 1 To 9
For \$y = 1 To 9
If _singlepossible(\$i, \$y) = 1 Then
\$change = 1
_possiblerow(\$i)
_possiblecolumn(\$y)
_possiblecell(\$i, \$y)
EndIf
Next
Next

For \$i = 1 To 9
\$rowtest = _singletoncolumn(\$i)
If \$rowtest <> 0 And \$rowtest <> "" Then
\$change = 1
_possiblecolumn(\$i)
_possiblerow(\$rowtest)
_possiblecell(\$rowtest, \$i)
EndIf
Next

For \$i = 1 To 9
\$columntest = _singletonrow(\$i)
If \$columntest <> 0 And \$columntest <> "" Then
\$change = 1
_possiblerow(\$i)
_possiblecolumn(\$columntest)
_possiblecell(\$i, \$columntest)
EndIf
Next

If \$change = 0 Then ExitLoop
WEnd

EndFunc;==>_testpossible

Func _solver2()
While 1
For \$i = 1 To 9
_paircolumn(\$i)
_pairrow(\$i)
Next

_testpossible ()

If \$change = 0 then ExitLoop

WEnd
EndFunc;==>_solver2

Func _paircolumn(\$column)
Dim \$count;[number]
Dim \$row[3]
Dim \$match

For \$l = 1 To 9;row
\$count = 0
For \$d = 1 To 9;number
If \$possibilities[\$l][\$column][\$d] = 1 Then \$count = \$count + 1
Next
If \$count = 2 Then
\$row[1] = \$l
For \$m = \$row[1] + 1 To 9;row
\$match = 0
For \$p = 1 To 9;number
If \$possibilities[\$m][\$column][\$p] <> \$possibilities[\$row[1]][\$column][\$p] Then \$match = \$match + 1
Next
If \$match = 0 Then
\$row[2] = \$m
ExitLoop (2)
EndIf
Next
EndIf
Next

If \$row[1] <> "" And \$row[2] <> "" Then
For \$d = 1 To 9;numbers removed from others
If \$possibilities[\$row[1]][\$column][\$d] = 1 Then
For \$l = 1 To 9;row
If \$l <> \$row[1] And \$l <> \$row[2] Then \$possibilities[\$l][\$column][\$d] = 0
Next
EndIf
Next
Return 1
EndIf
EndFunc;==>_paircolumn

Func _pairrow(\$row)
Dim \$count;[number]
Dim \$column[3]
Dim \$match

For \$l = 1 To 9;column
\$count = 0
For \$d = 1 To 9;number
If \$possibilities[\$row][\$l][\$d] = 1 Then \$count = \$count + 1
Next
If \$count = 2 Then
\$column[1] = \$l
For \$m = \$column[1] + 1 To 9;column
\$match = 0
For \$p = 1 To 9;number
If \$possibilities[\$row][\$m][\$p] <> \$possibilities[\$row][\$column[1]][\$p] Then \$match = \$match + 1
Next
If \$match = 0 Then
\$column[2] = \$m
ExitLoop (2)
EndIf
Next
EndIf
Next

If \$column[1] <> "" And \$column[2] <> "" Then
For \$d = 1 To 9;numbers removed from others
If \$possibilities[\$row][\$column[1]][\$d] = 1 Then
For \$l = 1 To 9;column
If \$l <> \$column[1] And \$l <> \$column[2] Then \$possibilities[\$row][\$l][\$d] = 0
Next
EndIf
Next
Return 1
EndIf
EndFunc;==>_pairrow

Func _exit()
Exit
EndFunc;==>_exit```

Last of all, anybody know how to tell Scite to update? I had to download the new version of autoit for this but Scite still isn't recognizing "StringCompare", however when I click "Start -> Programs -> AutoIt -> RunScript" it works fine...

My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]

##### Share on other sites

This is what I meant by changing the GUI, feel free to change this to whatever... I also made the font bigger and set the text to center. I know there is something to make it so that the input can only receive numbers but I can't find it (in my very brief search).

```#include <GuiConstants.au3>

Dim \$input[9][10]

\$Form1_1 = GUICreate("solver", 610, 374, 189, 173)
\$Button1 = GUICtrlCreateButton("Solve", 260, 338, 75, 25, 0)

GuiSetFont(11)
For \$i = 0 To 8
If \$i = 3 or \$i = 6 or \$i = 9 then
EndIf

For \$j = 1 To 9
\$x = 56 * \$j - 60
\$y = 32 * (\$i + 1) - 10

If Mod(\$j - 1, 3) = 0 then
EndIf

\$input[\$i][\$j] = GUICtrlCreateInput("", \$x + \$XaddAmmount, \$y + \$YaddAmmount, 36, 23, \$ES_CENTER)
Next

Next

GUISetState(@SW_SHOW)

While 1
Switch GuiGetMsg()
Case -3
Exit

EndSwitch
WEnd```
Edited by Piano_Man

My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]

##### Share on other sites

Thx for the gui ill add that. My script is indented in scite the indents must have been lost when i copied it.

When you dl the latest version of autoit which one do you pick from the dl page?

##### Share on other sites

Thx for the gui ill add that. My script is indented in scite the indents must have been lost when i copied it.

Your welcome... and I thought that might be the problem because that has happened to me sometimes.

When you dl the latest version of autoit which one do you pick from the dl page?

From here I picked the first one in the list for the AutoIt3 (not beta), then for beta I picked the third one.

However I think the problem is more with scite, because the helpfile shows the StringCompare() and when I doubleclick on the .au3 icon it works fine but when I open scite and try to run it doesn't work (because it can't find the function StringCompare)...

EDIT: This works now, and I don't know what I did to fix it... Anyways thanks for the help!

Edited by Piano_Man

My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]

##### Share on other sites

updated gui and clear button.

##### Share on other sites

I like hitting Solve when theres no numbers - it practically generates a puzzle and solves it.

##### Share on other sites

updated gui and clear button.

Looks better now and seems fast.

Maybe you could check that the numbers entered are legal. If you put the same number more than once in a row or column it shouldn't try to solve it.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

##### Share on other sites

Maybe you could check that the numbers entered are legal. If you put the same number more than once in a row or column it shouldn't try to solve it.

I don't quite understand what your saying. Are you talking about the brute test?

##### Share on other sites

Now has naked pairs for cells as well

##### Share on other sites

Thx geosoft the does work.

Now Version 2: has pair logic

YW but I see you still have it #included and I hate that file with a vengence.

When you use it you are actually #including 17 files with a total of 643 constants. No matter I just run it through my constants replacer script.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

##### Share on other sites

I don't quite understand what your saying. Are you talking about the brute test?

I mean someone can enter numbers which are illegal. I tried putting two 4s in one column, and two 4s in one row. Your script then will try forever to solve it.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

##### Share on other sites

ohh you mean check the user inputs for the original puzzle? Yeh i can add that.

Im currently working on locked candidates but im having some problems.

##### Share on other sites

I have added a couple of new solving strategies but i ahve not been able to get them to work so i think im done with the solver. If anyone would want to continue working on it i can give you the newest code. The new code contains naked triples and locked candidates but neither of them work.

Edited by sccrstvn93

## Create an account

Register a new account