Sudoku: Difference between revisions

136,521 bytes added ,  2 months ago
m
moved commentary outside the code block.
m (→‎Constraint Satisfaction (Norvig): 3.7 ms looked too good, even if could not find issue but this 6.7 ms timings with updated code I trust better)
m (moved commentary outside the code block.)
 
(32 intermediate revisions by 14 users not shown)
Line 12:
{{trans|Kotlin}}
 
<langsyntaxhighlight lang="11l">T Sudoku
solved = 0B
grid = [0] * 81
Line 83:
‘000036040’]
 
Sudoku(rows).solve()</langsyntaxhighlight>
 
{{out}}
Line 118:
 
=={{header|8th}}==
<langsyntaxhighlight lang="8th">
\
\ Simple iterative backtracking Sudoku solver for 8th
Line 265:
"No solution!\n" .
then ;
</syntaxhighlight>
</lang>
 
=={{header|Ada}}==
{{trans|C++}}
<langsyntaxhighlight lang="ada">
with Ada.Text_IO;
 
Line 378:
solve( sudoku_ar );
end Sudoku;
</syntaxhighlight>
</lang>
 
{{out}}
Line 401:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny].}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
<langsyntaxhighlight lang="algol68">MODE AVAIL = [9]BOOL;
MODE BOX = [3, 3]CHAR;
 
Line 495:
"__1__6__9"))
END CO
)</langsyntaxhighlight>
{{out}}
<pre>
Line 515:
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">#SingleInstance, Force
SetBatchLines, -1
SetTitleMatchMode, 3
Line 658:
r .= SubStr(p, A_Index, 1) . "|"
return r
}</langsyntaxhighlight>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f SUDOKU_RC.AWK
BEGIN {
Line 849:
}
function error(message) { printf("error: %s\n",message) ; errors++ }
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 886:
{{works with|BBC BASIC for Windows}}
[[Image:sudoku_bbc.gif|right]]
<langsyntaxhighlight lang="bbcbasic"> VDU 23,22,453;453;8,20,16,128
*FONT Arial,28
Line 990:
ENDIF
NEXT
= D%</langsyntaxhighlight>
 
=={{header|BCPL}}==
<langsyntaxhighlight BCPLlang="bcpl">// This can be run using Cintcode BCPL freely available from www.cl.cam.ac.uk/users/mr10.
// Implemented by Martin Richards.
 
Line 1,388:
{ count := count + 1
prboard()
}</langsyntaxhighlight>
 
=={{header|Befunge}}==
Line 1,394:
Input should be provided as a sequence of 81 digits (optionally separated by whitespace), with zero representing an unknown value.
 
<langsyntaxhighlight lang="befunge">99*>1-:0>:#$"0"\# #~`#$_"0"-\::9%:9+00p3/\9/:99++10p3vv%2g\g01<
2%v|:p+9/9\%9:\p\g02\1p\g01\1:p\g00\1:+8:\p02+*93+*3/<>\20g\g#:
v<+>:0\`>v >\::9%:9+00p3/\9/:99++10p3/3*+39*+20p\:8+::00g\g2%\^
Line 1,401:
p|<$0.0^!g+:#9/9<^@ ^,>#+5<5_>#!<>#$0"------+-------+-----":#<^
<>v$v1:::0<>"P"`!^>0g#0v#p+9/9\%9:p04:\pg03g021pg03g011pg03g001
::>^_:#<0#!:p#-\#1:#g0<>30g010g30g020g30g040g:9%\:9/9+\01-\1+0:</langsyntaxhighlight>
 
{{in}}
Line 1,431:
=={{header|Bracmat}}==
The program:
<langsyntaxhighlight lang="bracmat">{sudokuSolver.bra
 
Solves any 9x9 sudoku, using backtracking.
Line 1,619:
. new$((its.sudoku),!arg):?puzzle
& (puzzle..Display)$
);</langsyntaxhighlight>
Solve a sudoku that is hard for a brute force solver:
<langsyntaxhighlight lang="bracmat">new'( sudokuSolver
, (.- - - - - - - - -)
(.- - - - - 3 - 8 5)
Line 1,631:
(.- - 2 - 1 - - - -)
(.- - - - 4 - - - 9)
);</langsyntaxhighlight>
Solution:
<pre>|~~~|~~~|~~~|
Line 1,651:
 
The following code is really only good for size 3 puzzles. A longer, even less readable version [[Sudoku/C|here]] could handle size 4s.
<langsyntaxhighlight lang="c">#include <stdio.h>
 
void show(int *x)
Line 1,717:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
===Backtracking===
{{trans|Java}}
<langsyntaxhighlight lang="csharp">using System;
 
class SudokuSolver
Line 1,824:
Console.Read();
}
}</langsyntaxhighlight>
 
=== Best First Search===
<!-- By Martin Freedman, 20/11/2021 -->
<langsyntaxhighlight lang="csharp">using System.Linq;
using static System.Linq.Enumerable;
using System.Collections.Generic;
Line 1,904:
}
}
}</langsyntaxhighlight>
Usage
<langsyntaxhighlight lang="csharp">using System.Linq;
using static System.Linq.Enumerable;
using static System.Console;
Line 1,941:
}
}
}</langsyntaxhighlight>
Output
<pre>693784512
Line 1,960:
{{libheader|Microsoft Solver Foundation}}
<!-- By Nigel Galloway, Jan 29, 2012 -->
<langsyntaxhighlight lang="csharp">using Microsoft.SolverFoundation.Solvers;
 
namespace Sudoku
Line 2,032:
}
}
}</langsyntaxhighlight>
Produces:
<pre>
Line 2,049:
 
==="Dancing Links"/Algorithm X===
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Text;
Line 2,327:
 
public static string DelimitWith<T>(this IEnumerable<T> source, string separator) => string.Join(separator, source);
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,352:
=={{header|C++}}==
{{trans|Java}}
<langsyntaxhighlight lang="cpp">#include <iostream>
using namespace std;
 
Line 2,443:
ss.solve();
return EXIT_SUCCESS;
}</langsyntaxhighlight>
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">(ns rosettacode.sudoku
(:use [clojure.pprint :only (cl-format)]))
 
Line 2,469:
(if (= x (dec c))
(recur ng 0 (inc y))
(recur ng (inc x) y)))))))</langsyntaxhighlight>
 
<langsyntaxhighlight lang="clojure">sudoku>(cl-format true "~{~{~a~^ ~}~%~}"
(solve [[3 9 4 0 0 2 6 7 0]
[0 0 0 3 0 0 4 0 0]
Line 2,491:
8 2 6 4 1 9 7 3 5
 
nil</langsyntaxhighlight>
 
=={{header|Common Lisp}}==
A simple solver without optimizations (except for pre-computing the possible entries of a cell).
<langsyntaxhighlight lang="lisp">(defun row-neighbors (row column grid &aux (neighbors '()))
(dotimes (i 9 neighbors)
(let ((x (aref grid row i)))
Line 2,534:
(setf (aref grid row column) choice)
(when (eq grid (solve grid row (1+ column)))
(return grid))))))</langsyntaxhighlight>
Example:
<pre>> (defparameter *puzzle*
Line 2,561:
(7 5 9 2 3 8 1 4 6)
(8 2 6 4 1 9 7 3 5))</pre>
=={{header|Crystal}}==
Based on the Java implementation presented in the video "[https://www.youtube.com/watch?v=mcXc8Mva2bA Create a Sudoku Solver In Java...]".
 
<syntaxhighlight lang="ruby">GRID_SIZE = 9
 
def isNumberInRow(board, number, row)
board[row].includes?(number)
end
def isNumberInColumn(board, number, column)
board.any?{|row| row[column] == number }
end
def isNumberInBox(board, number, row, column)
localBoxRow = row - row % 3
localBoxColumn = column - column % 3
(localBoxRow...(localBoxRow+3)).each do |i|
(localBoxColumn...(localBoxColumn+3)).each do |j|
return true if board[i][j] == number
end
end
false
end
 
def isValidPlacement(board, number, row, column)
return !isNumberInRow(board, number, row) &&
!isNumberInColumn(board, number, column) &&
!isNumberInBox(board, number, row, column)
end
 
def solveBoard(board)
board.each_with_index do |row, i|
row.each_with_index do |cell, j|
if(cell == 0)
(1..GRID_SIZE).each do |n|
if(isValidPlacement(board,n,i,j))
board[i][j]=n
if(solveBoard(board))
return true
else
board[i][j]=0
end
end
end
return false
end
end
end
return true
end
 
def printBoard(board)
board.each_with_index do |row, i|
row.each_with_index do |cell, j|
print cell
print '|' if j == 2 || j == 5
print '\n' if j == 8
end
print "-"*11 + '\n' if i == 2 || i == 5
end
print '\n'
end
 
board = [
[7, 0, 2, 0, 5, 0, 6, 0, 0],
[0, 0, 0, 0, 0, 3, 0, 0, 0],
[1, 0, 0, 0, 0, 9, 5, 0, 0],
[8, 0, 0, 0, 0, 0, 0, 9, 0],
[0, 4, 3, 0, 0, 0, 7, 5, 0],
[0, 9, 0, 0, 0, 0, 0, 0, 8],
[0, 0, 9, 7, 0, 0, 0, 0, 5],
[0, 0, 0, 2, 0, 0, 0, 0, 0],
[0, 0, 7, 0, 4, 0, 2, 0, 3]]
 
printBoard(board)
if(solveBoard(board))
printBoard(board)
end
</syntaxhighlight>
{{out}}
<pre>
702|050|600
000|003|000
100|009|500
-----------
800|000|090
043|000|750
090|000|008
-----------
009|700|005
000|200|000
007|040|203
 
732|458|619
956|173|824
184|629|537
-----------
871|564|392
643|892|751
295|317|468
-----------
329|786|145
418|235|976
567|941|283
</pre>
=={{header|Curry}}==
Copied from [http://www.informatik.uni-kiel.de/~curry/examples/ Curry: Example Programs].
<langsyntaxhighlight lang="curry">-----------------------------------------------------------------------------
--- Solving Su Doku puzzles in Curry with FD constraints
---
Line 2,626 ⟶ 2,728:
" 5 7 921 ",
" 64 9 ",
" 2 438"]</langsyntaxhighlight>
 
 
Line 2,632 ⟶ 2,734:
{{Works with|PAKCS}}
Minimal w/o read or show utilities.
<langsyntaxhighlight lang="curry">import CLPFD
import Constraint (allC)
import List (transpose)
Line 2,665 ⟶ 2,767:
, [7,_,_,6,_,_,5,_,_]
]
main | sudoku xs = xs where xs = test</langsyntaxhighlight>
{{Out}}
<pre>Execution time: 0 msec. / elapsed: 10 msec.
Line 2,673 ⟶ 2,775:
{{trans|C++}}
A little over-engineered solution, that shows some strong static typing useful in larger programs.
<langsyntaxhighlight lang="d">import std.stdio, std.range, std.string, std.algorithm, std.array,
std.ascii, std.typecons;
 
Line 2,799 ⟶ 2,901:
else
solution.get.representSudoku.writeln;
}</langsyntaxhighlight>
{{out}}
<pre>8 5 . | . . 2 | 4 . .
Line 2,827 ⟶ 2,929:
===Short Version===
Adapted from: http://code.activestate.com/recipes/576725-brute-force-sudoku-solver/
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.range;
 
const(int)[] solve(immutable int[] s) pure nothrow @safe {
Line 2,860 ⟶ 2,962:
0, 0, 0, 0, 3, 6, 0, 4, 0];
writefln("%(%s\n%)", problem.solve.chunks(9));
}</langsyntaxhighlight>
{{out}}
<pre>[8, 5, 9, 6, 1, 2, 4, 3, 7]
Line 2,874 ⟶ 2,976:
===No-Heap Version===
This version is similar to the precedent one, but it shows idioms to avoid memory allocations on the heap. This is enforced by the use of the @nogc attribute.
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.range, std.typecons;
 
Nullable!(const ubyte[81]) solve(in ubyte[81] s) pure nothrow @safe @nogc {
Line 2,915 ⟶ 3,017:
0, 0, 0, 0, 3, 6, 0, 4, 0];
writefln("%(%s\n%)", problem.solve.get[].chunks(9));
}</langsyntaxhighlight>
Same output.
 
=={{header|Delphi}}==
Example taken from C++
<langsyntaxhighlight lang="delphi">type
TIntArray = array of Integer;
 
Line 3,044 ⟶ 3,146:
ShowMessage('Solved!');
end;
end;</langsyntaxhighlight>
Usage:
<langsyntaxhighlight lang="delphi">var
SudokuSolver: TSudokuSolver;
begin
Line 3,063 ⟶ 3,165:
FreeAndNil(SudokuSolver);
end;
end;</langsyntaxhighlight>
 
=={{header|EasyLang}}==
<syntaxhighlight lang="text">
<lang>len row[] 810
len colrow[] 81090
len boxcol[] 81090
len box[] 90
len grid[] 82
#
funcproc init . .
for pos range= 1 to 81
if pos mod 9 = 01
s$[] = str_split input " "
. if s$ = ""
dig = number s$[pos mod= 9]input
grid[pos] = dig .
r = pos div 9 len inp[] 0
c for i = pos1 to modlen 9s$
b = r div 3 * 3 + cif divsubstr 3s$ i 1 <> " "
row[r * 10 + dig inp[] &= number substr s$ i 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 range= 1 to 81
write grid[i] & " "
if i mod 3 = 20
write " "
.
if i mod 9 = 80
print ""
.
if i mod 27 = 260
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 01
#
input_data
5 3 0 0 2 4 7 0 0
0 0 2 0 0 0 8 0 0
1 0 0 7 0 3 9 0 2
 
0 0 8 0 7 2 0 4 9
0 2 0 9 8 0 0 7 2 0 4 9
70 92 0 0 09 8 0 0 87 0
7 9 0 0 0 0 3 0 58 0 6
 
9 6 0 0 1 0 3 0 0
0 50 0 6 9 0 3 0 1 5 0</lang> 6
9 6 0 0 1 0 3 0 0
0 5 0 6 9 0 0 1 0
 
</syntaxhighlight>
 
=={{header|Elixir}}==
{{trans|Erlang}}
<langsyntaxhighlight lang="elixir">defmodule Sudoku do
def display( grid ), do: ( for y <- 1..9, do: display_row(y, grid) )
Line 3,303 ⟶ 3,421:
{{3, 8}, 2}, {{5, 8}, 1},
{{5, 9}, 4}, {{9, 9}, 9}]
Sudoku.task( difficult )</langsyntaxhighlight>
 
{{out}}
Line 3,363 ⟶ 3,481:
=={{header|Erlang}}==
I first try to solve the Sudoku grid without guessing. For the guessing part I eschew spawning a process for each guess, instead opting for backtracking. It is fun trying new things.
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( sudoku ).
 
Line 3,526 ⟶ 3,644:
display( Solved ),
io:nl().
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,610 ⟶ 3,728:
0 is the empty cell.
 
<syntaxhighlight lang="erre">
<lang ERRE>
!--------------------------------------------------------------------
! risolve Sudoku: in input il file SUDOKU.TXT
Line 4,017 ⟶ 4,135:
 
 
</syntaxhighlight>
</lang>
 
=={{header|F_Sharp|F#}}==
===Backtracking===
<!-- By Martin Freedman, 26/11/2021 -->
<langsyntaxhighlight lang="fsharp">module SudokuBacktrack
 
//Helpers
Line 4,095 ⟶ 4,213:
/// solve sudoku using simple backtracking
let solve grid = grid |> parseGrid >>= flip backtracker (Some "A1")</langsyntaxhighlight>
'''Usage:'''
<langsyntaxhighlight lang="fsharp">open System
open SudokuBacktrack
 
Line 4,109 ⟶ 4,227:
printfn "Press any key to exit"
Console.ReadKey() |> ignore
0</langsyntaxhighlight>
{{Output}}<pre>
Puzzle:
Line 4,138 ⟶ 4,256:
===Constraint Satisfaction (Norvig)===
<!-- By Martin Freedman, 27/11/2021 -->
<langsyntaxhighlight lang="fsharp">// https://norvig.com/sudoku.html
// using array O(1) lookup & mutable instead of map O(logn) immutable - now 6 times faster
module SudokuCPS
module SudokuCPSArray
open System
// helpers
let tuple2 a b = a,b
let (>>=) f g = Option.bind g f
 
/// from 11 to 99 as squares key maps to 0 to 80 in arrays
/// folds folder returning Some on completion or returns None if not
let reckey alla folderb state= source(9*a =+ b) - 10
match state, source with
| None, _ -> None
| Some st, [] -> Some st
| Some st , hd::rest -> folder st hd |> (fun st1 -> all folder st1 rest)
 
/// "A1" to "I9" squares as key in values dictionary
let key a b = 10*a + b// $"{a}{b}"
 
/// Keys generator
let cross ax bx = [| for a in ax do for b in bx do key a b |]
 
// constants
let digits = [|1..9|]
let rows = digits
Line 4,167 ⟶ 4,275:
let squares = cross rows cols
 
/// List of all row, cols and boxes: aka units
let unitlist =
[for c in cols -> cross rows [|c|] ]@
Line 4,175 ⟶ 4,283:
/// Dictionary of units for each square
let units =
[|for s in squares do s, [| for u in unitlist do if u |> Array.contains s then u |] |]
|> Map.ofList
 
/// Dictionary of all peer squares in the relevant units wrt square in question
let peers =
[| for s in squares do units[s] |> Array.concat |> Array.distinct |> Array.except [s] |> tuple2 s]
|> Map.ofList
 
/// folds folder returning Some on completion or returns None if not
/// Eliminate d from values[s] and propagate when values = 1.
let rec all folder state source =
/// Return Some values, except return None if a contradiction is detected.
match state, source with
let rec eliminate (values:Map<_,_>) s d =
let| peerElimNone, (vx:Map<_,_ ->) =None
| Some st, [] -> Some st
match Seq.length vx[s] with // (1) If a square s is reduced to one value d, then eliminate d from the peers.
| Some st , hd::rest -> folder st hd |> 0(fun st1 -> None //all removedfolder lastst1 valuerest)
 
| 1 -> peers[s] |> List.ofArray |> all (fun st s2 -> eliminate st s2 (vx[s] |> Seq.head) ) (Some vx)
/// Assign digit d to values[s] and propagate (via eliminate)
| _ -> Some vx
/// Return Some values, except None if a contradiction is detected.
let rec assign (values:int[][]) (s) d =
values[s]
|> Array.filter ((<>)d)
|> List.ofArray |> all (fun vx d1 -> eliminate vx s d1) (Some values)
/// Eliminate digit d from values[s] and propagate when values[s] size is 1.
let unitsElim vx =
/// Return Some values, except return None if a contradiction is detected.
units[s] // (2) If a unit u is reduced to only one place for a value d, then put it there.
and eliminate (values:int[][]) s d =
|> List.ofArray |> all (fun (st:Map<_,_>) u ->
let peerElim (values1:int[][]) = // If a square s is reduced to one value d, then *eliminate* d from the peers.
let dKeys = [for s in u do if st[s] |> Seq.contains d then s]
match Seq.length dKeysvalues1[s] with
| 0 -> None // contradiction - removed last value
| 1 -> peers[s] |> List.ofArray |> all (fun vx1 s1 -> eliminate vx1 s1 (values1[s] |> Seq.head) ) (Some values1)
| _ -> Some values1
let unitsElim values1 = // If a unit u is reduced to only one place for a value d, then *assign* it there.
units[s]
|> List.ofArray
|> all (fun (vx1:int[][]) u ->
let sx = [for s in u do if vx1[s] |> Seq.contains d then s]
match Seq.length sx with
| 0 -> None
| 1 -> assign stvx1 (Seq.head dKeyssx) d
| _ -> Some stvx1) (Some vxvalues1)
 
match values[s] |> Seq.contains d with
| false -> Some values // Already eliminated, nothing to do
| true ->
let values2 = values |> Map.change [s] (Option.map (fun dx <-> dx values[s]|> Array.filter ((<>)d)))
peerElim values2values
|> functionpeerElim
| None -> None // fromOption.bind peersunitsElim
| Some values3 -> unitsElim values3
 
/// Eliminate all the other values (except d) from values[s] and propagate.
/// Return Some values, except None if a contradiction is detected.
and assign (values:Map<_,_>) (s) d =
values[s]
|> Seq.filter ((<>)d)
|> List.ofSeq |> all (fun st d2 -> eliminate st s d2) (Some values)
 
/// Convert grid into a Map of {square: char} with "0","."or"," for empties.
Line 4,222 ⟶ 4,335:
if Seq.length cells = 81 then cells |> Seq.zip squares |> Map.ofSeq |> Some else None
 
/// Convert grid to a Map of constraint popagatedpropagated possible values, or return None if a contradiction is detected.
let applyCPS (parsedGrid:Map<_,int_>) =
let values = [| for s in squares do s, digits]|> Map.ofList|]
parsedGrid
|> (Seq.filter (fun (KeyValue(_,d)) -> digits |> Seq.contains d)
|> List.ofSeq
>> List.ofSeq >> all (fun vx (KeyValue(s,d)) -> assign vx s d) (Some values) )
|> all (fun vx (KeyValue(s,d)) -> assign vx s d) (Some values)
 
/// Calculate string centre for each square - which can contain more than 1 digit when debugging
Line 4,238 ⟶ 4,352:
 
/// Display these values as a 2-D grid. Used for debugging
let prettyPrint (values:Map<_,_>int[][]) =
let asString = Seq.map string >> String.concat ""
let width = 1 + ([for s in squares do Seq.length values[s]] |> List.max)
Line 4,244 ⟶ 4,358:
[for r in rows do
for c in cols do
sprintf "%s%s" (centre (asString values[key r c]) width) (if List.contains c [3;6] then "|" else "")
sprintf "\n%s"(if List.contains r [3;6] then line else "") ]
|> String.concat ""
Line 4,250 ⟶ 4,364:
/// Outputs single line puzzle with 0 as empty squares
let asString values = values |> Map.toSeq |> Seq.map (snd>>string) |> String.concat ""
 
let copy values = values |> Array.map Array.copy
 
/// Using depth-first search and propagation, try all possible values.
let rec search (values:Map<_,_>int[][])=
let rec some = function
| [] -> None // No Solution
| s::sx ->
values[s]
|> Seq.tryPick (fun d -> assign values s d >>= search)
|> function
| Some seqx when Seq.isEmpty seqx -> some sx // reduces calls to find fewest possibilities
| Some seq -> Some seq // returns Some in previous stack's tryPick
| _ -> None // returns None in previous stack's tryPick
// Choose the unfilled square s with the fewest possibilities
[for s in squares do if Seq.length values[s] > 1 then Seq.length values[s] ,s]
|> function
| [] -> Some values // Solved!
| list -> list// |>tryPick List.sortBy~ fst |> List.map snd |>Norvig's `some`
list |> List.minBy fst
|> fun (_,s) -> values[s] |> Seq.tryPick (fun d -> assign (copy values) s d |> (Option.bind search))
 
let run n g f = parseGrid >> function None -> n | Some m -> f m |> g
// Core API
let run error stringF applyF = parseGrid >> function None -> error | Some m -> applyF m |> stringF
let solver = run "Parse Error" (Option.fold (fun _ t -> t |> prettyPrint) "No Solution")
let solveNoSearch: string -> string = solver applyCPS
let solveWithSearch: string -> string = solver (applyCPS >> (Option.bind search))
let solveWithSearchToMapOnly:string -> Map<int,int[]>[] option = run None id (applyCPS >> (Option.bind search)) </langsyntaxhighlight>
'''Usage'''<langsyntaxhighlight lang="fsharp">open System
open SudokuCPSSudokuCPSArray
open System.Diagnostics
open System.IO
Line 4,291 ⟶ 4,398:
printfn "Try again with search:"
simple |> run "Parse Error" prettyPrint (Map.toSeq >> Seq.map (fun (k,v) -> k , string v) >> Map.ofSeq) |> printfn "%s"
simple |> solveWithSearch |> printfn "%s"
Line 4,307 ⟶ 4,413:
if Seq.length argv = 1 then
let num = argv[0] |> int
printfn $"First {num} puzzles in sudoku17 (http://staffhome.ecm.uwa.edu.au/~00013890/sudoku17)"
File.ReadLines(@"sudoku17.txt") |> Seq.take num |>Array.ofSeq
else
printfn $"All puzzles in sudoku17 (http://staffhome.ecm.uwa.edu.au/~00013890/sudoku17)"
File.ReadLines(@"sudoku17.txt") |>Array.ofSeq
watch.Start()
Line 4,317 ⟶ 4,423:
if result |> Seq.forall Option.isSome then
let total = watch.ElapsedMilliseconds
printfnlet $"\nPuzzles:{result.Length},avg Total:%.2f{((float)total)/1000.0}= s, Average:%.2f{((float total) /(float result.Length))} ms"
printfn $"\nPuzzles:{result.Length}, Total:%.2f{((float)total)/1000.0} s, Average:%.2f{avg} ms"
else
printfn "Some sudoku17 puzzles failed"
Console.ReadKey() |> ignore
0</langsyntaxhighlight>
{{Output}}Timings run on i7500U @2.75Ghz CPU, 16GB RAM<pre>Easy board solution automatic with constraint propagation
4 8 3 |9 2 1 |6 5 7
Line 4,350 ⟶ 4,457:
 
Try again with search:
4 0 0 |0 0 0 |8 0 5
0 3 0 |0 0 0 |0 0 0
0 0 0 |7 0 0 |0 0 0
------+------+------
0 2 0 |0 0 0 |0 6 0
0 0 0 |0 8 0 |4 0 0
0 0 0 |0 1 0 |0 0 0
------+------+------
0 0 0 |6 0 3 |0 7 0
5 0 0 |2 0 0 |0 0 0
1 0 4 |0 0 0 |0 0 0
 
4 1 7 |3 6 9 |8 2 5
6 3 2 |1 5 8 |9 4 7
Line 4,387 ⟶ 4,482:
5 9 8 |7 3 6 |2 4 1
 
Elapsed milliseconds = 118 ms
All puzzles in sudoku17 (http://staffhome.ecm.uwa.edu.au/~00013890/sudoku17)
 
Puzzles:49151, Total:33280.5099 s, Average:61.7665 ms</pre>
 
===SLPsolve===
<langsyntaxhighlight lang="fsharp">
// Solve Sudoku Like Puzzles. Nigel Galloway: September 6th., 2018
let fN y n g=let _q n' g'=[for n in n*n'..n*n'+n-1 do for g in g*g'..g*g'+g-1 do yield (n,g)]
Line 4,422 ⟶ 4,517:
List.map2(fun n g->List.map(fun(n',g')->((n',g'),n))g) (List.rev n) g|>List.concat|>List.sortBy (fun ((_,n),_)->n)|>List.groupBy(fun ((n,_),_)->n)|>List.sortBy(fun(n,_)->n)
|>List.iter(fun (_,n)->n|>Seq.fold(fun z ((_,g),v)->[z..g-1]|>Seq.iter(fun _->printf " |");printf "%s|" v; g+1 ) 0 |>ignore;printfn "")
</syntaxhighlight>
</lang>
'''Usage:'''
Given sud1.csv:
Line 4,437 ⟶ 4,532:
</pre>
then
<langsyntaxhighlight lang="fsharp">
let n=SLPsolve (fE ([1..9]|>List.map(string)) 9 3 3 "sud1.csv")
printSLP ([1..9]|>List.map(string)) (Seq.item 0 n)
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 4,456 ⟶ 4,551:
=={{header|Forth}}==
{{works with|4tH|3.60.0}}
<langsyntaxhighlight lang="forth">include lib/interprt.4th
include lib/istype.4th
include lib/argopen.4th
Line 4,819 ⟶ 4,914:
;
 
sudoku</langsyntaxhighlight>
 
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
This implementation uses a brute force method. The subroutine <code>solve</code> recursively checks valid entries using the rules defined in the function <code>is_safe</code>. When <code>solve</code> is called beyond the end of the sudoku, we know that all the currently entered values are valid. Then the result is displayed.
<langsyntaxhighlight lang="fortran">program sudoku
 
implicit none
Line 4,921 ⟶ 5,016:
end subroutine pretty_print
 
end program sudoku</langsyntaxhighlight>
{{out}}<pre>
+-----+-----+-----+
Line 4,954 ⟶ 5,049:
=={{header|FreeBASIC}}==
{{trans|VBA}}
<langsyntaxhighlight lang="freebasic">Dim Shared As Integer cuadricula(9, 9), cuadriculaResuelta(9, 9)
 
Function isSafe(i As Integer, j As Integer, n As Integer) As Boolean
Line 5,040 ⟶ 5,135:
If (i Mod 3 = 0) Then Print !"\n---------+---------+---------" Else Print
Next i
Sleep</langsyntaxhighlight>
{{out}}
<pre>
Line 5,062 ⟶ 5,157:
=={{header|FutureBasic}}==
First is a short version:
<langsyntaxhighlight 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;
mutStr = CFStringCreateMutable( kCFAllocatorDefault, 0 );
short solve_sudoku( short i )
 
{
for (i = 0; i < 9; i++)
short {r, c;
for (j = 0; j < 9; j++)
if (i < 0) return {0;
else if (i >= 81) return -1;
CFStringAppendFormat( mutStr, NULL, (CFStringRef)@" %d", sudoku[i][j] );
}
r = i / 9;
CFStringAppendFormat( mutStr, NULL, (CFStringRef)@"\r" );
c }= i % 9;
return( mutStr );
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 ( 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,152 ⟶ 5,244:
toolbox fn print_sudoku() = CFMutableStringRef
 
dim as short solution
dim as CFMutableStringRef cfRef
 
gC = " "
Line 5,164 ⟶ 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
 
</lang>
HandleEvents
</syntaxhighlight>
 
Output:
Line 5,203 ⟶ 5,297:
More code in this one, but faster execution:
<pre>
include "ConsoleWindow"
include "Tlbx Timer.incl"
 
begin globals
_digits = 9
Line 5,214 ⟶ 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,576 ⟶ 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,587 ⟶ 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 5,633 ⟶ 5,701:
Input to function solve is an 81 character string.
This seems to be a conventional computer representation for Sudoku puzzles.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 5,834 ⟶ 5,902:
}
c.r.l, c.l.r = &c.x, &c.x
}</langsyntaxhighlight>
{{out}}
<pre>
Line 5,867 ⟶ 5,935:
 
Imprime todas las soluciones posibles, sale con un error, pero funciona.
<langsyntaxhighlight lang="golfscript">
'Solution:'
;'2 8 4 3 7 5 1 6 9
Line 5,881 ⟶ 5,949:
 
~]{:@0?:^~!{@p}*10,@9/^9/=-@^9%>9%-@3/^9%3/>3%3/^27/={+}*-{@^<\+@1^+>+}/1}do
</syntaxhighlight>
</lang>
 
=={{header|Groovy}}==
Line 5,889 ⟶ 5,957:
 
I consider this a "brute force" solution of sorts, in that it is the same method I use when solving Sudokus manually.
<langsyntaxhighlight lang="groovy">final CELL_VALUES = ('1'..'9')
class GridException extends Exception {
Line 5,956 ⟶ 6,024:
}
grid
}</langsyntaxhighlight>
'''Test/Benchmark Cases'''
 
Mentions of ''"exceptionally difficult" example in Wikipedia'' refer to this (former) page: [[https://en.wikipedia.org/w/index.php?title=Sudoku_solving_algorithms&oldid=410240496#Exceptionally_difficult_Sudokus_.28hardest_Sudokus.29 Exceptionally difficult Sudokus]]
<langsyntaxhighlight lang="groovy">def sudokus = [
//Used in Curry solution: ~ 0.1 seconds
'819..5.....2...75..371.4.6.4..59.1..7..3.8..2..3.62..7.5.7.921..64...9.....2..438',
Line 6,023 ⟶ 6,091:
solution.each { println it }
println "\nELAPSED: ${elapsed} seconds"
}</langsyntaxhighlight>
 
{{out}} (last only):
Line 6,057 ⟶ 6,125:
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">public class Sudoku
{
private int mBoard[][];
Line 6,175 ⟶ 6,243:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 6,214 ⟶ 6,282:
====ES6====
 
<langsyntaxhighlight JavaScriptlang="javascript">//-------------------------------------------[ Dancing Links and Algorithm X ]--
/**
* The doubly-doubly circularly linked data object.
Line 6,487 ⟶ 6,555:
search(H, []);
};
</syntaxhighlight>
</lang>
 
<syntaxhighlight lang="javascript">[
<lang JavaScript>[
'819..5.....2...75..371.4.6.4..59.1..7..3.8..2..3.62..7.5.7.921..64...9.....2..438',
'53..247....2...8..1..7.39.2..8.72.49.2.98..7.79.....8.....3.5.696..1.3...5.69..1.',
Line 6,514 ⟶ 6,582:
let s = new Array(Math.pow(n, 4)).fill('.').join('');
reduceGrid(s);
</syntaxhighlight>
</lang>
 
<pre>+-------+-------+-------+
Line 6,543 ⟶ 6,611:
| 7 8 2 | 6 9 3 | 5 4 1 |
+-------+-------+-------+
</pre>
 
=={{header|jq}}==
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq'''
 
'''Also works with fq, a Go implementation of a large subset of jq'''
 
The two solutions presented here take advantage of jq's built-in backtracking
mechanism.
 
The first solution uses a naive backtracking algorithm which can readily be modified to include more sophisticated
strategies.
 
The second solution modifies `next_row` to use a simple greedy algorithm,
namely, "select the row with the fewest gaps".
 
For the `tarx0134` problem (taken from the
[https://en.wikipedia.org/w/index.php?title=Sudoku_solving_algorithms#Exceptionally_difficult_Sudokus_.28hardest_Sudokus.29 Wikipedia collection] but googleable by that name),
the running time (u+s) is reduced from 264s to 180s on my 3GHz machine.
The memory usage statistics as produced by `/usr/bin/time -lp`
are also shown in the output section below.
<syntaxhighlight lang=jq>
## Utility Functions
def div($b): (. - (. % $b)) / $b;
 
def count(s): reduce s as $_ (0; .+1);
 
def row($i): .[$i];
 
def col($j): transpose | row($j);
 
# pretty print
def pp: .[:3][],"", .[3:6][], "", .[6:][];
 
# Input: 9 x 9 matrix
# Output: linear array corresponding to the specified 3x3 block using IO=0:
# 0,0 0,1 0,2
# 1,0 1,1 1,2
# 2,0 2,1 2,2
def block($i;$j):
def x: range(0;3) + 3*$i;
def y: range(0;3) + 3*$j;
[.[x][y]];
 
# Output: linear block containing .[$i][$j]
def blockOf($i;$j):
block($i|div(3); $j|div(3));
 
# Input: the entire Sudoku matrix
# Output: the update matrix after solving for row $i
def solveRow($i):
def s:
(.[$i] | index(0)) as $j
| if $j
then ((( [range(1;10)] - row($i)) - col($j)) - blockOf($i;$j) ) as $candidates
| if $candidates|length == 0 then empty
else $candidates[] as $x
| .[$i][$j] = $x
| s
end
else .
end;
s;
 
def distinct: map(select(. != 0)) | length - (unique|length) == 0;
 
# Is the Sudoku valid?
def valid:
. as $in
| length as $l
| all(.[]; distinct) and
all( range(0;9); . as $i | $in | col($i) | distinct ) and
all( range(0;3); . as $i | all(range(0;3); . as $j
| $in | block($i;$j) | distinct ));
 
# input: the full puzzle in its current state
# output: null if there is no candidate next row
def next_row:
first( range(0; length) as $i | select(row($i)|index(0)) | $i) // null;
 
def solve(problem):
def s:
next_row as $ix
| if $ix then solveRow($ix) | s
else .
end;
if problem|valid then first(problem|s) | pp
else "The Sukoku puzzle is invalid."
end;
 
# Rating Program: dukuso's suexratt
# Rating: 3311
# Poster: tarek
# Label: tarx0134
# ........8..3...4...9..2..6.....79.......612...6.5.2.7...8...5...1.....2.4.5.....3
def tarx0134:
[[0,0,0,0,0,0,0,0,8],
[0,0,3,0,0,0,4,0,0],
[0,9,0,0,2,0,0,6,0],
[0,0,0,0,7,9,0,0,0],
[0,0,0,0,6,1,2,0,0],
[0,6,0,5,0,2,0,7,0],
[0,0,8,0,0,0,5,0,0],
[0,1,0,0,0,0,0,2,0],
[4,0,5,0,0,0,0,0,3]];
 
# An invalid puzzle, for checking `valid`:
def unsolvable:
[[3,9,4,3,0,2,6,7,0],
[0,0,0,3,0,0,4,0,0],
[5,0,0,6,9,0,0,2,0],
[0,4,5,0,0,0,9,0,0],
[6,0,0,0,0,0,0,0,7],
[0,0,7,0,0,0,5,8,0],
[0,1,0,0,6,7,0,0,8],
[0,0,9,0,0,8,0,0,0],
[0,2,6,4,0,0,7,3,5]] ;
 
solve(tarx0134)
</syntaxhighlight>
 
====Greedy Algorithm====
Replace `def next_row:` with the following definition:
<syntaxhighlight lang=jq>
# select a row with the fewest number of unknowns
def next_row:
length as $len
| . as $in
| reduce range(0;length) as $i ([];
. + [ [ count( $in[$i][] | select(. != 0)), $i] ] )
| map(select(.[0] != $len))
| if length == 0 then null
else max_by(.[0]) | .[1]
end ;
</syntaxhighlight>
 
{{output}}
For the naive next_row:
<pre>
[6,2,1,9,4,3,7,5,8]
[7,8,3,6,1,5,4,9,2]
[5,9,4,7,2,8,3,6,1]
 
[1,4,2,8,7,9,6,3,5]
[3,5,7,4,6,1,2,8,9]
[8,6,9,5,3,2,1,7,4]
 
[2,3,8,1,9,7,5,4,6]
[9,1,6,3,5,4,8,2,7]
[4,7,5,2,8,6,9,1,3]
 
# Summary performance statistics:
user 260.89
sys 3.32
2240512 maximum resident set size
1302528 peak memory footprint
</pre>
 
For the greedy next_row algorithm, jq produces the same solution
with the following performance statistics:
<pre>
user 177.94
sys 2.12
2224128 maximum resident set size
1277952 peak memory footprint
</pre>
gojq stats for the greedy algorithm:
<pre>
user 62.19
sys 7.44
7458418688 maximum resident set size
7683284992 peak memory footprint
</pre>
 
fq stats for the greedy algorithm:
<pre>
user 73.56
sys 5.34
6084091904 maximum resident set size
6436892672 peak memory footprint
</pre>
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">function check(i, j)
id, im = div(i, 9), mod(i, 9)
jd, jm = div(j, 9), mod(j, 9)
Line 6,569 ⟶ 6,818:
for i in 1:81
if grid[i] == 0
t = Dict{Int64, VoidNothing}()
 
for j in 1:81
Line 6,612 ⟶ 6,861:
0, 5, 0, 6, 9, 0, 0, 1, 0]
 
solve_sudoku(display, grid)</langsyntaxhighlight>
{{out}}
<pre>
Line 6,630 ⟶ 6,879:
=={{header|Kotlin}}==
{{trans|C++}}
<langsyntaxhighlight lang="scala">// version 1.2.10
 
class Sudoku(rows: List<String>) {
Line 6,713 ⟶ 6,962:
)
Sudoku(rows).solve()
}</langsyntaxhighlight>
 
{{out}}
Line 6,748 ⟶ 6,997:
=={{header|Lua}}==
===without FFI, slow===
<langsyntaxhighlight lang="lua">--9x9 sudoku solver in lua
--based on a branch and bound solution
--fields are not tried in plain order
Line 6,930 ⟶ 7,179:
if x then
return printer(x)
end</langsyntaxhighlight>
Input:
<pre>
Line 6,962 ⟶ 7,211:
Time with luajit: 9.245s
===with FFI, fast===
<langsyntaxhighlight lang="lua">#!/usr/bin/env luajit
ffi=require"ffi"
local printf=function(fmt, ...) io.write(string.format(fmt, ...)) end
Line 7,030 ⟶ 7,279:
... .8. .79
]])
end</langsyntaxhighlight>
{{out}}
<pre>> time ./sudoku_fast.lua
Line 7,049 ⟶ 7,298:
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight lang="mathematica">solve[sudoku_] :=
NestWhile[
Join @@ Table[
Line 7,058 ⟶ 7,307:
Extract[Partition[s, {3, 3}], Quotient[#, 3, -2]]]} & /@
Position[s, 0, {2}],
Length@Last@# &], {s, #}] &, {sudoku}, ! FreeQ[#, 0] &]</langsyntaxhighlight>
Example:
<syntaxhighlight lang="text">solve[{{9, 7, 0, 3, 0, 0, 0, 6, 0},
{0, 6, 0, 7, 5, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 8, 0, 5, 0},
Line 7,068 ⟶ 7,317:
{7, 0, 0, 0, 2, 5, 0, 0, 0},
{0, 0, 2, 0, 1, 0, 0, 0, 8},
{0, 4, 0, 0, 0, 7, 3, 0, 0}}]</langsyntaxhighlight>
{{out}}
<pre>{{{9, 7, 5, 3, 4, 2, 8, 6, 1}, {8, 6, 1, 7, 5, 9, 4, 3, 2}, {3, 2, 4,
Line 7,079 ⟶ 7,328:
 
For this to work, this code must be placed in a file named "sudokuSolver.m"
<langsyntaxhighlight MATLABlang="matlab">function solution = sudokuSolver(sudokuGrid)
 
%Define what each of the sub-boxes of the sudoku grid are by defining
Line 7,431 ⟶ 7,680:
%% End of program
end %end sudokuSolver</langsyntaxhighlight>
[http://www.menneske.no/sudoku/eng/showpuzzle.html?number=6903541 Test Input]:
All empty cells must have a value of NaN.
<langsyntaxhighlight MATLABlang="matlab">sudoku = [NaN NaN NaN NaN 8 3 9 NaN NaN
1 NaN NaN NaN NaN NaN NaN 3 NaN
NaN NaN 4 NaN NaN NaN NaN 7 NaN
Line 7,442 ⟶ 7,691:
NaN 2 NaN NaN NaN NaN NaN NaN NaN
NaN 8 NaN NaN NaN 9 2 NaN NaN
NaN NaN NaN 2 5 NaN NaN NaN 6]</langsyntaxhighlight>
[http://www.menneske.no/sudoku/eng/solution.html?number=6903541 Output]:
<langsyntaxhighlight MATLABlang="matlab">solution =
 
7 6 5 4 8 3 9 2 1
Line 7,454 ⟶ 7,703:
9 2 6 1 4 7 5 8 3
5 8 1 3 6 9 2 4 7
4 7 3 2 5 8 1 9 6</langsyntaxhighlight>
 
=={{header|Nim}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang="nim">{.this: self.}
 
type
Line 7,532 ⟶ 7,781:
var puzzle = Sudoku()
puzzle.init(rows)
puzzle.solve()</langsyntaxhighlight>
 
{{out}}
Line 7,565 ⟶ 7,814:
=={{header|OCaml}}==
uses the library [http://ocamlgraph.lri.fr/index.en.html ocamlgraph]
<langsyntaxhighlight lang="ocaml">(* Ocamlgraph demo program: solving the Sudoku puzzle using graph coloring
Copyright 2004-2007 Sylvain Conchon, Jean-Christophe Filliatre, Julien Signoles
 
Line 7,634 ⟶ 7,883:
module C = Coloring.Mark(G)
 
let () = C.coloring g 9; display ()</langsyntaxhighlight>
 
=={{header|Oz}}==
Using built-in constraint propagation and search.
<langsyntaxhighlight lang="oz">declare
%% a puzzle is a function that returns an initial board configuration
fun {Puzzle1}
Line 7,721 ⟶ 7,970:
end
in
{Inspect {Solve Puzzle1}.1}</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
 
Build plugin for PARI's function interface from C code: sudoku.c
<langsyntaxhighlight Clang="c">#include <pari/pari.h>
 
typedef int SUDOKU [9][9];
Line 7,796 ⟶ 8,045:
return gen_0; /* no solution */
}
</syntaxhighlight>
</lang>
Compile plugin: gcc -O2 -Wall -fPIC -shared sudoku.c -o libsudoku.so -lpari
 
Install plugin from home directory and play:
<langsyntaxhighlight lang="parigp">install("plug_sudoku", "G", "sudoku", "~/libsudoku.so")</langsyntaxhighlight>
 
Output:<pre> gp > S=[5,3,0,0,7,0,0,0,0;6,0,0,1,9,5,0,0,0;0,9,8,0,0,0,0,6,0;8,0,0,0,6,0,0,0,3;4,0,0,8,0,3,0,0,1;7,0,0,0,2,0,0,0,6;0,6,0,0,0,0,2,8,0;0,0,0,4,1,9,0,0,5;0,0,0,0,8,0,0,7,9]
Line 7,828 ⟶ 8,077:
{{works with|Free Pascal}}
Simple backtracking implimentation, therefor it must be fast to be competetive.With doReverse = true same sequence for trycell. nearly 5 times faster than [[Sudoku#C|C]]-Version.
<langsyntaxhighlight lang="pascal">Program soduko;
{$IFDEF FPC}
{$CODEALIGN proc=16,loop=8}
Line 8,084 ⟶ 8,333:
Outfield(solF);
writeln(86400*1000*(T1-T0)/k:10:3,' ms Test calls :',callCnt/k:8:0);
end.</langsyntaxhighlight>
{{out}}
<pre>
Line 8,120 ⟶ 8,369:
 
=={{header|Perl}}==
<langsyntaxhighlight Perllang="perl">#!/usr/bin/perl
use integer;
use strict;
Line 8,159 ⟶ 8,408:
}
}
solve();</langsyntaxhighlight>
{{out}}
<pre>
Line 8,177 ⟶ 8,426:
=={{header|Phix}}==
Simple brute force solution. Generally quite good but will struggle on some puzzles (eg see "the beast" below)
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>sequence board = split("""
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
.......39
<span style="color: #004080;">sequence</span> <span style="color: #000000;">board</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"""
.....1..5
..3.5.8...39
..8.9..1.6.5
.7.3.5.2.8..
1 ..4.8.9...6
.7.9.8.2..5.
1.2.4...6..
4 ..79.8..5..""",'\n')
.2....6..
 
4..7....."""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">)</span>
function valid_move(integer y, integer x, integer ch)
for i=1 to 9 do
<span style="color: #008080;">function</span> <span style="color: #000000;">valid_move</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span>
if ch=board[i][x] then return 0 end if
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
if ch=board[y][i] then return 0 end if
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
y -= mod(y-1,3)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
x -= mod(x-1,3)
<span style="color: #000000;">y</span> <span style="color: #0000FF;">-=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
for ys=y to y+2 do
<span style="color: #000000;">x</span> <span style="color: #0000FF;">-=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
for xs=x to x+2 do
<span style="color: #008080;">for</span> <span style="color: #000000;">ys</span><span style="color: #0000FF;">=</span><span style="color: #000000;">y</span> <span style="color: #008080;">to</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span> <span style="color: #008080;">do</span>
if ch=board[ys][xs] then return 0 end if
<span style="color: #008080;">for</span> <span style="color: #000000;">xs</span><span style="color: #0000FF;">=</span><span style="color: #000000;">x</span> <span style="color: #008080;">to</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span> <span style="color: #008080;">do</span>
end for
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ys</span><span style="color: #0000FF;">][</span><span style="color: #000000;">xs</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
return 1
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
sequence solution = {}
 
<span style="color: #004080;">sequence</span> <span style="color: #000000;">solution</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
procedure brute_solve()
for y=1 to 9 do
<span style="color: #008080;">procedure</span> <span style="color: #000000;">brute_solve</span><span style="color: #0000FF;">()</span>
for x=1 to 9 do
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
if board[y][x]<='0' then
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
for ch='1' to '9' do
<span style="color: #008080;">if</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]<=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">then</span>
if valid_move(y,x,ch) then
<span style="color: #008080;">for</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'1'</span> <span style="color: #008080;">to</span> <span style="color: #008000;">'9'</span> <span style="color: #008080;">do</span>
board[y][x] = ch
<span style="color: #008080;">if</span> <span style="color: #000000;">valid_move</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
brute_solve()
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ch</span>
board[y][x] = ' '
if length(solution)<span thenstyle="color: return#000000;">brute_solve</span><span endstyle="color: if#0000FF;">()</span>
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">' '</span>
end if
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end if
<span style="color: #008080;">return</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
solution = board -- (already solved case)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end procedure
<span style="color: #000000;">solution</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (already solved case)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
atom t0 = time()
brute_solve()
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
printf(1,"%s\n(solved in %3.2fs)\n",{join(solution,"\n"),time()-t0})</lang>
<span style="color: #000000;">brute_solve</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n(solved in %3.2fs)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 8,244 ⟶ 8,496:
contains 339 puzzles, can be run as a command-line or gui program, check for multiple solutions, and produce
a more readable single-puzzle output (example below).
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>-- Working directly on 81-character strings ultimately proves easier: Originally I
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
-- just wanted to simplify the final display, but later I realised that a 9x9 grid
<span style="color: #000080;font-style:italic;">-- Working directly on 81-character strings ultimately proves easier: Originally I
-- encourages laborious indexing/looping everwhere whereas using a flat 81-element
-- just wanted to simplify the final display, but later I realised that a 9x9 grid
-- approach encourages precomputation of index sets, and once you commit to that,
-- encourages laborious indexing/looping everwhere whereas using a flat 81-element
-- the rest of the code starts to get a whole lot cleaner. Below we create 27+18
-- approach encourages precomputation of index sets, and once you commit to that,
-- sets and 5 tables of lookup indexes to locate them quickly.
-- the rest of the code starts to get a whole lot cleaner. Below we create 27+18
 
-- sets and 5 tables of lookup indexes to locate them quickly.</span>
sequence nines = {}, -- will be 27 in total
cols = repeat(0,9*9), -- remainder(i-1,9)+1
<span style="color: #004080;">sequence</span> <span style="color: #000000;">nines</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000080;font-style:italic;">-- will be 27 in total</span>
rows = repeat(0,9*9), -- floor((i-1)/9)+10
<span style="color: #000000;">cols</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- remainder(i-1,9)+1</span>
squares = repeat(0,9*9),
<span style="color: #000000;">rows</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- floor((i-1)/9)+10</span>
sixes = {}, -- will be 18 in total
<span style="color: #000000;">squares</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span>
dotcol = repeat(0,9*9), -- same col, diff square
<span style="color: #000000;">sixes</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000080;font-style:italic;">-- will be 18 in total</span>
dotrow = repeat(0,9*9) -- same row, diff square
<span style="color: #000000;">dotcol</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- same col, diff square</span>
 
<span style="color: #000000;">dotrow</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- same row, diff square</span>
procedure set_nines()
sequence nine, six
<span style="color: #008080;">procedure</span> <span style="color: #000000;">set_nines</span><span style="color: #0000FF;">()</span>
integer idx, ndx
<span style="color: #004080;">sequence</span> <span style="color: #000000;">nine</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">six</span>
for x=0 to 8 do -- columns
<span style="color: #004080;">integer</span> <span style="color: #000000;">idx</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ndx</span>
nine = {}
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- columns</span>
ndx = length(nines)+1
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
for y=1 to 81 by 9 do
<span style="color: #000000;">ndx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
idx = y+x
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">81</span> <span style="color: #008080;">by</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
nine = append(nine,idx)
<span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span>
cols[idx] = ndx
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">,</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #000000;">cols</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ndx</span>
nines = append(nines,nine)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #000000;">nines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">)</span>
for y=1 to 81 by 9 do -- rows
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
nine = {}
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">81</span> <span style="color: #008080;">by</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- rows</span>
ndx = length(nines)+1
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
for x=0 to 8 do
<span style="color: #000000;">ndx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
idx = y+x
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
nine = append(nine,idx)
<span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span>
rows[idx] = ndx
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">,</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #000000;">rows</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ndx</span>
nines = append(nines,nine)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #000000;">nines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">)</span>
if length(nines)!=18 then ?9/0 end if
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
for y=0 to 8 by 3 do -- small squares [19..27]
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">18</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
for x=0 to 8 by 3 do
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">by</span> <span style="color: #000000;">3</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- small squares [19..27]</span>
nine = {}
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">by</span> <span style="color: #000000;">3</span> <span style="color: #008080;">do</span>
ndx = length(nines)+1
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
for sy=y*9 to y*9+18 by 9 do
<span style="color: #000000;">ndx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
for sx=x to x+2 do
<span style="color: #008080;">for</span> <span style="color: #000000;">sy</span><span style="color: #0000FF;">=</span><span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span> <span style="color: #008080;">to</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">+</span><span style="color: #000000;">18</span> <span style="color: #008080;">by</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
idx = sy+sx+1
<span style="color: #008080;">for</span> <span style="color: #000000;">sx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">x</span> <span style="color: #008080;">to</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span> <span style="color: #008080;">do</span>
nine = append(nine,idx)
<span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sy</span><span style="color: #0000FF;">+</span><span style="color: #000000;">sx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
squares[idx] = ndx
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">,</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #000000;">squares</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ndx</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
nines = append(nines,nine)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #000000;">nines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
if length(nines)!=27 then ?9/0 end if
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
for i=1 to 9*9 do
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">27</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
six = {}
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
nine = nines[cols[i]] -- dotcol
<span style="color: #000000;">six</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
for j=1 to length(nine) do
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">cols</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]</span> <span style="color: #000080;font-style:italic;">-- dotcol</span>
if squares[i]!=squares[nine[j]] then
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
six = append(six,nine[j])
<span style="color: #008080;">if</span> <span style="color: #000000;">squares</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">squares</span><span style="color: #0000FF;">[</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]]</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">six</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">six</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
ndx = find(six,sixes)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
if ndx=0 then
<span style="color: #000000;">ndx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">six</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">)</span>
sixes = append(sixes,six)
<span style="color: #008080;">if</span> <span style="color: #000000;">ndx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
ndx = length(sixes)
<span style="color: #000000;">sixes</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">,</span><span style="color: #000000;">six</span><span style="color: #0000FF;">)</span>
end if
<span style="color: #000000;">ndx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">)</span>
dotcol[i] = ndx
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
six = {}
<span style="color: #000000;">dotcol</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ndx</span>
nine = nines[rows[i]] -- dotrow
<span style="color: #000000;">six</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
for j=1 to length(nine) do
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">rows</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]</span> <span style="color: #000080;font-style:italic;">-- dotrow</span>
if squares[i]!=squares[nine[j]] then
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
six = append(six,nine[j])
<span style="color: #008080;">if</span> <span style="color: #000000;">squares</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">squares</span><span style="color: #0000FF;">[</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]]</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">six</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">six</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
ndx = find(six,sixes)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
if ndx=0 then
<span style="color: #000000;">ndx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">six</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">)</span>
sixes = append(sixes,six)
<span style="color: #008080;">if</span> <span style="color: #000000;">ndx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
ndx = length(sixes)
<span style="color: #000000;">sixes</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">,</span><span style="color: #000000;">six</span><span style="color: #0000FF;">)</span>
end if
<span style="color: #000000;">ndx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">)</span>
dotrow[i] = ndx
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #000000;">dotrow</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ndx</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
set_nines()
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
 
<span style="color: #000000;">set_nines</span><span style="color: #0000FF;">()</span>
integer improved = 0
 
<span style="color: #004080;">integer</span> <span style="color: #000000;">improved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
function eliminate_in(sequence valid, sequence set, integer ch)
for i=1 to length(set) do
<span style="color: #008080;">function</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span>
integer idx = set[i]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
if string(valid[idx]) then
<span style="color: #004080;">integer</span> <span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
integer k = find(ch,valid[idx])
<span style="color: #008080;">if</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span>
if k!=0 then
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">])</span>
valid[idx][k..k] = ""
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
improved = 1
<span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">..</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
end if
<span style="color: #000000;">improved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return valid
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">valid</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function test_comb(sequence chosen, sequence pool, sequence valid)
--
<span style="color: #008080;">function</span> <span style="color: #000000;">test_comb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">chosen</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pool</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">)</span>
-- (see deep_logic()/set elimination)
<span style="color: #000080;font-style:italic;">--
-- chosen is a sequence of length 2..4 of integers 1..9: ordered elements of pool.
-- (see deep_logic()/set elimination)
-- pool is a set of elements of the sequence valid, each of which is a sequence.
-- chosen is a sequence of length 2..4 of integers 1..9: ordered elements of pool.
-- (note that elements of valid in pool not in chosen are not necessarily sequences)
-- pool is a set of elements of the sequence valid, each of which is a sequence.
--
-- (note that elements of valid in pool not in chosen are not necessarily sequences)
sequence contains = repeat(0,9)
--</span>
integer ccount = 0, ch
<span style="color: #004080;">sequence</span> <span style="color: #000000;">contains</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span>
object set
<span style="color: #004080;">integer</span> <span style="color: #000000;">ccount</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ch</span>
 
<span style="color: #004080;">object</span> <span style="color: #000000;">set</span>
for i=1 to length(chosen) do
set = valid[pool[chosen[i]]]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
for j=1 to length(set) do
<span style="color: #000000;">set</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">[</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]]</span>
ch = set[j]-'0'
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
if contains[ch]=0 then
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span>
contains[ch] = 1
<span style="color: #008080;">if</span> <span style="color: #000000;">contains</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
ccount += 1
<span style="color: #000000;">contains</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
end if
<span style="color: #000000;">ccount</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
if ccount=length(chosen) then
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
for i=1 to length(pool) do
<span style="color: #008080;">if</span> <span style="color: #000000;">ccount</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
if find(i,chosen)=0 then
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">)</span>
set = valid[pool[i]]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
if sequence(set) then
<span style="color: #008080;">if</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
-- (reverse order so deletions don't foul indexes)
<span style="color: #000000;">set</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]</span>
for j=length(set) to 1 by -1 do
<span style="color: #008080;">if</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
ch = set[j]-'0'
<span style="color: #000080;font-style:italic;">-- (reverse order so deletions don't foul indexes)</span>
if contains[ch] then
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
valid[pool[i]][j..j] = ""
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span>
improved = 1
<span style="color: #008080;">if</span> <span style="color: #000000;">contains</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">..</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
end for
<span style="color: #000000;">improved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return valid
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
 
<span style="color: #008080;">return</span> <span style="color: #000000;">valid</span>
-- from [[Combinations#Phix|Combinations]]
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
-- from http://rosettacode.org/wiki/Combinations#Phix
function comb(sequence pool, valid, integer needed, done=0, sequence chosen={})
<span style="color: #000080;font-style:italic;">-- from [[Combinations#Phix|Combinations]]
-- (used by deep_logic()/set elimination)
-- from http://rosettacode.org/wiki/Combinations#Phix</span>
if needed=0 then -- got a full set
<span style="color: #008080;">function</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">pool</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">needed</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">done</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">chosen</span><span style="color: #0000FF;">={})</span>
return test_comb(chosen,pool,valid)
<span style="color: #000080;font-style:italic;">-- (used by deep_logic()/set elimination)</span>
end if
<span style="color: #008080;">if</span> <span style="color: #000000;">needed</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- got a full set</span>
if done+needed>length(pool) then return valid end if -- cannot fulfil
<span style="color: #008080;">return</span> <span style="color: #000000;">test_comb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">)</span>
-- get all combinations with and without the next item:
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
done += 1
<span style="color: #008080;">if</span> <span style="color: #000000;">done</span><span style="color: #0000FF;">+</span><span style="color: #000000;">needed</span><span style="color: #0000FF;">></span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">valid</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- cannot fulfil
if sequence(valid[pool[done]]) then
-- get all combinations with and without the next item:</span>
valid = comb(pool,valid,needed-1,done,append(chosen,done))
<span style="color: #000000;">done</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
end if
<span style="color: #008080;">if</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">[</span><span style="color: #000000;">done</span><span style="color: #0000FF;">]])</span> <span style="color: #008080;">then</span>
return comb(pool,valid,needed,done,chosen)
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">needed</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">done</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">),</span><span style="color: #000000;">done</span><span style="color: #0000FF;">))</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
 
<span style="color: #008080;">return</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">needed</span><span style="color: #0000FF;">,</span><span style="color: #000000;">done</span><span style="color: #0000FF;">,</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">)</span>
function deep_logic(string board, sequence valid)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
--
-- Create a grid of valid moves. Note this does not modify board, but instead creates
<span style="color: #008080;">function</span> <span style="color: #000000;">deep_logic</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">)</span>
-- sets of permitted values for each cell, which can also be and are used for hints.
<span style="color: #000080;font-style:italic;">--
-- Apply standard eliminations of known cells, then try some more advanced tactics:
-- Create a grid of valid moves. Note this does not modify board, but instead creates
--
-- sets of permitted values for each cell, which can also be and are used for hints.
-- 1) row/col elimination
-- Apply standard eliminations of known cells, then try some more advanced tactics:
-- If in any of the 9 small squares a number can only occur in one row or column,
--
-- then that number cannot occur in that row or column in two other corresponding
-- 1) row/col elimination
-- small squares. Example (this one with significant practical benefit):
-- If in any of the 9 small squares a number can only occur in one row or column,
-- 000|000|036
-- then that number cannot occur in that row or column in two other corresponding
-- 840|000|000
-- small squares. Example (this one with significant practical benefit):
-- 000|000|020
-- ---+---+---000|000|036
-- 000840|203000|000
-- 010000|000|700020
-- 000|600|400---+---+---
-- ---+---+---000|203|000
-- 000010|410000|050700
-- 003|000|200600|400
-- 600|000|000 <-- 3-+---+---
-- ^-- 3000|410|050
-- 003|000|200
-- Naively, the br can contain a 3 in the four corners, but looking at mid-right and
-- 600|000|000 &lt;-- 3
-- mid-bottom leads us to eliminating 3s in column 9 and row 9, leaving 7,7 as the
-- only square in the br that can be a 3. Uses dotcol and dotrow. ^-- 3
-- Without thisNaively, brutethe forcebr oncan thecontain abovea takes3 ~8sin the four corners, but withlooking itat mid-right ~0sand
-- mid-bottom leads us to eliminating 3s in column 9 and row 9, leaving 7,7 as the
--
-- only square in the br that can be a 3. Uses dotcol and dotrow.
-- 2) set elimination
-- Without this, brute force on the above takes ~8s, but with it ~0s
-- If in any 9-set there is a set of n blank squares that can only contain n digits,
--
-- then no other squares can contain those digits. Example (with some benefit):
-- 2) set elimination
-- 75.|.9.|.46
-- If in any 9-set there is a set of n blank squares that can only contain n digits,
-- 961|...|352
-- then no other squares can contain those digits. Example (with some benefit):
-- 4..|...|79.
-- ---+---+---75.|.9.|.46
-- 2961|..|6.1|..7352
-- 4.8.|...|.279.
-- 1..|328|.65---+---+---
-- ---+---+---2..|6.1|..7
-- ..8.|...|.2.. <-- [7,8] is {1,3,8}, [7,9] is {1,3,8}
-- 3.9|.1..|2328|.4 <-- [8,8] is {1,8}65
-- 84.|.3.|.79---+---+---
-- The three cells above the br 479 can only...|...|... &lt;-- [7,8] containis {1,3,8}, so[7,9] the .. of the .2.is {1,3,8}
-- in column 7 of that square are {5,6} (not3.9|...|2.4 1) and hence &lt;-- [98,48] must be ais {1.,8}
-- 84.|.3.|.79
-- (Relies on plain_logic to spot that "must be a 1", and serves as a clear example
-- The ofthree whycells thisabove routinethe shouldbr not479 bothercan toonly attemptcontain updating{1,3,8}, so the board.. itselfof -the .2. as
-- in itcolumn spends7 almostof allthat ofsquare itsare time{5,6} looking(not in1) aand completelyhence different[9,4] placemust be a 1.)
-- (OneRelies couldon argueplain_logic to spot that [7,7]"must andbe [9a 1",7] areand theserves onlyas placesa thatclear canexample hold {5,6} and
-- thereforeof wewhy this routine should eliminatenot allbother non-{5,6}to fromattempt thoseupdating squares,the asboard anitself alternative- as
-- it spends almost all of its time looking in a completely different place.)
-- strategy. However I think that would be harder to code and cannot imagine a case
-- (One saidcould complementaryargue logicthat covers[7,7] thatand [9,7] are the aboveonly places that can doeshold not{5,6} cmiiw.)and
-- therefore we should eliminate all non-{5,6} from those squares, as an alternative
--
-- strategy. However I think that would be harder to code and cannot imagine a case
-- 3) x-wings
-- said complementary logic covers, that the above does not, cmiiw.)
-- If a pair of rows or columns can only contain a given number in two matching places,
--
-- then once filled they will occupy opposite diagonal corners, hence that said number
-- 3) x-wings
-- cannot occur elsewhere in those two columns/rows. Example (with a benefit):
-- If a pair of rows or columns can .43|98.|25.only <--contain 6a given number in [1,{6two matching places,9}]
-- then once filled they will occupy opposite diagonal corners, hence that said number
-- 6..|425|...
-- cannot occur elsewhere in those two columns/rows. Example (with a benefit):
-- 2..|..1|.94
-- .43|98.|25. &lt;---+---+--- 6 in [1,{6,9}]
-- 96..|425|..4|.7. <-- hence 6 not in [4,9]
-- 32..|6.8.1|...94
-- 41.|2.9|..3---+---+---
-- 9..|..4|.7. &lt;---+---+--- hence 6 not in [4,9]
-- 823..|5.6.8|... <-- hence 6 not in [7,6],[7,9]
-- ..41.|2.4.9|..5 <-- hence 6 not in [8,6]3
-- 534|89.|71. <-- 6 in [9,{6,9}]-+---+---
-- A 6 must be in [1,6] or [1,9] and82.|5..|... [9,6] or [9,9], hence [7,9] is not 6 and must be &lt;-- hence 6 not in [7,6],[7,9.]
-- ...|.4.|..5 &lt;-- hence 6 not in [8,6]
-- (we also eliminate 6 from [4,9], [7,6] and [8,6] to no great use)
-- In practice this offers little benefit over a single534|89.|71. trial&lt;-and-error step,6 asin [9,{6,9}]
-- A obviously6 tryingmust either 6be in row [1,6] or [1,9] immediatelyand pinpoints[9,6] thator [9,9], anywayhence [7,9] is not 6 and must be 9.
-- (we also eliminate 6 from [4,9], [7,6] and [8,6] to no great use)
--
-- In practice this offers little benefit over a single trial-and-error step, as
-- 4) swordfish (not attempted)
-- obviously trying either 6 in row 1 or 9 immediately pinpoints that 9 anyway.
-- There is an extension to x-wings known as swordfish: three (or more) pairs form
--
-- a staggered pair (or more) of rectangles that exhibit similar properties, eg:
-- 4) swordfish (not attempted)
-- 8-1|-5-|-3-
-- There is an extension to x-wings known as swordfish: three (or more) pairs form
-- 953|-68|---
-- a staggered pair (or more) of rectangles that exhibit similar properties, eg:
-- -4-|-*3|5*8
-- 8-1|-5-+---+-|-3-
-- 6--953|9-268|---
-- -84-|-*3-|-4-5*8
-- 3*-|5-1|-*7 <+---+--- hence [6,3] is not 9, must be 4
-- 6--|9-+---+2|---
-- 5*2-8-|-*3-|-84-
-- 3*--8|375-1|-*7 &lt;-- hence [6,3] is not 9, must be 4
-- -3-|82-|1+---+---
-- ^5*2|-*-|-^8---^-- 3 pairs of 9s (marked with *) on 3 rows (only)
-- --8|37-|--9
-- It is not a swordfish if the 3 pairs are on >3 rows, I trust that is obvious.
-- -3-|82-|1--
-- Logically you can extend this to N pairs on N rows, however I cannot imagine a
-- ^---^---^-- 3 pairs of 9s (marked with *) on 3 rows (only)
-- case where this is not immediately solved by a single trial-step being invalid.
-- (egIt aboveis ifnot youa tryswordfish [3,5]:=9if itthe is3 quicklypairs provedare toon be&gt;3 invalidrows, andI thetrust that is sameobvious.
-- Logically you can extend this to N pairs on N rows, however I cannot imagine a
-- goes for [6,8]:=9 and [7,2]:=9, since they are all entirely inter-dependent.)
-- Obviouslycase where Ithis haveis saidnot rows,immediately thesolved sameby concepta cansingle be appliedtrial-step tobeing columnsinvalid.
-- (eg above if you try [3,5]:=9 it is quickly proved to be invalid, and the same
-- Likewise there are "Alternate Pairs" and "Hook or X-Y wing" strategies, which
-- goes for [6,8]:=9 and [7,2]:=9, since they are all entirely inter-dependent.)
-- are easily solved with a single trial-and-error step, and of course the brute
-- forceObviously algorithmwhere isI goinghave tosaid selectrows, pairsthe firstsame anyway.concept [Erm,can nobe itapplied doesn't,to columns.
-- Likewise there are "Alternate Pairs" and "Hook or X-Y wing" strategies, which
-- it selects shortest - I've noted the possible improvement below.]
-- are easily solved with a single trial-and-error step, and of course the brute
--
-- force algorithm is going to select pairs first anyway. [Erm, no it doesn't,
integer col, row
-- it selects shortest - I've noted the possible improvement below.]
sequence c, r
--</span>
sequence nine, prevsets, set
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #000080;font-style:italic;">-- (scratch)</span>
object vj
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
integer ch, k, idx, sx, sy, count
<span style="color: #000080;font-style:italic;">-- initialise/start again from scratch</span>
 
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"123456789"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span>
if length(valid)=0 then
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
-- initialise/start again from scratch
<span style="color: #000080;font-style:italic;">--
valid = repeat("123456789",9*9)
-- First perform standard eliminations of any known cells:
end if
-- (repeated every time so plain_logic() does not have to worry about it)
--
--</span>
-- First perform standard eliminations of any known cells:
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
-- (repeated every time so plain_logic() does not have to worry about it)
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
--
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">></span><span style="color: #008000;">'0'</span>
for i=1 to 9*9 do
<span style="color: #008080;">and</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span>
ch = board[i]
<span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ch</span>
if ch>'0'
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">cols</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]],</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span>
and string(valid[i]) then
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">rows</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]],</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span>
valid[i] = ch
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">squares</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]],</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span>
valid = eliminate_in(valid,nines[cols[i]],ch)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
valid = eliminate_in(valid,nines[rows[i]],ch)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
valid = eliminate_in(valid,nines[squares[i]],ch)
<span style="color: #000080;font-style:italic;">--
end if
-- 1) row/col elimination
end for
--</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">=</span><span style="color: #000000;">19</span> <span style="color: #008080;">to</span> <span style="color: #000000;">27</span> <span style="color: #008080;">do</span>
-- 1) row/col elimination
<span style="color: #004080;">sequence</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- 0 = none seen, 1..9 this col only, -1: &gt;1 col</span>
--
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- "" row row</span>
for s=19 to 27 do
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">]</span>
c = repeat(0,9) -- 0 = none seen, 1..9 this col only, -1: >1 col
<span style="color: #004080;">integer</span> <span style="color: #000000;">row</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">col</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ch</span>
r = repeat(0,9) -- "" row row
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
nine = nines[s]
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">]</span>
for n=1 to 9 do
<span style="color: #004080;">object</span> <span style="color: #000000;">vk</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span>
k = nine[n]
<span style="color: #008080;">if</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vk</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
vj = valid[k]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vk</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
if string(vj) then
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">vk</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span>
for i=1 to length(vj) do
<span style="color: #000000;">col</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dotcol</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span>
ch = vj[i]-'0'
<span style="color: #000000;">row</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dotrow</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span>
col = dotcol[k]
<span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">],{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">col</span><span style="color: #0000FF;">})!=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">?</span><span style="color: #000000;">col</span><span style="color: #0000FF;">:-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
row = dotrow[k]
<span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">],{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">row</span><span style="color: #0000FF;">})!=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">?</span><span style="color: #000000;">row</span><span style="color: #0000FF;">:-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
c[ch] = iff(find(c[ch],{0,col})!=0?col:-1)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
r[ch] = iff(find(r[ch],{0,row})!=0?row:-1)
<span style="color: #008080;">end</span> <span style="color: for#008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end if
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
end for
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #008000;">'0'</span>
for i=1 to 9 do
<span style="color: #000000;">col</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
ch = i+'0'
<span style="color: #008080;">if</span> <span style="color: #000000;">col</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
col = c[i]
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">col</span><span style="color: #0000FF;">],</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span>
if col>0 then
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
valid = eliminate_in(valid,sixes[col],ch)
<span style="color: #000000;">row</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
end if
<span style="color: #008080;">if</span> <span style="color: #000000;">row</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
row = r[i]
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">row</span><span style="color: #0000FF;">],</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span>
if row>0 then
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
valid = eliminate_in(valid,sixes[row],ch)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #000080;font-style:italic;">--
end for
-- 2) set elimination
-- 2) set elimination</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
--
<span style="color: #000080;font-style:italic;">--
for i=1 to length(nines) do
-- Practical note: Meticulously counting empties to eliminate larger set sizes
--
-- would at best reduce 6642 tests to 972, not deemed worth it.
-- Practical note: Meticulously counting empties to eliminate larger set sizes
--</span>
-- would at best reduce 6642 tests to 972, not deemed worth it.
<span style="color: #008080;">for</span> <span style="color: #000000;">set_size</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span>
--
<span style="color: #000080;font-style:italic;">--if floor(count_empties(nines[i])/2)&gt;=set_size then -- (untested)</span>
for set_size=2 to 4 do
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">set_size</span><span style="color: #0000FF;">)</span>
--if floor(count_empties(nines[i])/2)>=set_size then -- (untested)
<span style="color: #000080;font-style:italic;">--end if</span>
valid = comb(nines[i],valid,set_size)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
--end if
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #000080;font-style:italic;">--
end for
-- 3) x-wings
-- 3) x-wings</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'1'</span> <span style="color: #008080;">to</span> <span style="color: #008000;">'9'</span> <span style="color: #008080;">do</span>
--
<span style="color: #004080;">sequence</span> <span style="color: #000000;">prevsets</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">set</span>
for ch='1' to '9' do
<span style="color: #004080;">integer</span> <span style="color: #000000;">count</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">idx</span>
prevsets = repeat(0,9)
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
for x=1 to 9 do
<span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
count = 0
<span style="color: #000000;">set</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span>
set = repeat(0,9)
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
for y=0 to 8 do
<span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span>
idx = y*9+x
<span style="color: #008080;">if</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span>
if sequence(valid[idx]) and find(ch,valid[idx]) then
<span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
set[y+1] = 1
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">count</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span>
if count=2 then
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set</span><span style="color: #0000FF;">,</span><span style="color: #000000;">prevsets</span><span style="color: #0000FF;">)</span>
k = find(set,prevsets)
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
if k!=0 then
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
for y=0 to 8 do
<span style="color: #008080;">if</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
if set[y+1]=1 then
<span style="color: #008080;">for</span> <span style="color: #000000;">sx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
for sx=1 to 9 do
<span style="color: #008080;">if</span> <span style="color: #000000;">sx</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">k</span> <span style="color: #008080;">and</span> <span style="color: #000000;">sx</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">x</span> <span style="color: #008080;">then</span>
if sx!=k and sx!=x then
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">+</span><span style="color: #000000;">sx</span><span style="color: #0000FF;">},</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span>
valid = eliminate_in(valid,{y*9+sx},ch)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">prevsets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">set</span>
prevsets[x] = set
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #000000;">prevsets</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span>
prevsets = repeat(0,9)
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
for y=0 to 8 do
<span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
count = 0
<span style="color: #000000;">set</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span>
set = repeat(0,9)
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
for x=1 to 9 do
<span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span>
idx = y*9+x
<span style="color: #008080;">if</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span>
if sequence(valid[idx]) and find(ch,valid[idx]) then
<span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
set[x] = 1
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">count</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span>
if count=2 then
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set</span><span style="color: #0000FF;">,</span><span style="color: #000000;">prevsets</span><span style="color: #0000FF;">)</span>
k = find(set,prevsets)
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
if k!=0 then
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
for x=1 to 9 do
<span style="color: #008080;">if</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
if set[x]=1 then
<span style="color: #008080;">for</span> <span style="color: #000000;">sy</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
for sy=0 to 8 do
<span style="color: #008080;">if</span> <span style="color: #000000;">sy</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">k</span> <span style="color: #008080;">and</span> <span style="color: #000000;">sy</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">y</span> <span style="color: #008080;">then</span>
if sy+1!=k and sy!=y then
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">sy</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span><span style="color: #0000FF;">},</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span>
valid = eliminate_in(valid,{sy*9+x},ch)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">prevsets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">set</span>
prevsets[y+1] = set
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #008080;">return</span> <span style="color: #000000;">valid</span>
return valid
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
end function
 
<span style="color: #008080;">function</span> <span style="color: #000000;">permitted_in</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">sets</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span>
function permitted_in(string board, sequence sets, sequence valid, integer ch)
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
sequence set
<span style="color: #004080;">sequence</span> <span style="color: #000000;">set</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">sets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]</span>
integer pos, idx, bch
<span style="color: #004080;">integer</span> <span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
for i=1 to 9 do
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
set = nines[sets[i]]
<span style="color: #004080;">integer</span> <span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">],</span>
pos = 0
<span style="color: #000000;">bch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">]</span>
for j=1 to 9 do
<span style="color: #008080;">if</span> <span style="color: #000000;">bch</span><span style="color: #0000FF;">></span><span style="color: #008000;">'0'</span> <span style="color: #008080;">then</span>
idx = set[j]
<span style="color: #008080;">if</span> <span style="color: #000000;">bch</span><span style="color: #0000FF;">=</span><span style="color: #000000;">ch</span> <span style="color: #008080;">then</span> <span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
bch = board[idx]
<span style="color: #008080;">elsif</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span>
if bch>'0' then
<span style="color: #008080;">if</span> <span style="color: #000000;">pos</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if bch=ch then pos = -1 exit end if
<span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">idx</span>
elsif find(ch,valid[idx]) then
<span if pos!style=0"color: then#008080;">end</span> pos<span style="color: -1 exit end #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
pos = idx
<span style="color: #008080;">if</span> <span style="color: #000000;">pos</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ch</span>
end for
<span style="color: #000000;">improved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
if pos>0 then
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
board[pos] = ch
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
improved = 1
<span style="color: #008080;">return</span> <span style="color: #000000;">board</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
end for
return board
<span style="color: #008080;">enum</span> <span style="color: #000000;">INVALID</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">INCOMPLETE</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">SOLVED</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">MULTIPLE</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">BRUTE</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">3</span>
end function
 
<span style="color: #008080;">function</span> <span style="color: #000000;">plain_logic</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">)</span>
enum INVALID = -1, INCOMPLETE = 0, SOLVED = 1, MULTIPLE = 2, BRUTE = 3
<span style="color: #000080;font-style:italic;">--
 
-- Responsible for:
function plain_logic(string board)
-- 1) cells with only one option
--
-- 2) numbers with only one home
-- Responsible for:
--</span>
-- 1) cells with only one option
<span style="color: #004080;">integer</span> <span style="color: #000000;">solved</span>
-- 2) numbers with only one home
<span style="color: #004080;">sequence</span> <span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
--
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
integer solved
<span style="color: #000000;">solved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">SOLVED</span>
sequence valid = {}
<span style="color: #000000;">improved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
object vi
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">deep_logic</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">)</span>
 
while 1 do
<span style="color: #000080;font-style:italic;">-- 1) cells with only one option:</span>
solved = SOLVED
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
improved = 0
<span style="color: #004080;">object</span> <span style="color: #000000;">vi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
valid = deep_logic(board,valid)
<span style="color: #008080;">if</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vi</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
 
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vi</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,{},</span><span style="color: #000000;">INVALID</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
-- 1) cells with only one option:
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vi</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
for i=1 to length(valid) do
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">vi</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
vi = valid[i]
<span style="color: #000000;">improved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
if string(vi) then
if length(vi)<span style=0"color: then#008080;">end</span> return<span {board,{},INVALID} endstyle="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if length(vi)=1 then
<span style="color: #008080;">if</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]<=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">then</span>
board[i] = vi[1]
<span style="color: #000000;">solved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">INCOMPLETE</span>
improved = 1
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end if
<span style="color: #008080;">if</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">SOLVED</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,{},</span><span style="color: #000000;">SOLVED</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if board[i]<='0' then
solved = INCOMPLETE
<span style="color: #000080;font-style:italic;">-- 2) numbers with only one home</span>
end if
<span style="color: #008080;">for</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'1'</span> <span style="color: #008080;">to</span> <span style="color: #008000;">'9'</span> <span style="color: #008080;">do</span>
end for
<span style="color: #000000;">board</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">permitted_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cols</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span>
if solved=SOLVED then return {board,{},SOLVED} end if
<span style="color: #000000;">board</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">permitted_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rows</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span>
 
<span style="color: #000000;">board</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">permitted_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,</span><span style="color: #000000;">squares</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span>
-- 2) numbers with only one home
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
for ch='1' to '9' do
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">improved</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
board = permitted_in(board,cols,valid,ch)
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
board = permitted_in(board,rows,valid,ch)
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solved</span><span style="color: #0000FF;">}</span>
board = permitted_in(board,squares,valid,ch)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
end for
if not improved then exit end if
<span style="color: #008080;">function</span> <span style="color: #000000;">validate</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">)</span>
end while
<span style="color: #000080;font-style:italic;">-- (sum9 should be sufficient - if you want, get rid of nine/nines)</span>
return {board,valid,solved}
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">sum9</span>
end function
<span style="color: #004080;">sequence</span> <span style="color: #000000;">nine</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">nines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span>
 
function validate(string board)
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- columns</span>
-- (sum9 should be sufficient - if you want, get rid of nine/nines)
<span style="color: #000000;">sum9</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
integer ch, sum9
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span>
sequence nine, nines = tagset(9)
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">81</span> <span style="color: #008080;">by</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
 
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span>
for x=0 to 8 do -- columns
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;"><</span><span style="color: #000000;">1</span> <span style="color: #008080;">or</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">></span><span style="color: #000000;">9</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
sum9 = 0
<span style="color: #000000;">sum9</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">ch</span>
nine = repeat(0,9)
<span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ch</span>
for y=1 to 81 by 9 do
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
ch = board[y+x]-'0'
<span style="color: #008080;">if</span> <span style="color: #000000;">sum9</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">45</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if ch<1 or ch>9 then return 0 end if
<span style="color: #008080;">if</span> <span style="color: #000000;">nine</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">nines</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
sum9 += ch
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
nine[ch] = ch
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">81</span> <span style="color: #008080;">by</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- rows</span>
end for
<span style="color: #000000;">sum9</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
if sum9!=45 then return 0 end if
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span>
if nine!=nines then return 0 end if
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
end for
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span>
for y=1 to 81 by 9 do -- rows
<span style="color: #000000;">sum9</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">ch</span>
sum9 = 0
<span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ch</span>
nine = repeat(0,9)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
for x=0 to 8 do
<span style="color: #008080;">if</span> <span style="color: #000000;">sum9</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">45</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
ch = board[y+x]-'0'
<span style="color: #008080;">if</span> <span style="color: #000000;">nine</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">nines</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
sum9 += ch
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
nine[ch] = ch
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">by</span> <span style="color: #000000;">3</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- small squares</span>
end for
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">by</span> <span style="color: #000000;">3</span> <span style="color: #008080;">do</span>
if sum9!=45 then return 0 end if
<span style="color: #000000;">sum9</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
if nine!=nines then return 0 end if
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #008080;">for</span> <span style="color: #000000;">sy</span><span style="color: #0000FF;">=</span><span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span> <span style="color: #008080;">to</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">+</span><span style="color: #000000;">18</span> <span style="color: #008080;">by</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
for y=0 to 8 by 3 do -- small squares
<span style="color: #008080;">for</span> <span style="color: #000000;">sx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">x</span> <span style="color: #008080;">to</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span> <span style="color: #008080;">do</span>
for x=0 to 8 by 3 do
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">sy</span><span style="color: #0000FF;">+</span><span style="color: #000000;">sx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span>
sum9 = 0
<span style="color: #000000;">sum9</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">ch</span>
nine = repeat(0,9)
<span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ch</span>
for sy=y*9 to y*9+18 by 9 do
for sx<span style=x"color: to#008080;">end</span> x+2<span dostyle="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
ch = board[sy+sx+1]-'0'
<span style="color: #008080;">if</span> <span style="color: #000000;">sum9</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">45</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
sum9 += ch
<span style="color: #008080;">if</span> <span style="color: #000000;">nine</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">nines</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
nine[ch] = ch
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span>
if sum9!=45 then return 0 end if
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
if nine!=nines then return 0 end if
end for
<span style="color: #008080;">function</span> <span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #0000FF;">{</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">plain_logic</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">)</span>
return 1
<span style="color: #008080;">if</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">INVALID</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #0000FF;">{{},</span><span style="color: #000000;">INVALID</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">if</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">SOLVED</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">},</span><span style="color: #000000;">SOLVED</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
 
<span style="color: #008080;">if</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">BRUTE</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">},</span><span style="color: #000000;">BRUTE</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
function solve(string board, sequence valid={})
<span style="color: #008080;">if</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">INCOMPLETE</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
sequence solution, solutions
<span style="color: #000080;font-style:italic;">-- find the cell with the fewest options:
integer solved
-- (a possible improvement here would be to select the shortest
integer minopt, mindx
-- with the "most pairs" set, see swordfish etc above.)</span>
object vi
<span style="color: #004080;">integer</span> <span style="color: #000000;">minopt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">mindx</span>
{solution,valid,solved} = plain_logic(board)
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
if solved=INVALID then return {{},INVALID} end if
<span style="color: #004080;">object</span> <span style="color: #000000;">vi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
if solved=SOLVED then return {{solution},SOLVED} end if
<span style="color: #008080;">if</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vi</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
if solved=BRUTE then return {{solution},BRUTE} end if
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vi</span><span style="color: #0000FF;">)<=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- should be caught above</span>
if solved!=INCOMPLETE then ?9/0 end if
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vi</span><span style="color: #0000FF;">)<</span><span style="color: #000000;">minopt</span> <span style="color: #008080;">then</span>
-- find the cell with the fewest options:
<span style="color: #000000;">minopt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vi</span><span style="color: #0000FF;">)</span>
-- (a possible improvement here would be to select the shortest
<span style="color: #000000;">mindx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
-- with the "most pairs" set, see swordfish etc above.)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
minopt = 10
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
for i=1 to 9*9 do
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
vi = valid[i]
<span style="color: #004080;">sequence</span> <span style="color: #000000;">solutions</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
if string(vi) then
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">minopt</span> <span style="color: #008080;">do</span>
if length(vi)<=1 then ?9/0 end if -- should be caught above
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">mindx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">mindx</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
if length(vi)<minopt then
<span style="color: #0000FF;">{</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solved</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">)</span>
minopt = length(vi)
<span style="color: #008080;">if</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">MULTIPLE</span> <span style="color: #008080;">then</span>
mindx = i
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span><span style="color: #000000;">MULTIPLE</span><span style="color: #0000FF;">}</span>
end if
<span style="color: #008080;">elsif</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">SOLVED</span>
end if
<span style="color: #008080;">or</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">BRUTE</span> <span style="color: #008080;">then</span>
end for
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">)</span>
solutions = {}
<span style="color: #008080;">and</span> <span style="color: #000000;">validate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span>
for i=1 to minopt do
<span style="color: #000000;">solutions</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
board[mindx] = valid[mindx][i]
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
{solution,solved} = solve(board,valid)
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">)></span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
if solved=MULTIPLE then
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">,</span><span style="color: #000000;">MULTIPLE</span><span style="color: #0000FF;">}</span>
return {solution,MULTIPLE}
<span style="color: #008080;">elsif</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
elsif solved=SOLVED
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">,</span><span style="color: #000000;">BRUTE</span><span style="color: #0000FF;">}</span>
or solved=BRUTE then
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if not find(solution[1],solutions)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
and validate(solution[1]) then
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
solutions = append(solutions,solution[1])
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
end if
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">,</span><span style="color: #000000;">BRUTE</span><span style="color: #0000FF;">}</span>
if length(solutions)>1 then
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return {solutions,MULTIPLE}
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{{},</span><span style="color: #000000;">INVALID</span><span style="color: #0000FF;">}</span>
elsif length(solutions) then
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
return {solutions,BRUTE}
end if
<span style="color: #008080;">function</span> <span style="color: #000000;">test_one</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">)</span>
end if
<span style="color: #0000FF;">{</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">solutions</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #004080;">string</span> <span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">desc</span>
if length(solutions)=1 then
<span style="color: #008080;">if</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">SOLVED</span> <span style="color: #008080;">then</span>
return {solutions,BRUTE}
<span style="color: #000000;">desc</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"(logic)"</span>
end if
<span style="color: #008080;">elsif</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">BRUTE</span> <span style="color: #008080;">then</span>
return {{},INVALID}
<span style="color: #000000;">desc</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"(brute force)"</span>
end function
<span style="color: #008080;">else</span>
 
<span style="color: #000000;">desc</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"???"</span> <span style="color: #000080;font-style:italic;">-- INVALID/INCOMPLETE/MULTIPLE</span>
function test_one(string board)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
sequence solutions
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
string solution, desc
<span style="color: #000000;">solution</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span>
integer solved
<span style="color: #000000;">desc</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"*** NO SOLUTIONS ***"</span>
{solutions,solved} = solve(board)
<span style="color: #008080;">elsif</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
if solved=SOLVED then
<span style="color: #000000;">solution</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">solutions</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
desc = "(logic)"
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">validate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
elsif solved=BRUTE then
<span style="color: #000000;">desc</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"*** ERROR ***"</span> <span style="color: #000080;font-style:italic;">-- (should never happen)</span>
desc = "(brute force)"
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
else
<span style="color: #008080;">else</span>
desc = "???" -- INVALID/INCOMPLETE/MULTIPLE
<span style="color: #000000;">solution</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span>
end if
<span style="color: #000000;">desc</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"*** MULTIPLE SOLUTIONS ***"</span>
if length(solutions)=0 then
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
solution = board
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">}</span>
desc = "*** NO SOLUTIONS ***"
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
elsif length(solutions)=1 then
solution = solutions[1]
<span style="color: #000080;font-style:italic;">--NB Blank cells can be represented by any character &lt;'1'. Spaces are not recommended since
if not validate(solution) then
-- they can all too easily be converted to tabs by copy/paste/save. In particular, ? and
desc = "*** ERROR ***" -- (should never happen)
-- _ are NOT valid characters for representing a blank square. Use any of .0-* instead.</span>
end if
else
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span>
solution = board
<span style="color: #008000;">"..............3.85..1.2.......5.7.....4...1...9.......5......73..2.1........4...9"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.01s, (logic))
desc = "*** MULTIPLE SOLUTIONS ***"
-- row/col elimination (was 8s w/o logic first)</span>
end if
<span style="color: #008000;">"000000036840000000000000020000203000010000700000600400000410050003000200600000000"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.04s, (brute force))</span>
return {solution,desc}
<span style="color: #008000;">".......39.....1..5..3.5.8....8.9...6.7...2...1..4.......9.8..5..2....6..4..7....."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (1.12s, (brute force))</span>
end function
<span style="color: #008000;">"000037600000600090008000004090000001600000009300000040700000800010009000002540000"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span>
 
<span style="color: #008000;">"....839..1......3...4....7..42.3....6.......4....7..1..2........8...92.....25...6"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.04s, (brute force))</span>
--NB Blank cells can be represented by any character <'1'. Spaces are not recommended since
<span style="color: #008000;">"..1..5.7.92.6.......8...6...9..2.4.1.........3.4.8..9...7...3.......7.69.1.8..7.."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))
-- they can all too easily be converted to tabs by copy/paste/save. In particular, ? and
-- (the following takes ~8s when checking for multiple solutions)</span>
-- _ are NOT valid characters for representing a blank square. Use any of .0-* instead.
<span style="color: #008000;">"--3------4---8--36--8---1---4--6--73---9----------2--5--4-7--686--------7--6--5--"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.01s, (brute force))</span>
 
<span style="color: #008000;">"..3.2.6..9..3.5..1..18.64....81.29..7.......8..67.82....26.95..8..2.3..9..5.1.3.."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span>
constant tests = {
<span style="color: #008000;">"--4-5--6--6-1--8-93----7----8----5-----4-3-----6----7----2----61-5--4-3--2--7-1--"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))
"..............3.85..1.2.......5.7.....4...1...9.......5......73..2.1........4...9", -- (0.01s, (logic))
-- x-wings</span>
-- row/col elimination (was 8s w/o logic first)
<span style="color: #008000;">".4398.25.6..425...2....1.949....4.7.3..6.8...41.2.9..382.5.........4...553489.71."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span>
"000000036840000000000000020000203000010000700000600400000410050003000200600000000", -- (0.04s, (brute force))
<span style="color: #008000;">".9...4..7.39....79.1.8.5..3.5.8...4.858.9...6.73...2...1.2.4....97.6..9.8..5..2.4..35.6..4..72..6...8."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (10.12s00s, (brute forcelogic))
-- "AL Escargot", so-called "hardest sudoku"</span>
"000037600000600090008000004090000001600000009300000040700000800010009000002540000", -- (0.00s, (logic))
<span style="color: #008000;">"1....8397.9.1.3..2...38..96.4.5...7.53.42.39...1.6.8...26....4...3.7..1..2.1..4.....8.7..927...3..25...6"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.04s26s, (brute force))</span>
<span style="color: #008000;">"12.3.1..5.7435.92.6..1....4.8...6...9.54..2.4.16...7.......3.4.8..9...731..5.3......9.7.69.1.8..76...8"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s48s, (logicbrute force))</span>
<span style="color: #008000;">"12.4..3..3...1..5...6...1..7...9.....4.6.3.....3..2...5...8.7....7.....5.......98"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (1.07s, (brute force))</span>
-- (the following takes ~8s when checking for multiple solutions)
<span style="color: #008000;">"394..267....3..4..5..69..2..45...9..6.......7..7...58..1..67..8..9..8....264..735"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span>
"--3------4---8--36--8---1---4--6--73---9----------2--5--4-7--686--------7--6--5--", -- (0.01s, (brute force))
<span style="color: #008000;">"4....3.2.6.5...8.9..3.5...1..18.64.2.7..81.29.1.7.9.....4.8..67.82.3.5..26.95.2.8..2.37..9.6.5...8.1.3.....6"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s01s, (logicbrute force))</span>
<span style="color: #008000;">"5...7....6..195....98....6.8...6...34..8.3..17...2...6.6....28....419..5....8..79"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span>
"--4-5--6--6-1--8-93----7----8----5-----4-3-----6----7----2----61-5--4-3--2--7-1--", -- (0.00s, (logic))
<span style="color: #008000;">"503600009010002600900000080000700005006804100200003000030000008004300050800006702"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span>
-- x-wings
<span style="color: #008000;">"53.4398.25.6247..425...2...8..1.949.7.39.2.4.78.372.49.62.898..7.4179.2.9..382.58.....3.5.696..41.3..553489.715.69..1."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span>
<span style="color: #008000;">"530070000600195000098000060800060003400803001700020006060000280000419005000080079"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))
".9...4..7.....79..8........4.58.....3.......2.....97.6........4..35.....2..6...8.", -- (0.00s, (logic))
-- set exclusion</span>
-- "AL Escargot", so-called "hardest sudoku"
<span style="1color: #008000;">"75..9..746961.9..33524..2...879.2.96.6.51..7.8.53..9..2.1..8328.65..26....4...3.9...2..1..4......7..7.484..3..79"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.26s00s, (brute forcelogic))
-- Worlds hardest sudoku:</span>
"12.3....435....1....4........54..2..6...7.........8.9...31..5.......9.7.....6...8", -- (0.48s, (brute force))
<span style="color: #008000;">"800000000003600000070090200050007000000045700000100030001000068008500010090000400"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.21s, (brute force))</span>
"12.4..3..3...1..5...6...1..7...9.....4.6.3.....3..2...5...8.7....7.....5.......98", -- (1.07s, (brute force))
<span style="color: #008000;">"819--5-----2---75--371-4-6-4--59-1--7--3-8--2--3-62--7-5-7-921--64---9-----2--438"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span>
"394..267....3..4..5..69..2..45...9..6.......7..7...58..1..67..8..9..8....264..735", -- (0.00s, (logic))
<span style="4color: #008000;">"85...24..72.6.5...8.9..34....1....2.1.7..23.5..1.9.....4.8....3.5....2..8..7..617.5...8.1.....36.64."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.01s, (brute forcelogic))</span>
<span style="5color: #008000;">"9..2..5.7..4..6..1953...3.98....6.8..9.6.2..34....5..8.3..177..4.2.37..6.6..1..28.5..2.419.4.5..1..86..799"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s17s, (logicbrute force))</span>
<span style="color: #008000;">"97.3...6..6.75.........8.5.......67.....3.....539..2..7...25.....2.1...8.4...73.."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))
"503600009010002600900000080000700005006804100200003000030000008004300050800006702", -- (0.00s, (logic))
-- "the beast" (an earlier algorithm took 318s (5min 18s) on this):</span>
"53..247....2...8..1..7.39.2..8.72.49.2.98..7.79.....8.....3.5.696..1.3...5.69..1.", -- (0.00s, (logic))
<span style="color: #008000;">"000060080020000000001000000070000102500030000000000400004201000300700600000000050"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.03s, (brute force))</span>
"530070000600195000098000060800060003400803001700020006060000280000419005000080079", -- (0.00s, (logic))
<span style="color: #0000FF;">$},</span>
-- set exclusion
"75..9..46961...3524.....79.2..6.1..7.8.....2.1..328.65.........3.9...2.484..3..79", -- (0.00s, (logic))
<span style="color: #000000;">lt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">),</span>
-- Worlds hardest sudoku:
<span style="color: #000000;">run_one_test</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
"800000000003600000070090200050007000000045700000100030001000068008500010090000400", -- (0.21s, (brute force))
"819--5-----2---75--371-4-6-4--59-1--7--3-8--2--3-62--7-5-7-921--64---9-----2--438", -- (0.00s, (logic))
<span style="color: #008080;">constant</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">" x x x | x x x | x x x "</span><span style="color: #0000FF;">,</span>
"85...24..72......9..4.........1.7..23.5...9...4...........8..7..17..........36.4.", -- (0.01s, (logic))
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"-------+-------+-------"</span><span style="color: #0000FF;">,</span>
"9..2..5...4..6..3...3.....6...9..2......5..8...7..4..37.....1...5..2..4...1..6..9", -- (0.17s, (brute force))
<span style="color: #000000;">l3</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">({</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">},</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">),</span>
"97.3...6..6.75.........8.5.......67.....3.....539..2..7...25.....2.1...8.4...73..", -- (0.00s, (logic))
<span style="color: #000000;">fmt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">({</span><span style="color: #000000;">l3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l3</span><span style="color: #0000FF;">},</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"x"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%c"</span><span style="color: #0000FF;">)&</span><span style="color: #008000;">"\n"</span>
-- "the beast" (an earlier algorithm took 318s (5min 18s) on this):
"000060080020000000001000000070000102500030000000000400004201000300700600000000050", -- (0.03s, (brute force))
<span style="color: #008080;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">()</span>
$},
<span style="color: #004080;">string</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (81 characters)</span>
 
<span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">desc</span>
lt = length(tests),
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
run_one_test = 0
<span style="color: #008080;">if</span> <span style="color: #000000;">run_one_test</span> <span style="color: #008080;">then</span>
 
<span style="color: #000000;">board</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">run_one_test</span><span style="color: #0000FF;">]</span>
constant l = " x x x | x x x | x x x ",
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">board</span><span style="color: #0000FF;">)</span>
s = "-------+-------+-------",
<span style="color: #0000FF;">{</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">test_one</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">)</span>
l3 = join({l,l,l},"\n"),
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
fmt = substitute(join({l3,s,l3,s,l3},"\n"),"x","%c")&"\n"
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"solution:\n"</span><span style="color: #0000FF;">)</span>
 
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">)</span>
procedure print_board(string board)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
printf(1,fmt,board)
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s, %3.2fs\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">})</span>
end procedure
<span style="color: #008080;">else</span>
 
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">lt</span> <span style="color: #008080;">do</span>
procedure test()
<span style="color: #004080;">atom</span> <span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
string board -- (81 characters)
<span style="color: #000000;">board</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
string solution, desc
<span style="color: #0000FF;">{</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">test_one</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">)</span>
atom t0 = time()
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" \"%s\", -- (%3.2fs, %s)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">})</span>
if run_one_test then
<span style="color: #000080;font-style:italic;">-- printf(1," \"%s\", -- (%3.2fs, %s)\n",{solution,time()-t1,desc})</span>
board = tests[run_one_test]
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
print_board(board)
<span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span>
{solution,desc} = test_one(board)
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d puzzles solved in %3.2fs (av %3.2fs)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">lt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">/</span><span style="color: #000000;">lt</span><span style="color: #0000FF;">})</span>
if length(solution)!=0 then
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
printf(1,"solution:\n")
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
print_board(solution)
<span style="color: #000000;">test</span><span style="color: #0000FF;">()</span>
end if
<!--</syntaxhighlight>-->
printf(1,"%s, %3.2fs\n",{desc,time()-t0})
else
for i=1 to lt do
atom t1 = time()
board = tests[i]
{solution,desc} = test_one(board)
printf(1," \"%s\", -- (%3.2fs, %s)\n",{board,time()-t1,desc})
-- printf(1," \"%s\", -- (%3.2fs, %s)\n",{solution,time()-t1,desc})
end for
t0 = time()-t0
printf(1,"%d puzzles solved in %3.2fs (av %3.2fs)\n",{lt,t0,t0/lt})
end if
end procedure
test()</lang>
{{out}}
<pre>
Line 8,970 ⟶ 9,209:
=={{header|PHP}}==
{{trans|C++}}
<langsyntaxhighlight lang="php"> class SudokuSolver {
protected $grid = [];
protected $emptySymbol;
Line 9,094 ⟶ 9,333:
$solver = new SudokuSolver('009170000020600001800200000200006053000051009005040080040000700006000320700003900');
$solver->solve();
$solver->display();</langsyntaxhighlight>
{{out}}
<pre>
Line 9,109 ⟶ 9,348:
7 8 2 | 5 6 3 | 9 1 4
(solved in 0.027s)
</pre>
 
=={{header|Picat}}==
Using constraint programming.
 
<syntaxhighlight lang="picat">import util.
import cp.
 
main => go.
 
go =>
sudokus(Sudokus),
foreach([Comment,SudokuS] in Sudokus)
println(SudokuS),
println(Comment),
% Convert string to numbers and "." to _ (unknown)
Sudoku = [ [cond(S == '.',_,S.to_integer()) :
S in slice(SudokuS,(I*9)+1,(I+1)*9)] : I in 0..8],
print_board(Sudoku),
% Ensure unicity of the solution (check that it is a unique solution)
All = findall(Sudoku,sudoku(Sudoku)),
if All.length > 1 then
printf("Problem has %d solutions!\n", All.length)
end,
print("Solution:")
foreach(A in All)
print_board(A)
end,
nl
end,
nl.
 
sudoku(Board) =>
N = ceiling(sqrt(Board.len)),
N2 = N*N,
Vars = Board.vars(),
Vars :: 1..N2,
foreach(Row in Board) all_different(Row) end,
foreach(Column in transpose(Board)) all_different(Column) end,
foreach(I in 1..N..N2, J in 1..N..N2)
all_different([Board[I+K,J+L] : K in 0..N-1, L in 0..N-1])
end,
solve([ffd,inout], Vars).
 
print_board(Board) =>
N = Board.length,
foreach(I in 1..N)
foreach(J in 1..N)
X = Board[I,J],
if var(X) then printf(" _") else printf(" %w", X) end
end,
nl
end,
nl.
 
% (Problems from the Groovy implementation)
sudokus(Sudokus) => Sudokus =
[
"819..5.....2...75..371.4.6.4..59.1..7..3.8..2..3.62..7.5.7.921..64...9.....2..438",
"53..247....2...8..1..7.39.2..8.72.49.2.98..7.79.....8.....3.5.696..1.3...5.69..1.",
"..3.2.6..9..3.5..1..18.64....81.29..7.......8..67.82....26.95..8..2.3..9..5.1.3..",
"394..267....3..4..5..69..2..45...9..6.......7..7...58..1..67..8..9..8....264..735",
"97.3...6..6.75.........8.5.......67.....3.....539..2..7...25.....2.1...8.4...73..",
"4......6.5...8.9..3....1....2.7....1.9.....4.8....3.5....2....7..6.5...8.1......6",
"85...24..72......9..4.........1.7..23.5...9...4...........8..7..17..........36.4.",
"..1..5.7.92.6.......8...6...9..2.4.1.........3.4.8..9...7...3.......7.69.1.8..7..",
".9...4..7.....79..8........4.58.....3.......2.....97.6........4..35.....2..6...8.",
"12.3....435....1....4........54..2..6...7.........8.9...31..5.......9.7.....6...8",
"9..2..5...4..6..3...3.....6...9..2......5..8...7..4..37.....1...5..2..4...1..6..9",
"1....7.9..3..2...8..96..5....53..9...1..8...26....4...3......1..4......7..7...3..",
"12.4..3..3...1..5...6...1..7...9.....4.6.3.....3..2...5...8.7....7.....5.......98",
"..............3.85..1.2.......5.7.....4...1...9.......5......73..2.1........4...9",
".......39.....1..5..3.5.8....8.9...6.7...2...1..4.......9.8..5..2....6..4..7.....",
"....839..1......3...4....7..42.3....6.......4....7..1..2........8...92.....25...6",
"..3......4...8..36..8...1...4..6..73...9..........2..5..4.7..686........7..6..5.."
].</syntaxhighlight>
 
{{out}}
All problems are solved (and proved/checked for unicity) in 0.043s.
<pre>
819..5.....2...75..371.4.6.4..59.1..7..3.8..2..3.62..7.5.7.921..64...9.....2..438
8 1 9 _ _ 5 _ _ _
_ _ 2 _ _ _ 7 5 _
_ 3 7 1 _ 4 _ 6 _
4 _ _ 5 9 _ 1 _ _
7 _ _ 3 _ 8 _ _ 2
_ _ 3 _ 6 2 _ _ 7
_ 5 _ 7 _ 9 2 1 _
_ 6 4 _ _ _ 9 _ _
_ _ _ 2 _ _ 4 3 8
 
Solution:
8 1 9 6 7 5 3 2 4
6 4 2 9 8 3 7 5 1
5 3 7 1 2 4 8 6 9
4 2 6 5 9 7 1 8 3
7 9 5 3 1 8 6 4 2
1 8 3 4 6 2 5 9 7
3 5 8 7 4 9 2 1 6
2 6 4 8 3 1 9 7 5
9 7 1 2 5 6 4 3 8
 
...
 
</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(load "lib/simul.l")
 
### Fields/Board ###
Line 9,193 ⟶ 9,536:
(0 6 0 0 0 0 2 8 0)
(0 0 0 4 1 9 0 0 5)
(0 0 0 0 8 0 0 7 9) ) )</langsyntaxhighlight>
{{out}}
<pre> +---+---+---+---+---+---+---+---+---+
Line 9,215 ⟶ 9,558:
+---+---+---+---+---+---+---+---+---+
a b c d e f g h i</pre>
<syntaxhighlight lang PicoLisp="picolisp">(go)</langsyntaxhighlight>
{{out}}
<pre> +---+---+---+---+---+---+---+---+---+
Line 9,240 ⟶ 9,583:
=={{header|PL/I}}==
Working PL/I version, derived from the Rosetta Fortran version.
<langsyntaxhighlight lang="pli">sudoku: procedure options (main); /* 27 July 2014 */
 
declare grid (9,9) fixed (1) static initial (
Line 9,323 ⟶ 9,666:
 
end sudoku;
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 9,357 ⟶ 9,700:
 
Another PL/I version, reads sudoku from the text data file as 81 character record.
<langsyntaxhighlight lang="pli">
*PROCESS MARGINS(1,120) LIBS(SINGLE,STATIC);
*PROCESS OPTIMIZE(2) DFT(REORDER);
Line 9,496 ⟶ 9,839:
 
end sudoku;
</syntaxhighlight>
</lang>
 
=={{header|Prolog}}==
<langsyntaxhighlight Prologlang="prolog">:- use_module(library(clpfd)).
sudoku(Rows) :-
Line 9,524 ⟶ 9,867:
[5,_,_,_,_,_,_,7,3],
[_,_,2,_,1,_,_,_,_],
[_,_,_,_,4,_,_,_,9]]).</langsyntaxhighlight>
 
===GNU Prolog version===
{{works with|GNU Prolog|1.4.4}}
<langsyntaxhighlight Prologlang="prolog">:- initialization(main).
 
 
Line 9,581 ⟶ 9,924:
 
main :- test(T), solve(T), maplist(show,T), halt.
show(X) :- write(X), nl.</langsyntaxhighlight>
{{Out}}
<pre>[1,2,3,4,5,6,7,8,9]
Line 9,596 ⟶ 9,939:
=={{header|PureBasic}}==
A brute force method is used, it seemed the fastest as well as the simplest.
<langsyntaxhighlight PureBasiclang="purebasic">DataSection
puzzle:
Data.s "394002670"
Line 9,706 ⟶ 10,049:
Input()
CloseConsole()
EndIf</langsyntaxhighlight>
{{out}}
<pre>+-----+-----+-----+
Line 9,738 ⟶ 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
<langsyntaxhighlight lang="python">
def initiate():
box.append([0, 1, 2, 9, 10, 11, 18, 19, 20])
Line 9,824 ⟶ 10,169:
print grid[i*9:i*9+9]
raw_input()
</syntaxhighlight>
</lang>
 
===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 9,833 ⟶ 10,245:
===Brute Force===
{{trans|Perl}}
<syntaxhighlight lang="raku" perl6line>my @A = <
5 3 0 0 2 4 7 0 0
0 0 2 0 0 0 8 0 0
Line 9,873 ⟶ 10,285:
}
}
solve;</langsyntaxhighlight>
 
{{out}}
Line 9,891 ⟶ 10,303:
This is an alternative solution that uses a more ellaborate set of choices instead of brute-forcing it.
 
<syntaxhighlight lang="raku" perl6line>#
# In this code, a sudoku puzzle is represented as a two-dimentional
# array. The cells that are not yet solved are represented by yet
Line 10,112 ⟶ 10,524:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 10,130 ⟶ 10,542:
A sudoku is represented as a matrix, see Rascal solutions to matrix related problems for examples.
 
<langsyntaxhighlight Rascallang="rascal">import Prelude;
import vis::Figure;
import vis::Render;
Line 10,213 ⟶ 10,625:
<0,7,0>, <1,7,0>, <2,7,9>, <3,7,0>, <4,7,0>, <5,7,8>, <6,7,0>, <7,7,0>, <8,7,0>,
<0,8,0>, <1,8,2>, <2,8,6>, <3,8,4>, <4,8,0>, <5,8,0>, <6,8,7>, <7,8,3>, <8,8,5>
};</langsyntaxhighlight>
 
Example
Line 10,506 ⟶ 10,918:
Example of a back-tracking solver, from [[wp:Algorithmics of sudoku]]
{{works with|Ruby|2.0+}}
<langsyntaxhighlight lang="ruby">def read_matrix(data)
lines = data.lines
9.times.collect { |i| 9.times.collect { |j| lines[i][j].to_i } }
Line 10,596 ⟶ 11,008:
print_matrix(matrix)
puts
print_matrix(solve_sudoku(matrix))</langsyntaxhighlight>
 
{{out}}
Line 10,630 ⟶ 11,042:
=={{header|Rust}}==
{{trans|Ada}}
<langsyntaxhighlight lang="rust">type Sudoku = [u8; 81];
 
fn is_valid(val: u8, x: usize, y: usize, sudoku_ar: &mut Sudoku) -> bool {
Line 10,693 ⟶ 11,105:
println!("Unsolvable");
}
}</langsyntaxhighlight>
 
{{out}}
Line 10,715 ⟶ 11,127:
Use CLP solver in SAS/OR:
 
<langsyntaxhighlight lang="sas">/* define SAS data set */
data Indata;
input C1-C9;
Line 10,761 ⟶ 11,173:
/* print solution */
print X;
quit;</langsyntaxhighlight>
 
Output:
Line 10,782 ⟶ 11,194:
This solver works with normally 9x9 sudokus as well as with sudokus of jigsaw type or sudokus with additional condition like diagonal constraint.
{{works with|Scala|2.9.1}}
<langsyntaxhighlight lang="scala">object SudokuSolver extends App {
 
class Solver {
Line 10,913 ⟶ 11,325:
println(solution match {case Nil => "no solution!!!" case _ => f2Str(solution)})
}</langsyntaxhighlight>
{{out}}
<pre>riddle:
Line 10,947 ⟶ 11,359:
The implementation above doesn't work so effective for sudokus like Bracmat version, therefore I implemented a second version inspired by Java section:
{{works with|Scala|2.9.1}}
<langsyntaxhighlight lang="scala">object SudokuSolver extends App {
 
object Solver {
Line 11,064 ⟶ 11,476:
+("\n"*2))
}
}</langsyntaxhighlight>
{{out}}
<pre>riddle used in Ada section:
Line 11,195 ⟶ 11,607:
The grid should be input in <code>Init_board</code> as a 9x9 matrix. The blanks should be represented by 0. A rule that the initial game should have at least 17 givens is enforced, for it guarantees a unique solution. It is also possible to set a maximum number of steps to the solver using <code>break_point</code>. If it is set to 0, there will be no break until it finds the solution.
 
<syntaxhighlight lang="text">Init_board=[...
5 3 0 0 7 0 0 0 0;...
6 0 0 1 9 5 0 0 0;...
Line 11,367 ⟶ 11,779:
disp('Invalid solution found.');
disp_board(Solved_board);
end</langsyntaxhighlight>
 
{{out}}
Line 11,427 ⟶ 11,839:
=={{header|Sidef}}==
{{trans|Raku}}
<langsyntaxhighlight lang="ruby">func check(i, j) is cached {
var (id, im) = i.divmod(9)
var (jd, jm) = j.divmod(9)
Line 11,475 ⟶ 11,887:
)
 
solve(grid)</langsyntaxhighlight>
{{out}}
<pre>5 3 9 8 2 4 7 6 1
Line 11,490 ⟶ 11,902:
 
=={{header|Shale}}==
<langsyntaxhighlight lang="shale">
#!/usr/local/bin/shale
 
Line 12,020 ⟶ 12,432:
 
// I'd like to see an irregular sudoku with a knight's move constraint. Any takers...
</syntaxhighlight>
</lang>
 
'''Output'''
Line 12,061 ⟶ 12,473:
The input and output are presented as strings of 81 characters, where each character is either a digit or a space (indicating an empty cell in the grid). The translation between grids and such strings is trivial (convert grid to string by concatenating rows, reading left to right and then top to bottom), and not covered in the solution. The input is given as a bind variable, ''':game'''.
 
<langsyntaxhighlight lang="sql">with
symbols (d) as (select to_char(level) from dual connect by level <= 9)
, board (i) as (select level from dual connect by level <= 81)
Line 12,089 ⟶ 12,501:
from r
where pos = 0
;</langsyntaxhighlight>
 
A better (faster) approach - taking advantage of database-specific features - is to create a '''table''' NEIGHBORS (similar to the inline view in the WITH clause) and an index on column I of that table; then the query execution time drops by more than half in most cases.
Line 12,113 ⟶ 12,525:
The example grid given below is taken from [https://en.wikipedia.org/wiki/Sudoku_solving_algorithms Wikipedia]. It does not require any recursive call (it's entirely filled in the first step of ''solve''), as can be seen with additional ''printf'' in the code to follow the algorithm.
 
<langsyntaxhighlight lang="stata">mata
function sudoku(a) {
s = J(81,20,.)
Line 12,213 ⟶ 12,625:
sudoku(a)
a
end</langsyntaxhighlight>
 
'''Output'''
Line 12,234 ⟶ 12,646:
Two more examples, from [http://www.7sudoku.com/very-difficult here] and [http://www.extremesudoku.info/sudoku.html there].
 
<langsyntaxhighlight lang="stata">a = 7,9,.,.,.,3,.,.,2\
.,6,.,5,1,.,.,.,.\
.,.,.,.,.,2,.,.,6\
Line 12,286 ⟶ 12,698:
8 | 3 8 5 4 7 9 2 1 6 |
9 | 7 6 9 3 2 1 4 5 8 |
+-------------------------------------+</langsyntaxhighlight>
 
=={{header|Swift}}==
{{trans|Java}}
<langsyntaxhighlight Swiftlang="swift">import Foundation
 
typealias SodukuPuzzle = [[Int]]
Line 12,413 ⟶ 12,825:
let puzzle = Soduku(board: board)
puzzle.solve()
puzzle.printBoard()</langsyntaxhighlight>
{{out}}
<pre>
Line 12,433 ⟶ 12,845:
{{works with|Swift 3}}
 
<syntaxhighlight lang="swift">
<lang Swift>
func solving(board: [[Int]]) -> [[Int]] {
var board = board
Line 12,498 ⟶ 12,910:
 
print(solving(board: puzzle))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 12,517 ⟶ 12,929:
 
 
<langsyntaxhighlight lang="systemverilog">
 
//////////////////////////////////////////////////////////////////////////////
Line 12,647 ⟶ 13,059:
end
endprogram
</syntaxhighlight>
</lang>
 
It can be seen that SystemVerilog randomization is a very powerfull tool, in this implementation I directly described the game constraints and the randomization engine takes care of producing solutions, and when multiple solutions are possible they will be chosen at random.
Line 12,702 ⟶ 13,114:
 
=={{header|Tailspin}}==
There is a blog post about how this code was developed: https://tobega.blogspot.com/2020/05/creating-algorithm.html
<lang tailspin>
<syntaxhighlight lang="tailspin">
templates deduceRemainingDigits
data row <"1">, col <"1"> local
templates findOpenPosition
@:{options: 10"1"};
$ -> \[i;j](when <[]?($::length <..~$@findOpenPosition.options::raw>)> do @findOpenPosition: {row: $i, col: $j, options: ($::length)"1"}; \) -> !VOID
$@ !
end findOpenPosition
 
templates selectFirst&{pos:}
def digit: $($pos.row;$pos.col) -> $(1);
Line 12,717 ⟶ 13,129:
when <[]?($i <=$pos.row>)
|[]?($j <=$pos.col>)
|[]?(($i::raw-1)~/3 <=($pos.row::raw-1)~/3>)?(($j::raw-1)~/3 <=($pos.col::raw-1)~/3>)> do [$... -> \(when <~=$digit> do $! \)] !
otherwisewhen <> do $ !
\) !
end selectFirst
 
@: $;
$ -> findOpenPosition -> #
when <{options: <=0"1">}> do row´1:[] !
when <{options: <=10"1">}> do $@ !
otherwisewhen <> 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::raw-1"1"} ! \) -> #
end deduceRemainingDigits
 
test 'internal solver'
def sample: row´1:[
col´1:[5,3,4,6,7,8,9,1,2],
col´1:[6,7,2,1,9,5,3,4,8],
col´1:[1,9,8,3,4,2,5,6,7],
col´1:[8,5,9,7,6,1,4,2,3],
col´1:[4,2,6,8,5,3,7,9,1],
col´1:[7,1,3,9,2,4,8,5,6],
col´1:[9,6,1,5,3,7,2,8,4],
col´1:[2,8,7,4,1,9,6,3,5],
col´1:[3,4,5,2,8,6,1,7,9]
];
 
assert $sample -> deduceRemainingDigits <=$sample> 'completed puzzle unchanged'
 
assert row´1:[
col´1:[[5],3,4,6,7,8,9,1,2],
$sample(row´2..last)...] -> deduceRemainingDigits <=$sample> 'final digit gets placed'
 
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:[
col´1:[[5],3,4,6,[2,5,7],8,9,1,[2,5]],
$sample(row´2..last)...] -> deduceRemainingDigits <=$sample> 'solves 3 digits on row'
 
assert row´1:[
col´1:[5,3,4,6,7,8,9,1,2],
col´1:[[6,7,9],7,2,1,9,5,3,4,8],
col´1:[1,9,8,3,4,2,5,6,7],
col´1:[8,5,9,7,6,1,4,2,3],
col´1:[4,2,6,8,5,3,7,9,1],
col´1:[[7],1,3,9,2,4,8,5,6],
col´1:[[7,9],6,1,5,3,7,2,8,4],
col´1:[2,8,7,4,1,9,6,3,5],
col´1:[3,4,5,2,8,6,1,7,9]
] -> deduceRemainingDigits <=$sample> 'solves 3 digits on column'
 
assert row´1:[
col´1:[5,3,[4,6],6,7,8,9,1,2],
col´1:[[6],7,2,1,9,5,3,4,8],
col´1:[1,[4,6,9],8,3,4,2,5,6,7],
$sample(row´4..last)...
] -> deduceRemainingDigits <=$sample> 'solves 3 digits in block'
 
// This gives a contradiction if 3 gets chosen out of [3,5]
assert row´1:[
col´1:[[3,5],[3,4,6],[3,4,6],[3,4,6],7,8,9,1,2],
$sample(row´2..last)...] -> deduceRemainingDigits <=$sample> 'contradiction is backtracked'
end 'internal solver'
 
composer parseSudoku
row´1:[<section>=3]
rule section: <row>=3 (<'-+'>? <WS>?)
rule row: col´1:[<triple>=3] (<WS>?)
rule triple: <digit|dot>=3 (<'\|'>?)
rule digit: [<'\d'>]
rule dot: <'\.'> -> [1..9 -> '$;']
end parseSudoku
 
test 'input sudoku'
def parsed:
Line 12,807 ⟶ 13,219:
...|419|..5
...|.8.|.79' -> parseSudoku;
 
assert $parsed <[<[<[]>=9](9)>=9](9)> 'parsed sudoku has 9 rows containing 9 columns of lists'
assert $parsed(row´1;col´1) <=['5']> 'a digit'
assert $parsed(row´1;col´3) <=['1','2','3','4','5','6','7','8','9']> 'a dot'
end 'input sudoku'
 
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;' !
$i -> \(when <=row´3|=row´6> do '-----------$#10;' !\) !
\) -> '$...;' !
end solveSudoku
 
test 'sudoku solver'
assert
Line 12,849 ⟶ 13,261:
'> 'solves sudoku and outputs pretty solution'
end 'sudoku solver'
</syntaxhighlight>
</lang>
 
=={{header|Tcl}}==
Line 12,856 ⟶ 13,268:
Note that you can implement more rules if you want. Just make another subclass of <code>Rule</code> and the solver will pick it up and use it automatically.
{{works with|Tcl|8.6}} or {{libheader|TclOO}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
oo::class create Sudoku {
variable idata
Line 13,104 ⟶ 13,516:
return 0
}
}</langsyntaxhighlight>
Demonstration code:
<langsyntaxhighlight lang="tcl">SudokuSolver create sudoku
sudoku load {
{3 9 4 @ @ 2 6 7 @}
Line 13,129 ⟶ 13,541:
}
}
sudoku destroy</langsyntaxhighlight>
{{out}}
<pre>+-----+-----+-----+
Line 13,145 ⟶ 13,557:
+-----+-----+-----+</pre>
If we'd added a logger method (after creating the <code>sudoku</code> object but before running the solver) like this:
<langsyntaxhighlight lang="tcl">oo::objdefine sudoku method Log msg {puts $msg}</langsyntaxhighlight>
Then this additional logging output would have been produced prior to the result being printed:
<pre>::RuleOnlyChoice solved ::sudoku at 8,0 for 1
Line 13,199 ⟶ 13,611:
 
=={{header|Ursala}}==
<langsyntaxhighlight Ursalalang="ursala">#import std
#import nat
 
Line 13,211 ⟶ 13,623:
~&rgg&& ~&irtPFXlrjrXPS; ~&lrK2tkZ2g&& ~&llrSL2rDrlPrrPljXSPTSL)+-,
//~&p ^|DlrDSLlrlPXrrPDSL(~&,num*+ rep2 block3)*= num block27 ~&iiK0 iota9,
* `0?=\~&iNC ! ~&t digits+-</langsyntaxhighlight>
test program:
<langsyntaxhighlight Ursalalang="ursala">#show+
 
example =
Line 13,228 ⟶ 13,640:
010067008
009008000
026400735]-</langsyntaxhighlight>
{{out}}
<pre>
Line 13,246 ⟶ 13,658:
=={{header|VBA}}==
{{trans|Fortran}}
<langsyntaxhighlight VBlang="vb">Dim grid(9, 9)
Dim gridSolved(9, 9)
 
Line 13,347 ⟶ 13,759:
Debug.Print
Next i
End Sub</langsyntaxhighlight>
{{out}}
<pre>
Line 13,366 ⟶ 13,778:
{{trans|VBA}}
To run in console mode with cscript.
<langsyntaxhighlight lang="vb">Dim grid(9, 9)
Dim gridSolved(9, 9)
Line 13,467 ⟶ 13,879:
End Sub 'Sudoku
 
Call sudoku</langsyntaxhighlight>
{{out}}
<pre>Problem:
Line 13,489 ⟶ 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}}
<langsyntaxhighlight ecmascriptlang="wren">class Sudoku {
construct new(rows) {
if (rows.count != 9 || rows.any { |r| r.count != 9 }) {
Line 13,569 ⟶ 14,139:
"000036040"
]
Sudoku.new(rows).solve()</langsyntaxhighlight>
 
{{out}}
Line 13,606 ⟶ 14,176:
can be verified by several other examples.
{{trans|C}}
<langsyntaxhighlight XPL0lang="xpl0">code ChOut=8, CrLf=9, IntOut=11, Text=12;
 
proc Show(X);
Line 13,676 ⟶ 14,246:
..9 ..8 ...
.26 4.. 735 ");
]</langsyntaxhighlight>
 
{{out}}
Line 13,695 ⟶ 14,265:
=={{header|zkl}}==
{{trans|C}} Note: Unlike in the C solution, 1<<-1 is defined (as 0).
<langsyntaxhighlight lang="zkl">fcn trycell(sdku,pos=0){
row,col:=pos/9, pos%9;
Line 13,716 ⟶ 14,286:
sdku[pos]=0;
return(False);
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">problem:=
#<<<
" 5 3 0 0 7 0 0 0 0
Line 13,735 ⟶ 14,305:
s[n*27,27].pump(Console.println,T(Void.Read,8),("| " + "%s%s%s | "*3).fmt); // 3 lines
println("+-----+-----+-----+");
}</langsyntaxhighlight>
{{out}}
<pre>
6

edits