Javascript-based Sudoku solving algorithm webpage _ javascript skills

Source: Internet
Author: User
The implementation of this algorithm is to simulate the thinking and computing process of the human brain. If you need it, you can refer to it. 1) when we get a question, we will first follow the conditions we already know, sort and analyze the data.

It is equivalent to writing all "OK items" in the 9th Palace, and marking "Possible options ".

Function refreshStat ()

2) afterwards, the thinking will enter the cycle of speculation/verification.

In cells 9, you can try "Possible options" to verify if they violate the existing conditions.

Each new branch has two final results: Answer/error.

The Code is as follows:


While (true ){
Var a = setOne ();
Var B = refreshStat ();
If (! A | B) {// If a = false or B = true, you can skip the loop.
Break;
}
}


The actual process of thinking is also to traverse the branches with fewer options.

Therefore, the program implementation is also to determine the point/2 branch/3 branch /....

3) When all paths are searched, the answer is not the only one, but contrary to the purpose of the sudoku game.

The following sections show all the Code. For ease of reading, the debugging information is not deleted.

The Code is as follows:




Sudoku solving program

Script
Function keygo (evt, obj ){
Key = window. event? Evt. keyCode: evt. which;
Var next = obj. tabIndex;
Var inputs = document. getElementsByTagName ("input ");
If (key = 38) {// else
If (next-9> = 0 ){
Inputs [next-9]. select ()
}
}
If (key = 40) {// else
If (next + 9 <81 ){
Inputs [next + 9]. select ()
}
}
If (key = 37) {// else
If (next-1> = 0 ){
Inputs [next-1]. select ()
}
}
If (key = 39) {// →
If (next + 1 <81) inputs [next + 1]. select ();
}
}
Script





004502006 <BR> 000000005 <BR> 002014007 <BR> 008000012 <BR> 070080050 <BR> 930020700 <BR> 600190200 <BR> 020000000 <BR> 300208500
You can copy the text to the bottom box and paste it at the bottom. 81 numeric sequences from left to right from top to bottom are not set to 0. Non-numeric characters in the middle are ignored.



Script
Var maxRow = 9;
Var maxCol = 9;
Var strTbody = ["







"];For (var I = 0; I <maxRow; I ++ ){StrTbody. push (" ");For (var j = 0; j <maxCol; j ++ ){StrTbody. push (" ");}StrTbody. push (" ");}StrTbody. push ("
");
Var sTbody = ["







"];For (var I = 0; I <maxRow; I ++ ){STbody. push (" ");For (var j = 0; j <maxCol; j ++ ){STbody. push (" ");}STbody. push (" ");}STbody. push ("

");
Var obj = document. getElementById ("sodukuTable ");
Obj. innerHTML = strTbody. join ("");
Var obj2 = document. getElementById ("statusDiv ");
Var grid = [
[5, 7, 0, 1, 2, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 6, 7, 0, 0, 0, 8, 0],
[3, 0, 4, 0, 0, 9, 0, 7, 0],
[0, 2, 0, 0, 7, 0, 0, 5, 0],
[0, 1, 0, 3, 0, 0, 9, 0, 2],
[0, 8, 0, 0, 0, 2, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 5, 4, 0, 6, 3];
Var candidatNum = [];
Var columns = [];
Var rows = [];
Var blook = [];
Var papers = 0;
Var discards = 0;
Var success = false;
Var steps = new Array ();
Var log1 = document. getElementById ("statusDiv ");

Function Step (current1, arrys ){
This. temp1 = new Array ();
This. step = [arrys [0], arrys [1], arrys [2];
For (var I = 0; I <9; I ++)
{
This. temp1 [I] = new Array ();
For (var j = 0; j <9; j ++)
{
This. temp1 [I] [j] = current1 [I] [j];
}
}
}
Out (grid );
Init ();

Function push (current1, I, j, n ){
Var s = new Step (current1, [I, j, n]);
Steps. push (s );
}
Function pop (){
Var step = steps. pop ();
Discards ++;
Grid = step. temp1;
Grid [step. step [0] [step. step [1] = step. step [2];
Var timeline = document. getElementById ('paperlist ');
Timeline. value + = ('discard: ['+ discards +']: ['+ papers +'] \ n ');
Timeline. scrollTop = timeline. scrollHeight;
Return step;
}

Function check (obj ){
If (obj. value = 0) return;
For (var I = 0; I <9; I ++ ){
For (var j = 0; j <9; j ++ ){
Var text = document. getElementById ("input" + (I * 9 + j ));
If (text. value = obj. value ){
Text. style. background = "green ";
} Else {
Text. style. background = "";
}
}

}

}
Function CheckNumInput (array, num, x, y ){
// Target:
// Conflict check parameter array: matrix num: Check value x/y: Check position
// No conflict exists in the row, and return true;
// If a conflict is found, return false;
If (rows [x] & (1 <num) = 0) & (columns [y] & (1 <num) = 0
& (Blook [parseInt (x/3) * 3 + parseInt (y/3)] & (1 <num) = 0 ){
Return true;
}
Return false;
}

Function out (array ){
Var result = true;
For (var I = 0; I <9; I ++)
{
For (var j = 0; j <9; j ++)
{
Document. getElementById ("input" + (I * 9 + j). value = array [I] [j];
If (array [I] [j] = 0) result = false;
}
}
Return result;
}
Function setOne (){
Var result = false;
// Target:
// Traverses the Matrix to check whether an error can be detected or refreshed.
For (var I = 0; I <9; I ++ ){
For (var j = 0; j <9; j ++ ){
// Target:
// (Grid [I] [j] = 0 & candidatNum [I] [j] [0] = 0)> no candidate number. An error occurred.
// (CandidatNum [I] [j] [0] = 1)> the candidate number is unique.
// CheckNumInput (grid, candidatNum [I] [j] [10], I, j)> check whether the number conforms to the logic
// No candidate number is determined. | the last candidate number does not conform to the logical conditions. Here, it is rolled back or an error is returned.
If (grid [I] [j] = 0 & candidatNum [I] [j] [0] = 0 |
(CandidatNum [I] [j] [0] = 1 &&! CheckNumInput (grid, candidatNum [I] [j] [10], I, j ))){
If (grid [I] [j] = 0 ){
Result = false;
}
If (steps. length> 0) {// rollback
Pop (); // The current tag has been proven to be a logical error and discarded
Return true;
} Else {
If (! Success ){
Alert ("Stack ended empty! "); // Question error, ended
}
Return false;
}
}
If (candidatNum [I] [j] [0] = 1) {// unique selection
Grid [I] [j] = candidatNum [I] [j] [10]; // update the matrix
RefreshStat3 (candidatNum [I] [j] [10], I, j); // update the row and column Palace
CandidatNum [I] [j] [0] = 0; // mark selected
Result = true;
Continue;
}

}
}
If (result = false) {// For (candidatNum [I] [j] [0]! = 1 ).
Return choose ();
}
Return result;
}
Function refreshStat3 (num, x, y) {// update the row and column Palace
Rows [x] | = 1 < Columns [y] | = 1 < Blook [parseInt (x/3) * 3 + parseInt (y/3)] | = 1 <num;

}
/*********************
* Matrix data analysis
* Remaining statistical options
*********************/
Function refreshStat (){
Var over = true;
// Target:
// Split rows/columns/Palace
For (var I = 0; I <9; I ++ ){
Rows [I] = 0; // row
Columns [I] = 0; // Column
Blook [I] = 0; // Palace
For (var j = 0; j <9; j ++ ){
If (grid [I] [j]! = 0 ){
Rows [I] | = 1 <grid [I] [j];
} Else {
Rows [I ~ (1 <grid [I] [j]);
}
If (grid [j] [I]! = 0 ){
Columns [I] | = 1 <grid [j] [I];
} Else {
Columns [I] & = ~ (1 <grid [j] [I]);
}
If (grid [parseInt (I/3) * 3 + parseInt (j/3)] [I % 3*3 + j % 3]! = 0 ){
Blook [I] | = 1 <grid [parseInt (I/3) * 3 + parseInt (j/3)] [I % 3*3 + j % 3];
}
}
}
// Target:
// Traverse the matrix and mark the candidates as candidatNum [I] [j] [0]
// CandidatNum [I] [j] [0] = 0; >>> the specified value already exists.
// CandidatNum [I] [j] [0] = k; >>> number of possible values
// CandidatNum [I] [j] [1] = 987654321x optional number in hexadecimal notation
For (var I = 0; I <9; I ++ ){
For (var j = 0; j <9; j ++ ){
If (grid [I] [j]! = 0 ){
CandidatNum [I] [j] [0] = 0;
Continue;
}
Var size = 0;
Over = false;
For (var k = 1; k <10; k ++ ){
If (CheckNumInput (grid, k, I, j )){
CandidatNum [I] [j] [1] | = 1 <k;
CandidatNum [I] [j] [10] = k;
Over = false;
Size ++;
} Else {
CandidatNum [I] [j] [1] & = ~ (1 <k );
}
}
CandidatNum [I] [j] [0] = size; // mark the number of remaining options
}
}
Return over;
}

Function calculate () {// function entry
// Read data
Var start = new Date ();
For (var I = 0; I <9; I ++)
{
For (var j = 0; j <9; j ++)
{
Var text = document. getElementById ("input" + (I * 9 + j ));
Grid [I] [j] = parseInt (text. value );
}
}

// Refresh the grid
RefreshStat ();
Out (grid );
// Computing matrix
While (true ){
Var a = setOne ();
Var B = refreshStat ();
If (! A | B) {// If a = false or B = true, you can skip the loop.
Break;
}
}
Out (grid); // Answer
Alert ("time used:" + (new Date ()-start) + "ms ");
Success = true;
// Computing ends

// Verify that the answer is unique
If (papers! = Discards ){
If (steps. length> 0) {// rollback
Pop (); // The current tag is discarded
// Computing matrix
While (true ){
Var a = setOne ();
Var B = refreshStat ();
If (! A | B) {// If a = false or B = true, you can skip the loop.
Break;
}
}
If (B ){
Alert ("the answer is not unique! Record! ");
Out (grid); // Answer
}
Else {
Alert ("the answer is unique !! "); // The answer is unique.
}
} Else {
Alert ("error ended! ");
Return false;
}
}
}
Function clearGrid (){
For (var I = 0; I <9; I ++ ){
For (var j = 0; j <9; j ++ ){
Grid [I] [j] = 0;
Document. getElementById ("input" + (I * 9 + j). value = grid [I] [j];
}
}
Out (grid );
}
Function init (){
For (var I = 0; I <9; I ++)
{CandidatNum [I] = new Array ();

For (var j = 0; j <9; j ++)
{CandidatNum [I] [j] = new Array ();

For (var k = 0; k <11; k ++)
{CandidatNum [I] [j] [k] = 0;
}
}
}
}
Function choose (){
// Target:
// Traverse the Matrix to create a search branch from the current position.
Var binarynode = false;
For (var I = 0; I <9; I ++ ){
For (var j = 0; j <9; j ++ ){
// 2. Cross-tree branch:
// If there are two possibilities at a location, option 1/Option 2
// It is assumed that option 1 is used for verification and a new tag is generated based on option 2.
If (candidatNum [I] [j] [0] = 2) {// There are 2 options
Binarynode = true;
Var found =-1;
For (var k = 1; k <10; k ++ ){
If (candidatNum [I] [j] [1] & (1 <k)> 0 ){
If (found> 0 ){
Papers ++;
Var timeline = document. getElementById ('paperlist ');
Timeline. value + = ('add papers: '+ papers +': '+ I + ''+ j +'' + k +' \ n ');
Timeline. scrollTop = timeline. scrollHeight;
Push (grid, I, j, k );
} Else {
Found = k;
}
}
}
Grid [I] [j] = found;
CandidatNum [I] [j] [0] = 0; // mark the selected tag on the current tag
Var timeline = document. getElementById ('paperlist ');
Timeline. value + = ('try CURRENT: '+ I + ''+ j +'' + found +' \ n ');
Timeline. scrollTop = timeline. scrollHeight;
Return true;
}
}
}
If (! Binarynode ){
Var timeline = document. getElementById ('paperlist ');
Timeline. value + = ('2 branch not found! \ N ');
Timeline. scrollTop = timeline. scrollHeight;
For (var I = 0; I <9; I ++ ){
For (var j = 0; j <9; j ++ ){
// If the search fails, start the 3-tree branch. As an extension, you can also start the 3-tree branch:
// If there are three possibilities in a location, option 1/OPTION 2/Option 3
// It is assumed that option 1 is used for verification and a new tag is generated based on option 2.
If (candidatNum [I] [j] [0] = 3) {// There are 3 options
Var timeline = document. getElementById ('paperlist ');
Timeline. value + = ('discover 3 forks! \ N ');
Timeline. scrollTop = timeline. scrollHeight;
Binarynode = true;
Var found =-1;
For (var k = 1; k <10; k ++ ){
If (candidatNum [I] [j] [1] & (1 <k)> 0 ){
If (found> 0 ){
Papers ++;
Var timeline = document. getElementById ('paperlist ');
Timeline. value + = ('add papers: '+ papers +': '+ I + ''+ j +'' + k +' \ n ');
Timeline. scrollTop = timeline. scrollHeight;
Push (grid, I, j, k );
} Else {
Found = k;
}
}
}
Grid [I] [j] = found;
CandidatNum [I] [j] [0] = 0; // mark the selected tag on the current tag
Var timeline = document. getElementById ('paperlist ');
Timeline. value + = ('try CURRENT: '+ I + ''+ j +'' + found +' \ n ');
Timeline. scrollTop = timeline. scrollHeight;
Return true;
}
}
}
}
Return false;
}
Function paste (){
Var gridstr = document. getElementById ("gtxt"). value;
Var a = gridstr. replace (/[^ 0-9]/g ,'');
If (a. length! = 81 ){
Alert ("Incorrect Data Format: \ n" + gridstr );
Return;
}
For (var I = 0; I <9; I ++)
{
For (var j = 0; j <9; j ++ ){
Grid [I] [j] = a. charAt (I * 9 + j );
Document. getElementById ("input" + (I * 9 + j). value = grid [I] [j];
}
}
Out (grid );
Papers = 0;
Discards = 0;
Success = false;
Steps = new Array ();
}
Script
We recommend that you use IE and F12 to enable the debugging mode.





Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.