【JavaScript】数独解析器 ver 1.0

来源:互联网 发布:住友酒店集团会员 知乎 编辑:程序博客网 时间:2024/05/02 05:07
<!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 gridfor (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 linefor (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" onclick="solveProblem()" value="Solve problem step by step"/><br/><div id="result" style="font-size:12px"></div></BODY></HTML>

原创粉丝点击