也许我几年前保存的一些东西可能会在下面给出一些想法,其中具有最多候选者的单元格而不是选择最少的单元格似乎可以确保在给定允许的情况下提供多个解决方案,然后停在计数等于二。否则尽可能解谜,只有在空单元数足够少的情况下,才可能进行计数。由于它是 html 代码,我不确定您是否可以看到它,但它是:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<TITLE>Sudoku Solver</TITLE>
<META name="Keywords" content="Sudoku, Simple, javascript, puzzle">
<META name="Description" content="Simple Sudoku Solver, written in JavaScript">
<script type="text/javascript">
function Board() {
this.cells=new Array();
for (var i=0; i<81; ++i)
this.cells[i]=0;
}
function CopyBoard(dest, src) {
for (var i=0; i<81; ++i)
dest.cells[i]=src.cells[i];
}
function CountConstraints(val) {
var cc=0;
for (var i=1; i<=9; ++i)
if (((1<<i) & val)!=0) ++cc;
return cc;
}
function MostConstrained() {
var max=-1, maxp=-1;
for (var i=0; i<81; ++i) {
if ((this.cells[i] & 1)==0) {
v=CountConstraints(this.cells[i]);
if (v>=max) {
max=v;
maxp=i;
}
}
}
return maxp;
}
Board.prototype.mostConstrained=MostConstrained;
function AllOptions(val) {
var cc=new Array;
var n=0;
for (var i=1; i<=9; ++i)
if (((1<<i) & val)==0) cc[n++]=i;
return cc;
}
function SetValue(pos, val) {
var x=pos%9;
var y=Math.floor(pos/9);
var x0=Math.floor(x/3)*3;
var y0=Math.floor(y/3)*3;
var add=(1<<val);
for (var k=0; k<9; ++k) {
this.cells[x+k*9]|=add;
this.cells[k+y*9]|=add;
this.cells[x0+(k%3)+9*(y0+Math.floor(k/3))]|=add;}
this.cells[pos]=1023-(1<<val);
}
Board.prototype.setValue=SetValue;
function CellText(d) {
if (d&1) {
for (var i=1; i<=9; ++i)
if ((d | (1<<i))==1023) return ""+i;
return "_";
}
else {
return "?"+AllOptions(d);
}
}
function AsHTML() {
var ans="";
for (var y=0; y<9; ++y) {
ans=ans+"<tr>"
for (var x=0; x<9; ++x) {
ans=ans+"<td class=sol>"+CellText(this.cells[x+y*9])+"<\/td>";
}
ans=ans+"<\/tr>";
}
return "<table border=1>"+ans+"<\/table>"
}
Board.prototype.asHTML=AsHTML;
function IsOK() {
for (var i=0; i<81; ++i) {
if ((this.cells[i] & 1022)==1022) {
return false;
}
}
return true;
}
function IsSolved() {
for (var i=0; i<81; ++i) {
if ((this.cells[i] & 1)==0) return false;
}
return true;
}
Board.prototype.isSolved=IsSolved;
Board.prototype.isOK=IsOK;
var theOne=new Board();
var numSol;
function SearchSolutions() {
while (this.isOK()) {
if (this.isSolved()) {
if (1<++numSol) return this;
CopyBoard(theOne,this);return null;}
var p=this.mostConstrained();
if (p<0) return null;
var l=AllOptions(this.cells[p]);
if (l.length<1) return null;
for (var i=1; i<l.length; ++i) {
var nb=new Board();
CopyBoard(nb, this);
nb.setValue(p, l[i]);
nb=nb.searchSolutions();
if (nb) return nb;}
this.setValue(p, l[0]);}
return null;
}
Board.prototype.searchSolutions=SearchSolutions;
function DrawInput() {
var ans="";
for (var y=0; y<9; ++y) {
ans=ans+"<tr>"
for (var x=0; x<9; ++x) {
ans=ans+"<td class=sol><input size=1 type=text id='C"+(x+y*9)+"'><\/td>";
}
ans=ans+"<\/tr>"
}
document.write("<table border=1>"+ans+"<\/table>");
}
function solve_click() {
var theSec=new Board();
numSol=0;
for (var i=0; i<81; ++i) {
var v=document.getElementById("C"+i).value
if (v>="1" && v<="9") theSec.setValue(i, parseInt(v));}
var rsp=theSec.searchSolutions();
var ans="<p>No solution<\/p>";
if (numSol==1) ans="<p>Valid Sudoku - One and only one solution !<\/p>"+theOne.asHTML();
if (numSol==2) ans="<p>Invalid Sudoku - More than one solution !<\/p>"+theOne.asHTML()+"<p><\/p>"+rsp.asHTML();
document.getElementById("answer").innerHTML=ans;
}
</SCRIPT>
<STYLE type=text/css>
.sol {
WIDTH: 1em; HEIGHT: 1em
}
</STYLE>
</HEAD>
<BODY>
<h1>Sudoku Solver</h1>
<a href="solverabout.html"><span style="font-size: smaller">(about)</span></a>
<div>
<script type="text/javascript">
DrawInput();
</script>
<input type="button" value="Solve" onclick="solve_click();">
</div>
<div id="answer"></div>
</BODY>
</HTML>