javascript实现数独解法
生生把写过的java版改成javascript版,第一次写,很不专业,见谅。唉,我是有多闲。
varSudoku={
init:function(str){
this.blank=[];
this.fixed=[];
this.cell=[];
this.trials=[];
for(i=0;i<81;i++){
varchr=str.charCodeAt(i);
if(chr==48){
this.cell[i]=511;
this.blank.push(i);
}else{
this.cell[i]=1<<chr-49;
this.fixed.push(i);
}
}
},
showBoard:function(){
varboard="";
for(vari=0;i<81;i++){
if(i%9==0){
board=board.concat("\n");
}
board=board.concat("[");
for(varj=0;j<9;j++){
if((this.cell[i]>>j&1)==1){
board=board.concat(String.fromCharCode(j+49));
}
}
board=board.concat("]");
}
returnboard;
},
check:function(){
varcheckpoint=[0,12,24,28,40,52,56,68,80];
for(variincheckpoint){
varr,b,c;
r=b=c=this.cell[checkpoint[i]];
for(j=0;j<8;j++){
c^=this.cell[this.getX(checkpoint[i])[j]];
b^=this.cell[this.getX(checkpoint[i])[8+j]];
r^=this.cell[this.getX(checkpoint[i])[16+j]];
}
if((r&b&c)!=0x1FF){
returnfalse;
}
}
returntrue;
},
bitCount:function(i){
varn=0;
for(varj=0;j<9;j++){
if((i>>j&1)==1)
n++;
}
returnn;
},
numberOfTrailingZeros:function(i){
varn=0;
for(varj=0;j<9;j++){
if((i>>j&1)==0)
n++;
else{
break;
}
}
returnn;
},
updateCandidates:function(){
for(variinthis.fixed){
varopt=0x1FF^this.cell[this.fixed[i]];
for(varj=0;j<24;j++){
this.cell[this.getX(this.fixed[i])[j]]&=opt;
//!notice
if(this.cell[this.getX(this.fixed[i])[j]]==0){
//console.log("Error-0candidate:"+x[this.fixed[i]][j]);
returnfalse;
}
}
}
returntrue;
},
seekUniqueCandidate:function(){
for(varbidxinthis.blank){
varrow=0,col=0,box=0;
for(i=0;i<8;i++){
row|=this.cell[this.getX(this.blank[bidx])[i]];
box|=this.cell[this.getX(this.blank[bidx])[8+i]];
col|=this.cell[this.getX(this.blank[bidx])[16+i]];
}
if(this.bitCount(this.cell[this.blank[bidx]]&~row)==1){
this.cell[this.blank[bidx]]&=~row;
continue;
}
if(this.bitCount(this.cell[this.blank[bidx]]&~col)==1){
this.cell[this.blank[bidx]]&=~col;
continue;
}
if(this.bitCount(this.cell[this.blank[bidx]]&~box)==1){
this.cell[this.blank[bidx]]&=~box;
}
}
},
seekFilledable:function(){
this.fixed=[];
var_del=[];
for(variinthis.blank){
if(this.bitCount(this.cell[this.blank[i]])==1){
this.fixed.push(this.blank[i]);
//console.log("fixed:"+this.blank[i]+"=>"+this.cell[this.blank[i]]);
//this.blank.splice(i,1);//todeleteitintheloopwouldcausebug
_del.push(i);
}
}
while(_del.length>0){
this.blank.splice(_del.pop(),1);
}
},
seekMutexCell:function(){
vartwo=[];
for(varninthis.blank){
if(this.bitCount(this.cell[this.blank[n]])==2){
two.push(this.blank[n]);
}
}
for(vari=0;i<two.length;i++){
for(varj=i+1;j<two.length;j++){
if(this.cell[two[i]]==this.cell[two[j]]){
varopt=~this.cell[two[i]];
if(parseInt(two[i]/9)==parseInt(two[j]/9)){
for(n=0;n<8;n++){
this.cell[this.getX(two[i])[n]]&=opt;
}
}
if((two[i]-two[j])%9==0){
for(n=8;n<16;n++){
this.cell[this.getX(two[i])[n]]&=opt;
}
}
if((parseInt(two[i]/27)*3+parseInt(two[i]%9/3))==(parseInt(two[j]/27)*3+parseInt(two[j]%9/3))){
for(n=16;n<24;n++){
this.cell[this.getX(two[i])[n]]&=opt;
}
}
this.cell[two[j]]=~opt;
}
}
}
},
basicSolve:function(){
do{
if(!this.updateCandidates(this.fixed)){
this.backForward();
}
this.seekUniqueCandidate();
this.seekMutexCell();
this.seekFilledable();
}while(this.fixed.length!=0);
returnthis.blank.length==0;
},
setTrialCell:function(){
for(variinthis.blank){
if(this.bitCount(this.cell[this.blank[i]])==2){
vartrialValue=1<<this.numberOfTrailingZeros(this.cell[this.blank[i]]);
varwaitingValue=this.cell[this.blank[i]]^trialValue;
//console.log("try:["+this.blank[i]+"]->"+(this.numberOfTrailingZeros(trialValue)+1)+"#"+(this.numberOfTrailingZeros(waitingValue)+1));
this.cell[this.blank[i]]=trialValue;
this.trials.push(this.createTrialPoint(this.blank[i],waitingValue,this.cell));
returntrue;
}
}
returnfalse;
},
backForward:function(){
if(this.trials.length==0){
console.log("Maybenosolution!");
return;
}
varback=this.trials.pop();
this.reset(back.data);
this.cell[back.idx]=back.val;
this.fixed.push(back.idx);
//console.log("back:["+back.idx+"]->"+(this.numberOfTrailingZeros(back.val)+1));
},
reset:function(data){
this.blank=[];
this.fixed=[];
this.cell=data.concat();
for(vari=0;i<81;i++){
if(this.bitCount(this.cell[i])!=1){
this.blank.push(i);
}else{
this.fixed.push(i);
}
}
},
trialSolve:function(){
while(this.blank.length!=0){
if(this.setTrialCell()){
this.basicSolve();
}else{
if(this.trials.length==0){
//console.log("Can'tgobackforward!Maybenosolution!");
break;
}else{
this.backForward();
this.basicSolve();
}
}
}
},
play:function(){
console.log(this.showBoard());
varstart=newDate().getMilliseconds();
if(!this.basicSolve()){
this.trialSolve();
}
varend=newDate().getMilliseconds();
console.log(this.showBoard());
if(this.check()){
console.log("["+(end-start)+"msOK!]");
}else{
console.log("["+(end-start)+"ms,cannotsolveit?");
}
//returnthis.showBoard();
},
getX:function(idx){
varneighbors=newArray(24);
varbox=newArray(0,1,2,9,10,11,18,19,20);
varr=parseInt(idx/9);
varc=idx%9;
varxs=parseInt(idx/27)*27+parseInt(idx%9/3)*3;
vari=0;
for(varn=0;n<9;n++){
if(n==c)continue;
neighbors[i++]=r*9+n;
}
for(varn=0;n<9;n++){
if(n==r)continue;
neighbors[i++]=c+n*9;
}
for(varn=0;n<9;n++){
vart=xs+box[n];
if(t==idx)continue;
neighbors[i++]=t;
}
returnneighbors;
},
createTrialPoint:function(idx,val,board){
vartp={};
tp.idx=idx;
tp.val=val;
tp.data=board.concat();
returntp;
}
};
//Sudoku.init("000000500000008300600100000080093000000000020700000000058000000000200017090000060");
//Sudoku.init("530070000600195000098000060800060003400803001700020006060000280000419005000080079");
Sudoku.init("800000000003600000070090200050007000000045700000100030001000068008500010090000400");
Sudoku.play();
以上就是关于使用javascript实现数独解法的全部代码了,希望大家能够喜欢。