Sudoku: Difference between revisions

7,961 bytes added ,  2 months ago
m
moved commentary outside the code block.
m (moved commentary outside the code block.)
 
(14 intermediate revisions by 6 users not shown)
Line 3,174:
len grid[] 82
#
funcproc init . .
for pos = 1 to 81
if pos mod 9 = 1
s$ = input
if s$ = ""
s$ = input
.
len inp[] 0
for i = 1 to len s$
if substr s$ i 1 <> " "
inp[] &= number substr s$ i 1
.
.
.
lendig = number inp[](pos 0- 1) mod 9 + 1]
forif idig => 1 to len s$0
if substrgrid[pos] s$= i 1 <> " "dig
r inp[] &= number(pos substr- s$1) idiv 19
. c = (pos - 1) mod 9
b = r div 3 * 3 + c div 3
row[r * 10 + dig] = 1
col[c * 10 + dig] = 1
box[b * 10 + dig] = 1
.
.
dig = number inp[(pos - 1) mod 9 + 1]
if dig > 0
grid[pos] = dig
r = (pos - 1) div 9
c = (pos - 1) mod 9
b = r div 3 * 3 + c div 3
row[r * 10 + dig] = 1
col[c * 10 + dig] = 1
box[b * 10 + dig] = 1
.
.
.
call init
#
funcproc display . .
for i = 1 to 81
write grid[i] & " "
if i mod 3 = 0
write " "
.
if i mod 9 = 0
print ""
.
if i mod 27 = 0
print ""
.
.
.
#
funcproc solve pos . .
while grid[pos] <> 0
pos += 1
.
if pos > 81
# solved
call display
break 1 return
.
r = (pos - 1) div 9
c = (pos - 1) mod 9
b = r div 3 * 3 + c div 3
r *= 10
c *= 10
b *= 10
for d = 1 to 9
if row[r + d] = 0 and col[c + d] = 0 and box[b + d] = 0
grid[pos] = d
row[r + d] = 1
col[c + d] = 1
box[b + d] = 1
call solve pos + 1
row[r + d] = 0
col[c + d] = 0
box[b + d] = 0
.
.
grid[pos] = 0
.
call solve 1
#
input_data
Line 3,260:
9 6 0 0 1 0 3 0 0
0 5 0 6 9 0 0 1 0
 
</syntaxhighlight>
 
Line 5,157 ⟶ 5,158:
First is a short version:
<syntaxhighlight lang="futurebasic">
include "ConsoleWindow"
include "NSLog.incl"
include "Util_Containers.incl"
 
begin globals
dim as container gC
end globals
 
BeginCDeclaration
short solve_sudoku(short i);
short check_sudoku(short r, short c);
CFMutableStringRef print_sudoku();
EndC
 
BeginCFunction
short sudoku[9][9] = {
{3,0,0,0,0,1,4,0,9},
{7,0,0,0,0,4,2,0,0},
{0,5,0,2,0,0,0,1,0},
{5,7,0,0,4,3,0,6,0},
{0,9,0,0,0,0,0,3,0},
{0,6,0,7,9,0,0,8,5},
{0,8,0,0,0,5,0,4,0},
{0,0,6,4,0,0,0,0,7},
{9,0,5,6,0,0,0,0,3},
};
 
 
short check_sudoku( short r, short c )
{
short i;
short rr, cc;
 
for (i = 0; i < 9; i++)
{
short i;
if (i != c && sudoku[r][i] == sudoku[r][c]) return 0;
short rr, cc;
if (i != r && sudoku[i][c] == sudoku[r][c]) return 0;
rr = r/3 * 3 + i/3;
ccfor (i = c/30; *i 3< +9; i%3;++)
if ((rr != r || cc != c) && sudoku[rr][cc] == sudoku[r][c]) return 0;
}
return -1;
}
 
 
short solve_sudoku( short i )
{
short r, c;
 
if (i < 0) return 0;
else if (i >= 81) return -1;
 
r = i / 9;
c = i % 9;
 
if (sudoku[r][c])
return check_sudoku(r, c) && solve_sudoku(i + 1);
else
for (sudoku[r][c] = 9; sudoku[r][c] > 0; sudoku[r][c]--)
{
if (i solve_sudoku(!= c && sudoku[r][i)] == sudoku[r][c]) return -10;
if (i != r && sudoku[i][c] == sudoku[r][c]) return 0;
rr = r/3 * 3 + i/3;
cc = c/3 * 3 + i%3;
if ((rr != r || cc != c) && sudoku[rr][cc] == sudoku[r][c]) return 0;
}
return 0-1;
}
 
 
CFMutableStringRef print_sudoku()
{
short i, j;
CFMutableStringRef mutStr;
short solve_sudoku( short i )
mutStr = CFStringCreateMutable( kCFAllocatorDefault, 0 );
{
 
short forr, (i = 0c; i < 9; i++)
{
forif (ji =< 0;) jreturn < 90; j++)
else if (i >= 81) return {-1;
CFStringAppendFormat( mutStr, NULL, (CFStringRef)@" %d", sudoku[i][j] );
r = i / }9;
c = i % 9;
CFStringAppendFormat( mutStr, NULL, (CFStringRef)@"\r" );
}
if (sudoku[r][c])
return( mutStr );
return check_sudoku(r, c) && solve_sudoku(i + 1);
}
else
for (sudoku[r][c] = 9; sudoku[r][c] > 0; sudoku[r][c]--)
{
if ( solve_sudoku(i) ) return -1;
}
return 0;
}
CFMutableStringRef print_sudoku()
{
short i, j;
CFMutableStringRef mutStr;
mutStr = CFStringCreateMutable( kCFAllocatorDefault, 0 );
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
CFStringAppendFormat( mutStr, NULL, (CFStringRef)@" %d", sudoku[i][j] );
}
CFStringAppendFormat( mutStr, NULL, (CFStringRef)@"\r" );
}
return( mutStr );
}
EndC
 
Line 5,246 ⟶ 5,244:
toolbox fn print_sudoku() = CFMutableStringRef
 
dim as short solution
dim as CFMutableStringRef cfRef
 
gC = " "
Line 5,258 ⟶ 5,256:
print : print "Sudoku solved:" : print
if ( solution )
gC = " "
cfRef = fn print_sudoku()
fn ContainerCreateWithCFString( cfRef, gC )
print gC
else
print "No solution found"
end if
 
HandleEvents
</syntaxhighlight>
 
Line 5,297:
More code in this one, but faster execution:
<pre>
include "ConsoleWindow"
include "Tlbx Timer.incl"
 
begin globals
_digits = 9
Line 5,308 ⟶ 5,305:
 
begin record Board
dim as booleanBoolean f(_digits,_digits,_digits)
dim as char match(_digits,_digits)
dim as pointer previousBoard // singly-linked list used to discover repetitions
dim &&
end record
 
dimBoard quiz as board
CFTimeInterval t
dim as long t
dim as double sProgStartTime
 
end globals
 
// 'ordinary' timer used for playing
local fn Milliseconds as long // time in ms since prog start
'~'1
dim as UnsignedWide us
 
long if ( sProgStartTime == 0.0 )
Microseconds( @us )
sProgStartTime = 4294967296.0*us.hi + us.lo
end if
Microseconds( @us )
end fn = (4294967296.0*us.hi + us.lo - sProgStartTime)'*1e-3
 
local fn InitMilliseconds
'~'1
sProgStartTime = 0.0
fn Milliseconds
end fn
 
local mode
local fn CopyBoard( source as ^Board, dest as ^Board )
BlockMoveData( source, dest, sizeof( Board ) )
'~'1
dest.previousBoard = source // linked list
BlockMoveData( source, dest, sizeof( Board ) )
dest.previousBoard = source // linked list
end fn
 
local fn prepare( b as ^Board )
short i, j, n
'~'1
dim as short i, j, n
for i = 1 to _digits
 
for ij = 1 to _digits
for jn = 1 to _digits
b.match[i, j] = 0
for n = 1 to _digits
b.matchf[i, j, n] = 0_true
next n
b.f[i, j, n] = _true
next nj
next ji
next i
end fn
 
local fn printBoard( b as ^Board )
short i, j
'~'1
dim as short i, j
for i = 1 to _digits
 
for ij = 1 to _digits
Print b.match[i, j];
for j = 1 to _digits
next j
Print b.match[i, j];
print
next j
next i
print
next i
end fn
 
local fn verifica( b as ^Board )
short i, j, n, first, x, y, ii
'~'1
Boolean check
dim as short i, j, n, first, x, y, ii
dim as boolean check
check = _true
 
check = _true
for i = 1 to _digits
 
for ij = 1 to _digits
if ( b.match[i, j] == 0 )
for j = 1 to _digits
check = _false
long if ( b.match[i, j] == 0 )
for n = 1 to _digits
check = _false
if ( b.f[i, j, n] != _false )
for n = 1 to _digits
check = _true
long if ( b.f[i, j, n] != _false )
end if
check = _true
next n
end if
if ( check == _false ) then exit fn
next n
end if
if ( check == _false ) then exit fn
next j
end if
next ji
next i
check = _true
 
for j = 1 to _digits
check = _true
for jn = 1 to _digits
for n = 1 to _digits first = 0
for i = 1 to _digits
first = 0
if ( b.match[i, j] == n )
for i = 1 to _digits
long if ( b.match[i, j]first == n0 )
long if ( first == 0 )i
else
first = i
check = _false
xelse
exit fn
check = _false
end if
exit fn
end if
next i
end if
next in
next nj
next j
for i = 1 to _digits
 
for in = 1 to _digits
for n = 1 to _digits first = 0
for j = 1 to _digits
first = 0
if ( b.match[i, j] == n )
for j = 1 to _digits
long if ( b.match[i, j]first == n0 )
long if ( first == 0 )j
else
first = j
check = _false
xelse
exit fn
check = _false
end if
exit fn
end if
next j
end if
next jn
next ni
next i
for x = 0 to ( _nSetH - 1 )
 
for xy = 0 to ( _nSetH_nSetV - 1 )
for y = 0 to ( _nSetVfirst -= 1 )0
for ii = 0 to ( _digits - 1 )
first = 0
i = x * _setH + ii mod _setH + 1
for ii = 0 to ( _digits - 1 )
i j = xy * _setH_setV + ii mod/ _setH + 1
j = y * _setV + ii / _setHif ( b.match[i, j] == +n 1)
long if ( b.match[i, j]first == n0 )
long if ( first == 0 )j
else
first = j
check = _false
xelse
exit fn
check = _false
end if
exit fn
end if
next ii
end if
next iiy
next yx
next x
 
end fn = check
 
 
local fn setCell( b as ^Board, x as short, y as short, n as short) as boolean
dim as short i, j, rx, ry
dim as booleanBoolean check
 
b.match[x, y] = n
for i = 1 to _digits
b.f[x, i, n] = _false
b.f[i, y, n] = _false
next i
 
rx = (x - 1) / _setH
ry = (y - 1) / _setV
 
for i = 1 to _setH
for j = 1 to _setV
b.f[ rx * _setH + i, ry * _setV + j, n ] = _false
next j
next i
 
check = fn verifica( #b )
if ( check == _false ) then exit fn
 
end fn = check
 
 
local fn solve( b as ^Board )
dim as short i, j, n, first, x, y, ii, ppi, ppj
dim as booleanBoolean check
 
check = _true
 
for i = 1 to _digits
for j = 1 to _digits
long if ( b.match[i, j] == 0 )
first = 0
for n = 1 to _digits
long if ( b.f[i, j, n] != _false )
long if ( first == 0 )
first = n
else
xelse
first = -1
exit for
end if
end if
next n
 
long if ( first > 0 )
check = fn setCell( #b, i, j, first )
if ( check == _false ) then exit fn
check = fn solve(#b)
if ( check == _false ) then exit fn
end if
 
end if
next j
next i
 
for i = 1 to _digits
for n = 1 to _digits
first = 0
 
for j = 1 to _digits
if ( b.match[i, j] == n ) then exit for
 
long if ( b.f[i, j, n] != _false ) and ( b.match[i, j] == 0 )
long if ( first == 0 )
first = j
else
xelse
first = -1
exit for
end if
 
end if
 
next j
 
long if ( first > 0 )
check = fn setCell( #b, i, first, n )
if ( check == _false ) then exit fn
check = fn solve(#b)
if ( check == _false ) then exit fn
end if
 
next n
next i
 
 
for j = 1 to _digits
for n = 1 to _digits
first = 0
 
for i = 1 to _digits
if ( b.match[i, j] == n ) then exit for
 
long if ( b.f[i, j, n] != _false ) and ( b.match[i, j] == 0 )
long if ( first == 0 )
first = i
else
xelse
first = -1
exit for
end if
 
end if
 
next i
 
long if ( first > 0 )
check = fn setCell( #b, first, j, n )
if ( check == _false ) then exit fn
check = fn solve(#b)
if ( check == _false ) then exit fn
end if
 
next n
next j
 
 
for x = 0 to ( _nSetH - 1 )
for y = 0 to ( _nSetV - 1 )
 
for n = 1 to _digits
first = 0
 
for ii = 0 to ( _digits - 1 )
 
i = x * _setH + ii mod _setH + 1
j = y * _setV + ii / _setH + 1
 
if ( b.match[i, j] == n ) then exit for
 
long if ( b.f[i, j, n] != _false ) and ( b.match[i, j] == 0 )
long if ( first == 0 )
first = n
ppi = i
ppj = j
else
xelse
first = -1
exit for
end if
end if
 
 
next ii
 
long if ( first > 0 )
check = fn setCell( #b, ppi, ppj, n )
if ( check == _false ) then exit fn
check = fn solve(#b)
if ( check == _false ) then exit fn
end if
 
next n
 
next y
next x
 
end fn = check
 
 
local fn resolve( b as ^Board )
dim as booleanBoolean check, daFinire
dim as long i, j, n
dim as boardBoard localBoard
 
check = fn solve(b)
 
long if ( check == _false )
exit fn
end if
 
daFinire = _false
 
for i = 1 to _digits
for j = 1 to _digits
long if ( b.match[i, j] == 0 )
 
daFinire = _true
 
for n = 1 to _digits
long if ( b.f[i, j, n] != _false )
 
fn CopyBoard( b, @localBoard )
 
check = fn setCell(@localBoard, i, j, n)
 
long if ( check != _false )
check = fn resolve( @localBoard )
long if ( check == -1 )
fn CopyBoard( @localBoard, b )
 
exit fn
end if
end if
 
end if
 
next n
 
end if
next j
next i
 
long if daFinire
else
xelse
check = -1
end if
 
end fn = check
 
 
fn InitMilliseconds
 
fn prepare( @quiz )
Line 5,670 ⟶ 5,642:
DATA 2,8,0,1,3,0,0,0,0
 
dim as short i, j, d
for i = 1 to _digits
for j = 1 to _digits
read d
fn setCell(@quiz, j, i, d)
next j
next i
 
Line 5,681 ⟶ 5,653:
fn printBoard( @quiz )
print : print "-------------------" : print
dim as booleanBoolean check
 
t = fn MillisecondsCACurrentMediaTime
check = fn resolve(@quiz)
t = (fn MillisecondsCACurrentMediaTime - t) * 1000
 
if ( check )
print "solution:"; str$( t/1000.0 ) + " ms"
else
print "No solution found"
end if
fn printBoard( @quiz )
 
HandleEvents
</pre>
 
Line 10,107 ⟶ 10,081:
=={{header|Python}}==
See [http://www2.warwick.ac.uk/fac/sci/moac/currentstudents/peter_cock/python/sudoku/ Solving Sudoku puzzles with Python] for GPL'd solvers of increasing complexity of algorithm.
 
===Backtrack===
 
A simple backtrack algorithm -- Quick but may take longer if the grid had been more than 9 x 9
Line 10,194 ⟶ 10,170:
raw_input()
</syntaxhighlight>
 
===Search + Wave Function Collapse===
 
A Sudoku solver using search guided by the principles of wave function collapse.
<syntaxhighlight lang="python">
 
 
sudoku = [
# cell value # cell number
0, 0, 4, 0, 5, 0, 0, 0, 0, # 0, 1, 2, 3, 4, 5, 6, 7, 8,
9, 0, 0, 7, 3, 4, 6, 0, 0, # 9, 10, 11, 12, 13, 14, 15, 16, 17,
0, 0, 3, 0, 2, 1, 0, 4, 9, # 18, 19, 20, 21, 22, 23, 24, 25, 26,
0, 3, 5, 0, 9, 0, 4, 8, 0, # 27, 28, 29, 30, 31, 32, 33, 34, 35,
0, 9, 0, 0, 0, 0, 0, 3, 0, # 36, 37, 38, 39, 40, 41, 42, 43, 44,
0, 7, 6, 0, 1, 0, 9, 2, 0, # 45, 46, 47, 48, 49, 50, 51, 52, 53,
3, 1, 0, 9, 7, 0, 2, 0, 0, # 54, 55, 56, 57, 58, 59, 60, 61, 62,
0, 0, 9, 1, 8, 2, 0, 0, 3, # 63, 64, 65, 66, 67, 68, 69, 70, 71,
0, 0, 0, 0, 6, 0, 1, 0, 0, # 72, 73, 74, 75, 76, 77, 78, 79, 80
# zero = empty.
]
 
numbers = {1,2,3,4,5,6,7,8,9}
 
def options(cell,sudoku):
""" determines the degree of freedom for a cell. """
column = {v for ix, v in enumerate(sudoku) if ix % 9 == cell % 9}
row = {v for ix, v in enumerate(sudoku) if ix // 9 == cell // 9}
box = {v for ix, v in enumerate(sudoku) if (ix // (9 * 3) == cell // (9 * 3)) and ((ix % 9) // 3 == (cell % 9) // 3)}
return numbers - (box | row | column)
 
initial_state = sudoku[:] # the sudoku is our initial state.
 
job_queue = [initial_state] # we need the jobqueue in case of ambiguity of choice.
 
while job_queue:
state = job_queue.pop(0)
if not any(i==0 for i in state): # no missing values means that the sudoku is solved.
break
 
# determine the degrees of freedom for each cell.
degrees_of_freedom = [0 if v!=0 else len(options(ix,state)) for ix,v in enumerate(state)]
# find cell with least freedom.
least_freedom = min(v for v in degrees_of_freedom if v > 0)
cell = degrees_of_freedom.index(least_freedom)
 
for option in options(cell, state): # for each option we add the new state to the queue.
new_state = state[:]
new_state[cell] = option
job_queue.append(new_state)
 
# finally - print out the solution
for i in range(9):
print(state[i*9:i*9+9])
 
# [2, 6, 4, 8, 5, 9, 3, 1, 7]
# [9, 8, 1, 7, 3, 4, 6, 5, 2]
# [7, 5, 3, 6, 2, 1, 8, 4, 9]
# [1, 3, 5, 2, 9, 7, 4, 8, 6]
# [8, 9, 2, 5, 4, 6, 7, 3, 1]
# [4, 7, 6, 3, 1, 8, 9, 2, 5]
# [3, 1, 8, 9, 7, 5, 2, 6, 4]
# [6, 4, 9, 1, 8, 2, 5, 7, 3]
# [5, 2, 7, 4, 6, 3, 1, 9, 8]
 
</syntaxhighlight>
 
This solver found the 45 unknown values in 45 steps.
 
=={{header|Racket}}==
Line 13,071 ⟶ 13,114:
 
=={{header|Tailspin}}==
There is a blog post about how this code was developed: https://tobega.blogspot.com/2020/05/creating-algorithm.html
<syntaxhighlight lang="tailspin">
templates deduceRemainingDigits
templates findOpenPosition
@:{options: 10"1"};
$ -> \[i;j](when <[]?($::length <..~$@findOpenPosition.options::raw>)> do @findOpenPosition: {row: $i, col: $j, options: ($::length)"1"}; \) -> !VOID
$@ !
end findOpenPosition
Line 13,092 ⟶ 13,136:
@: $;
$ -> findOpenPosition -> #
when <{options: <=0"1">}> do row´1:[] !
when <{options: <=10"1">}> do $@ !
when <> do def next: $;
$@ -> selectFirst&{pos: $next} -> deduceRemainingDigits
-> \(when <~=row´1:[]> do @deduceRemainingDigits: $; {options: 10"1"} !
when <=row´1:[]> do ^@deduceRemainingDigits($next.row;$next.col;1)
-> { $next..., options: $next.options-1"1"} ! \) -> #
end deduceRemainingDigits
Line 13,122 ⟶ 13,166:
assert row´1:[
col´1:[[],3,4,6,7,8,9,1,2],
$sample(row´2..last)...] -> deduceRemainingDigits <=row´1:[]> 'no remaining options returns empty'
 
assert row´1:[
Line 13,183 ⟶ 13,227:
templates solveSudoku
$ -> parseSudoku -> deduceRemainingDigits -> #
when <=row´1:[]> do 'No result found' !
when <> do $ -> \[i](
'$(col´1..col´3)...;|$(col´4..col´6)...;|$(col´7..col´9)...;$#10;' !
Line 13,857 ⟶ 13,901:
2 4 3 1 5 7 8 6 9
5 1 9 8 3 6 7 2 4</pre>
 
===Alternate version===
A faster version adapted from the C solution
<syntaxhighlight lang="vb">
'VBScript Sudoku solver. Fast recursive algorithm adapted from the C version
'It can read a problem passed in the command line or from a file /f:textfile
'if no problem passed it solves a hardwired problem (See the prob0 string)
'problem string can have 0's or dots in the place of unknown values. All chars different from .0123456789 are ignored
 
Option explicit
Sub print(s):
On Error Resume Next
WScript.stdout.Write (s)
If err= &h80070006& Then WScript.Echo " Please run this script with CScript": WScript.quit
End Sub
 
function parseprob(s)'problem string to array
Dim i,j,m
print "parsing: " & s & vbCrLf & vbcrlf
j=0
For i=1 To Len(s)
m=Mid(s,i,1)
Select Case m
Case "0","1","2","3","4","5","6","7","8","9"
sdku(j)=cint(m)
j=j+1
Case "."
sdku(j)=0
j=j+1
Case Else 'all other chars are ignored as separators
End Select
Next
' print j
If j<>81 Then parseprob=false Else parseprob=True
End function
 
sub getprob 'get problem from file or from command line or from
Dim s,s1
With WScript.Arguments.Named
If .exists("f") Then
s1=.item("f")
If InStr(s1,"\")=0 Then s1= Left(WScript.ScriptFullName, InStrRev(WScript.ScriptFullName, "\"))&s1
On Error Resume Next
s= CreateObject("Scripting.FileSystemObject").OpenTextFile (s1, 1).readall
If err Then print "can't open file " & s1 : parseprob(prob0): Exit sub
If parseprob(s) =True Then Exit sub
End if
End With
With WScript.Arguments.Unnamed
If .count<>0 Then
s1=.Item(0)
If parseprob(s1)=True Then exit sub
End if
End With
parseprob(prob0)
End sub
 
function solve(x,ByVal pos)
'print pos & vbcrlf
'display(x)
Dim row,col,i,j,used
solve=False
If pos=81 Then solve= true :Exit function
row= pos\9
col=pos mod 9
If x(pos) Then solve=solve(x,pos+1):Exit Function
used=0
For i=0 To 8
used=used Or pwr(x(i * 9 + col))
Next
For i=0 To 8
used=used Or pwr(x(row*9 + i))
next
row = (row\ 3) * 3
col = (col \3) * 3
For i=row To row+2
For j=col To col+2
' print i & " " & j &vbcrlf
used = used Or pwr(x(i*9+j))
Next
Next
'print pos & " " & Hex(used) & vbcrlf
For i=1 To 9
If (used And pwr(i))=0 Then
x(pos)=i
'print pos & " " & i & " " & num2bin((used)) & vbcrlf
solve= solve(x,pos+1)
If solve=True Then Exit Function
'x(pos)=0
End If
Next
x(pos)=0
solve=False
End Function
 
Sub display(x)
Dim i,s
For i=0 To 80
If i mod 9=0 Then print s & vbCrLf :s=""
If i mod 27=0 Then print vbCrLf
If i mod 3=0 Then s=s & " "
s=s& x(i)& " "
Next
print s & vbCrLf
End Sub
 
Dim pwr:pwr=Array(1,2,4,8,16,32,64,128,256,512,1024,2048)
Dim prob0:prob0= "001005070"&"920600000"& "008000600"&"090020401"& "000000000" & "304080090" & "007000300" & "000007069" & "010800700"
Dim sdku(81),Time
getprob
print "The problem"
display(sdku)
Time=Timer
If solve (sdku,0) Then
print vbcrlf &"solution found" & vbcrlf
display(sdku)
Else
print "no solution found " & vbcrlf
End if
print vbcrlf & "time: " & Timer-Time & " seconds" & vbcrlf
</syntaxhighlight>
{{out}}
<small>
<pre>
parsing: 001005070920600000008000600090020401000000000304080090007000300000007069010800700
 
The problem
 
0 0 1 0 0 5 0 7 0
9 2 0 6 0 0 0 0 0
0 0 8 0 0 0 6 0 0
 
0 9 0 0 2 0 4 0 1
0 0 0 0 0 0 0 0 0
3 0 4 0 8 0 0 9 0
 
0 0 7 0 0 0 3 0 0
0 0 0 0 0 7 0 6 9
0 1 0 8 0 0 7 0 0
 
solution found
 
6 3 1 2 4 5 9 7 8
9 2 5 6 7 8 1 4 3
4 7 8 3 1 9 6 5 2
 
7 9 6 5 2 3 4 8 1
1 8 2 9 6 4 5 3 7
3 5 4 7 8 1 2 9 6
 
8 6 7 4 9 2 3 1 5
2 4 3 1 5 7 8 6 9
5 1 9 8 3 6 7 2 4
 
time: 0.3710938 seconds
</pre>
</small>
 
=={{header|Wren}}==
{{trans|Kotlin}}
<syntaxhighlight lang="ecmascriptwren">class Sudoku {
construct new(rows) {
if (rows.count != 9 || rows.any { |r| r.count != 9 }) {
6

edits