A logical game that uses paper and pen for computation. Players need to deduce all the numbers with spaces based on the known numbers on the 9 & #215; 9 disk, the numbers in each row, column, and inner line contain 1-9, not repeated. I changed the written java version to the javascript version. I wrote it for the first time and it was very unprofessional. sorry. Alas, how idle I am.
The code is as follows:
Var Sudoku = {
Init: function (str ){
This. blank = [];
This. fixed = [];
This. cell = [];
This. trials = [];
For (I = 0; I <81; I ++ ){
Var chr = 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 (){
Var board = "";
For (var I = 0; I <81; I ++ ){
If (I % 9 = 0 ){
Board = board. concat ("\ n ");
}
Board = board. concat ("[");
For (var j = 0; j <9; j ++ ){
If (this. cell [I]> j & 1) = 1 ){
Board = board. concat (String. fromCharCode (j + 49 ));
}
}
Board = board. concat ("]");
}
Return board;
},
Check: function (){
Var checkpoint = [0, 12, 24, 28, 40, 52, 56, 68, 80];
For (var I in checkpoint ){
Var r, 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 ){
Return false;
}
}
Return true;
},
BitCount: function (I ){
Var n = 0;
For (var j = 0; j <9; j ++ ){
If (I> j & 1) = 1)
N ++;
}
Return n;
},
NumberOfTrailingZeros: function (I ){
Var n = 0;
For (var j = 0; j <9; j ++ ){
If (I> j & 1) = 0)
N ++;
Else {
Break;
}
}
Return n;
},
UpdateCandidates: function (){
For (var I in this. fixed ){
Var opt = 0x1FF ^ this. cell [this. fixed [I];
For (var j = 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-0 candidate:" + x [this. fixed [I] [j]);
Return false;
}
}
}
Return true;
},
SeekUniqueCandidate: function (){
For (var bidx in this. blank ){
Var row = 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 (var I in this. 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); // to delete it in the loop wocould cause bug
_ Del. push (I );
}
}
While (_ del. length> 0 ){
This. blank. splice (_ del. pop (), 1 );
}
},
SeekMutexCell: function (){
Var two = [];
For (var n in this. blank ){
If (this. bitCount (this. cell [this. blank [n]) = 2 ){
Two. push (this. blank [n]);
}
}
For (var I = 0; I <two. length; I ++ ){
For (var j = I + 1; j <two. length; j ++ ){
If (this. cell [two [I] = this. cell [two [j]) {
Var opt = ~ 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 );
Return this. blank. length = 0;
},
SetTrialCell: function (){
For (var I in this. blank ){
If (this. bitCount (this. cell [this. blank [I]) = 2 ){
Var trialValue = 1 <this. numberOfTrailingZeros (this. cell [this. blank [I]);
Var waitingValue = 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 ));
Return true;
}
}
Return false;
},
BackForward: function (){
If (this. trials. length = 0 ){
Console. log ("Maybe no solution! ");
Return;
}
Var back = 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 (var I = 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't go backforward! Maybe no solution! ");
Break;
} Else {
This. backForward ();
This. basicSolve ();
}
}
}
},
Play: function (){
Console. log (this. showBoard ());
Var start = new Date (). getMilliseconds ();
If (! This. basicSolve ()){
This. trialSolve ();
}
Var end = new Date (). getMilliseconds ();
Console. log (this. showBoard ());
If (this. check ()){
Console. log ("[" + (end-start) + "ms OK!] ");
} Else {
Console. log ("[" + (end-start) + "ms, cannot solve it? ");
}
// Return this. showBoard ();
},
GetX: function (idx ){
Var neighbors = new Array (24 );
Var box = new Array (, 20 );
Var r = parseInt (idx/9 );
Var c = idx % 9;
Var xs = parseInt (idx/27) * 27 + parseInt (idx % 9/3) * 3;
Var I = 0;
For (var n = 0; n <9; n ++ ){
If (n = c) continue;
Neighbors [I ++] = r * 9 + n;
}
For (var n = 0; n <9; n ++ ){
If (n = r) continue;
Neighbors [I ++] = c + n * 9;
}
For (var n = 0; n <9; n ++ ){
Var t = xs + box [n];
If (t = idx) continue;
Neighbors [I ++] = t;
}
Return neighbors;
},
CreateTrialPoint: function (idx, val, board ){
Var tp = {};
Tp. idx = idx;
Tp. val = val;
Tp. data = board. concat ();
Return tp;
}
};
// Sudoku. init ("000000500000008300600100000080093000000000020700000000058000000000200017090000060 ");
// Sudoku. init ("530070000600195000098000060800060003400803001700020006060000280000419005000080079 ");
Sudoku. init ("800000000003600000070090200050007000000045700000100030001000068008500010090000400 ");
Sudoku. play ();
The above is all the code for implementing the Sudoku solution using javascript. I hope you will like it.