<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>数独解析器 ver 1.0</TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="莲兮奈若何-杜子兮(lotusiki)">
<META NAME="Keywords" CONTENT="数独 深度优先搜索 排除法">
<META NAME="Description" CONTENT="以九宫格、行、列为单位,优先选择空格少的进行1~9的数字排列。用数组存储解空间,总体上以深度优先算法求解。">
<META NAME="CreateDate" CONTENT="2013.1.18">
</HEAD>
<script language="javascript">
var time=0; //解析次数
var arr=[]; //当前数字填充状态(9 X 9)
var type; //空格数最少的单位类型:格、行、列
var emptyNum=[]; //每个单位的空格数
var emptySum; //空格数之和
var solve=[]; //解空间
var stepNo=0; //搜索深度
var way=1; //当前状态下第n种可能性
var notFound=false; //是否找到解
function solveProblem(){
time++;
getProblem();
if(emptySum==0){
alert("结果已算出!");
return;
}
findStep();
if(notFound){
goBack();
}else{
way=1;
}
inputValue();
showSolve();
}
function getProblem(){
emptySum=0;
for(var i=1;i<=9;i++){
arr[i]=[];
for (var j=1;j<=9;j++){
arr[i][j]=document.getElementById("txt"+i+""+j).value;
}
}
for (var i=1;i<28 ;i++ ){
emptyNum[i]=0;
}
for (var i=1;i<=9 ;i++ ){
for (var j=1;j<=9 ;j++ ){
var gridNo=getGrid(i,j);
if (arr[i][j]==""){
emptyNum[gridNo]++;
emptyNum[9+i]++;
emptyNum[18+i]++;
emptySum++;
}
}
}
}
function findStep(){
var min=9;
var iMin=1;
var num=0;
var ll=[1,1,1,1,1,1,1,1,1];
var I=[];
var J=[];
var L=[];
var aL=[];
var x0,y0;
stepNo++;
for (var i=1;i<28 ;i++ ){
if ((emptyNum[i]<min)&&(emptyNum[i]!=0)){
min=emptyNum[i];
iMin=i;
}
}
if (iMin<=9){
type="grid";
x0=getX0(iMin);
y0=getY0(iMin);
for (var i=x0;i<x0+3 ;i++ ){
for (var j=y0;j<y0+3 ;j++ ){
if (arr[i][j]==""){
I[I.length]=i;
J[J.length]=j;
}else{
ll[arr[i][j]-1]=0;
}
}
}
}else if (iMin<=18){
type="line";
x0=iMin-9;
for (var j=1;j<=9 ;j++ ){
if (arr[x0][j]==""){
I[I.length]=x0;
J[J.length]=j;
}else{
ll[arr[x0][j]-1]=0;
}
}
}else{
type="list";
y0=iMin-18;
for (var i=1;i<=9 ;i++ ){
if (arr[i][y0]==""){
I[I.length]=i;
J[J.length]=y0;
}else{
ll[arr[i][y0]-1]=0;
}
}
}
for (var i=0;i<9 ;i++ ){
if (ll[i]){
L[L.length]=i+1;
}
}
if (min==1){
if (checkOk(iMin,I,J,L)){
num++;
memoWay(stepNo,num,I,J,L);
}
}
if (min==2){
for (var a=0;a<min ;a++ ){
for (var b=0;b<min ;b++ ){
if (L[a]!=L[b]){
aL=[L[a],L[b]];
if (!checkOk(iMin,I,J,aL)){
break;
}
num++;
memoWay(stepNo,num,I,J,aL);
}
}
}
}
if (min==3){
for (var a=0;a<min ;a++ ){
for (var b=0;b<min ;b++ ){
for (var c=0;c<min ;c++ ){
if ((L[a]!=L[b])&&(L[a]!=L[c])&&(L[b]!=L[c])){
aL=[L[a],L[b],L[c]];
if (!checkOk(iMin,I,J,aL)){
break;
}
num++;
memoWay(stepNo,num,I,J,aL);
}
}
}
}
}
if (min==4){
for (var a=0;a<min ;a++ ){
for (var b=0;b<min ;b++ ){
for (var c=0;c<min ;c++ ){
for (var d=0;d<min ;d++ ){
if ((L[a]!=L[b])&&(L[a]!=L[c])&&(L[a]!=L[d])&&(L[b]!=L[c])&&(L[b]!=L[d])&&(L[c]!=L[d])){
aL=[L[a],L[b],L[c],L[d]];
if (!checkOk(iMin,I,J,aL)){
break;
}
num++;
memoWay(stepNo,num,I,J,aL);
}
}
}
}
}
}
if (min==5){
for (var a=0;a<min ;a++ ){
for (var b=0;b<min ;b++ ){
for (var c=0;c<min ;c++ ){
for (var d=0;d<min ;d++ ){
for (var e=0;e<min ;e++ ){
if ((L[a]!=L[b])&&(L[a]!=L[c])&&(L[a]!=L[d])&&(L[a]!=L[e])&&(L[b]!=L[c])&&(L[b]!=L[d])&&(L[b]!=L[e])&&(L[c]!=L[d])&&(L[c]!=L[e])&&(L[d]!=L[e])){
aL=[L[a],L[b],L[c],L[d],L[e]];
if (!checkOk(iMin,I,J,aL)){
break;
}
num++;
memoWay(stepNo,num,I,J,aL);
}
}
}
}
}
}
}
if (num==0){
notFound=true;
for (var i=0;i<solve.length ;i++ ){
if ((solve[i][0]==stepNo)&&(solve[i][1]==way-1)){
arr[solve[i][2]][solve[i][3]]="";
}
if ((solve[i][5]!="XX")&&(solve[i][0]==stepNo-1)&&(solve[i][1]==way)){
solve[i][5]="XX";
arr[solve[i][2]][solve[i][3]]="";
try {
if (solve[i+1][1]!=way){
break;
}
}catch(e){
}
}
}
}else{
notFound=false;
}
}
function checkOk(iMin,I,J,L){
for (var l=0;l<I.length ;l++ ){
var gridNo=getGrid(I[l],J[l]);
var x0=getX0(gridNo);
var y0=getY0(gridNo);
//1st: check the grid
for (var i=x0;i<x0+3 ;i++ ){
for (var j=y0;j<y0+3 ;j++ ){
if (!(i==I[l])&&(j==J[l])){
if (arr[i][j]==L[l].toString()){
return false;
}
}
}
}
//2nd: check the line
for (var j=1; j<=9; j++){
if ((j!=J[l])&&(arr[I[l]][j]==L[l].toString())){
return false;
}
}
//3rd: check the list
for (var i=1; i<=9; i++){
if ((i!=I[l])&&(arr[i][J[l]]==L[l].toString())){
return false;
}
}
}
return true;
}
function memoWay(stepNo,num,I,J,aL){
for (var i=0;i<I.length ;i++ ){
solve[solve.length]=[];
solve[solve.length-1][0]=stepNo;
solve[solve.length-1][1]=num;
solve[solve.length-1][2]=I[i];
solve[solve.length-1][3]=J[i];
solve[solve.length-1][4]=aL[i];
solve[solve.length-1][5]="ok";
}
}
function goBack(){
for (var i=0;i<solve.length ;i++ ){
if ((solve[i][0]==stepNo)&&(solve[i][1]==way)){
arr[solve[i][2]][solve[i][3]]="";
}
}
stepNo--;
if (stepNo<0){
alert("未能求得可行解");
return;
}
way++;
var exist=false;
for (var i=0;i<solve.length ;i++ ){
if ((solve[i][0]==stepNo)&&(solve[i][1]==way)&&(solve[i][5]!="XX")){
exist=true;
break;
}
}
if (!exist){
for (var i=0;i<solve.length ;i++ ){
if ((solve[i][0]==stepNo-1)&&(solve[i][5]=="ok")){
way=solve[i][1];
break;
}
}
for (var i=0;i<solve.length ;i++ ){
if ((solve[i][0]==stepNo-1)&&(solve[i][1]==way)&&(solve[i][5]=="ok")){
solve[i][5]="XX";
arr[solve[i][2]][solve[i][3]]="";
try{
if (solve[i+1][1]!=way){
break;
}
}catch(e){}
}
}
goBack();
}
}
function inputValue(){
for (var i=0;i<solve.length ;i++ ){
if ((solve[i][0]==stepNo)&&(solve[i][1]==way)&&(solve[i][5]=="ok")){
arr[solve[i][2]][solve[i][3]]=solve[i][4];
document.getElementById("txt"+solve[i][2]+solve[i][3]).style.color="blue";
}
}
}
function showSolve(){
for (var i=1;i<=9 ;i++ ){
for (var j=1;j<=9 ;j++ ){
document.getElementById("txt"+i+""+j).value=arr[i][j];
}
}
var strHTML="Time:"+time+" Step:"+stepNo+" way:"+way+"<br/>";
for (var i=0;i<solve.length ;i++ ){
strHTML+=solve[i]+"<br/>";
}
document.getElementById("result").innerHTML=strHTML;
}
function getGrid(x,y){
if ((x<4)&&(y<4)){
return 1;
}else if((x>=4)&&(x<7)&&(y<4)){
return 2;
}else if((x>=7)&&(y<4)){
return 3;
}else if((x<4)&&(y>=4)&&(y<7)){
return 4;
}else if((x>=4)&&(x<7)&&(y>=4)&&(y<7)){
return 5;
}else if((x>=7)&&(y>=4)&&(y<7)){
return 6;
}else if((x<4)&&(y>=7)){
return 7;
}else if((x>=4)&&(x<7)&&(y>=7)){
return 8;
}else{
return 9;
}
}
function getX0(iMin){
if(iMin%3==1){
return 1;
}else if (iMin%3==2){
return 4;
}else{
return 7;
}
}
function getY0(iMin){
if(iMin<=3){
return 1;
}else if (iMin<=6){
return 4;
}else{
return 7;
}
}
</script>
<BODY>
<input id="txt11" type="text" style="width:22;text-align:center" value="5"/>
<input id="txt12" type="text" style="width:22;text-align:center" value=""/>
<input id="txt13" type="text" style="width:22;text-align:center" value=""/>
<input id="txt14" type="text" style="width:22;text-align:center" value="3"/>
<input id="txt15" type="text" style="width:22;text-align:center" value=""/>
<input id="txt16" type="text" style="width:22;text-align:center" value="2"/>
<input id="txt17" type="text" style="width:22;text-align:center" value=""/>
<input id="txt18" type="text" style="width:22;text-align:center" value=""/>
<input id="txt19" type="text" style="width:22;text-align:center" value="6"/><br/>
<input id="txt21" type="text" style="width:22;text-align:center" value=""/>
<input id="txt22" type="text" style="width:22;text-align:center" value=""/>
<input id="txt23" type="text" style="width:22;text-align:center" value="1"/>
<input id="txt24" type="text" style="width:22;text-align:center" value=""/>
<input id="txt25" type="text" style="width:22;text-align:center" value="6"/>
<input id="txt26" type="text" style="width:22;text-align:center" value=""/>
<input id="txt27" type="text" style="width:22;text-align:center" value="8"/>
<input id="txt28" type="text" style="width:22;text-align:center" value=""/>
<input id="txt29" type="text" style="width:22;text-align:center" value=""/><br/>
<input id="txt31" type="text" style="width:22;text-align:center" value=""/>
<input id="txt32" type="text" style="width:22;text-align:center" value="2"/>
<input id="txt33" type="text" style="width:22;text-align:center" value=""/>
<input id="txt34" type="text" style="width:22;text-align:center" value=""/>
<input id="txt35" type="text" style="width:22;text-align:center" value="1"/>
<input id="txt36" type="text" style="width:22;text-align:center" value=""/>
<input id="txt37" type="text" style="width:22;text-align:center" value=""/>
<input id="txt38" type="text" style="width:22;text-align:center" value="3"/>
<input id="txt39" type="text" style="width:22;text-align:center" value=""/><br/>
<input id="txt41" type="text" style="width:22;text-align:center" value="3"/>
<input id="txt42" type="text" style="width:22;text-align:center" value=""/>
<input id="txt43" type="text" style="width:22;text-align:center" value=""/>
<input id="txt44" type="text" style="width:22;text-align:center" value="2"/>
<input id="txt45" type="text" style="width:22;text-align:center" value=""/>
<input id="txt46" type="text" style="width:22;text-align:center" value="4"/>
<input id="txt47" type="text" style="width:22;text-align:center" value=""/>
<input id="txt48" type="text" style="width:22;text-align:center" value=""/>
<input id="txt49" type="text" style="width:22;text-align:center" value="7"/><br/>
<input id="txt51" type="text" style="width:22;text-align:center" value=""/>
<input id="txt52" type="text" style="width:22;text-align:center" value="7"/>
<input id="txt53" type="text" style="width:22;text-align:center" value="2"/>
<input id="txt54" type="text" style="width:22;text-align:center" value=""/>
<input id="txt55" type="text" style="width:22;text-align:center" value=""/>
<input id="txt56" type="text" style="width:22;text-align:center" value=""/>
<input id="txt57" type="text" style="width:22;text-align:center" value="4"/>
<input id="txt58" type="text" style="width:22;text-align:center" value="5"/>
<input id="txt59" type="text" style="width:22;text-align:center" value=""/><br/>
<input id="txt61" type="text" style="width:22;text-align:center" value="9"/>
<input id="txt62" type="text" style="width:22;text-align:center" value=""/>
<input id="txt63" type="text" style="width:22;text-align:center" value=""/>
<input id="txt64" type="text" style="width:22;text-align:center" value="6"/>
<input id="txt65" type="text" style="width:22;text-align:center" value=""/>
<input id="txt66" type="text" style="width:22;text-align:center" value=""/>
<input id="txt67" type="text" style="width:22;text-align:center" value="3"/>
<input id="txt68" type="text" style="width:22;text-align:center" value=""/>
<input id="txt69" type="text" style="width:22;text-align:center" value=""/><br/>
<input id="txt71" type="text" style="width:22;text-align:center" value=""/>
<input id="txt72" type="text" style="width:22;text-align:center" value="8"/>
<input id="txt73" type="text" style="width:22;text-align:center" value=""/>
<input id="txt74" type="text" style="width:22;text-align:center" value=""/>
<input id="txt75" type="text" style="width:22;text-align:center" value="3"/>
<input id="txt76" type="text" style="width:22;text-align:center" value=""/>
<input id="txt77" type="text" style="width:22;text-align:center" value=""/>
<input id="txt78" type="text" style="width:22;text-align:center" value="9"/>
<input id="txt79" type="text" style="width:22;text-align:center" value=""/><br/>
<input id="txt81" type="text" style="width:22;text-align:center" value=""/>
<input id="txt82" type="text" style="width:22;text-align:center" value=""/>
<input id="txt83" type="text" style="width:22;text-align:center" value="5"/>
<input id="txt84" type="text" style="width:22;text-align:center" value=""/>
<input id="txt85" type="text" style="width:22;text-align:center" value="4"/>
<input id="txt86" type="text" style="width:22;text-align:center" value=""/>
<input id="txt87" type="text" style="width:22;text-align:center" value="2"/>
<input id="txt88" type="text" style="width:22;text-align:center" value=""/>
<input id="txt89" type="text" style="width:22;text-align:center" value=""/><br/>
<input id="txt91" type="text" style="width:22;text-align:center" value="4"/>
<input id="txt92" type="text" style="width:22;text-align:center" value=""/>
<input id="txt93" type="text" style="width:22;text-align:center" value=""/>
<input id="txt94" type="text" style="width:22;text-align:center" value="7"/>
<input id="txt95" type="text" style="width:22;text-align:center" value=""/>
<input id="txt96" type="text" style="width:22;text-align:center" value="6"/>
<input id="txt97" type="text" style="width:22;text-align:center" value=""/>
<input id="txt98" type="text" style="width:22;text-align:center" value=""/>
<input id="txt99" type="text" style="width:22;text-align:center" value="5"/><br/>
<input type="button" οnclick="solveProblem()" value="Solve problem step by step"/><br/>
<div id="result" style="font-size:12px"></div>
</BODY>
</HTML>
【JavaScript】数独解析器 ver 1.0
最新推荐文章于 2023-11-29 23:07:33 发布