Armada Productions

Learning About Loops and Arrays Wtih Sudoku

   One particular topic in programming catches my attention every time. And that is loops. Loops are incredibly powerful and fun to use tools when it comes to solving problems. And while they may lead to efficiency issues in the algorithm if left unchecked, they are a vital piece to the success of a coder.

   During a web development course, I was trying to find a fun and simple project to tackle to try and start getting into coding shape. And one day at work on the break room table I saw an unfinished Sudoku puzzle in the daily paper and sat down to work on it. Shortly after that, it became clear that the person who started the puzzle had made some mistakes with their numbers. That is the moment I began pondering making a Sudoku solver.

   Now to briefly cover the basics of Sudoku. The board is a 9X9 grid, which is also broken down into 9 groups of smaller 3X3 grids (shown below). The rules are fairly simple, the individual squares must be filled with a single digit (1-9), but that same number cannot be contained in the same column, row, or 3X3 grid as itself. For example, if the very first square contained a "3", then there could not be another "3" in the entire first row, nor in the entire first column, and also no other "3" can be within the first 3X3 grid. The puzzle is generally scaled from easier to harder based on the numbers that the player is given to start with.

A 9X9 Sudoku grid
A Sudoku grid.

   With the basics of Sudoku out of the way, it appeared to be pretty clear to me that the Sudoku board could be represented by a 2-dimensional array. In my code that looks like this:

					
puzzle = [
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0]
];
					
				

  What this represents is each row is an array of 9 individual numbers, each column is a new array, and that is all encapsualted into one larger array container. This way you could call on an individual square easily by identifying it's position with 'X' and 'Y' coordinates. I will show the main code snippet from the solver below, which highlights several loops being used to parse through the puzzle. (There are two puzzle arrays being used, the Sudoku puzzle itself which is being built as it progresses, and another for checking to see if the currently selected square was a pre-filled number to start the puzle out). There is code in there calling other functions that I made. They are very simple functions using loops to just verify that the row/column/3X3 grid do not already contain a given number. If they do, the loop goes to the next number.

						
function clearPuzzle() {
    emptyPuzzle();

    for (var xPos = 0; xPos < 9; xPos++) { // loop to go through the x coordinates of the puzzle
        for (var yPos = 0; yPos < 9; yPos++) { 
            document.getElementById(xPos + "," + yPos).value = "";
        }
    }
}


for (var xPos = 0; xPos < 9; xPos++) { // loop to go through the x coordinates of the puzzle
        for (var yPos = 0; yPos < 9; yPos++) { // loop to go through the y coordinates of the puzzle
            if (puzzleSet[xPos][yPos] == 2) { // Check if the box is a set input, if it is then skip over this box
                puzzle[xPos][yPos] = "" + puzzle[xPos][yPos] + "";
                continue; 
            } 
            else {
                for (var x = 1; x < 10; x++) { // loop goes through possible numbers for each box
                    puzzle[xPos][yPos] = x; // sets the box to the value it will check
                    if (verifyGrid(puzzle, xPos, yPos) && verifyRow(puzzle,xPos, yPos) && verifyColumn(puzzle,xPos, yPos)) { 
                        // calls functions to check if the number is valid, if it is currently valid, it will break and proceed to the next box
                        break;
                    }
                    while ( (!verifyGrid(puzzle, xPos, yPos) || !verifyRow(puzzle,xPos, yPos) || !verifyColumn(puzzle,xPos, yPos)) && x == 9) {
                        // if the value goes up to 9 and none of the values have passed
                        // it will set the current box to 0 and decrement the y coordinate
                        puzzle[xPos][yPos] = 0
                        yPos--;
                        // if the y coordinate drop below 0, it will decrement the x coordinate and set the y coordinate to 8
                        // this sends the 'pointer' up a row and to the farthest right box
                        if(yPos < 0) {
                            yPos = 8;
                            xPos--;
                        }
                        if (xPos < 0) {
                            alert("Not solvable.");
                            return;
                        }
                        while ( (puzzleSet[xPos][yPos] == 2) || (puzzle[xPos][yPos] == 9) ) {
                            // this loop effectively does the same as the above lines
                            // the difference is this is checking to make sure the new position is not a set puzzle number
                            // if it is, it decrements again
                            if (puzzleSet[xPos][yPos] != 2) { puzzle[xPos][yPos] = 0; }
                            yPos--;
                            if(yPos < 0) {
                                yPos = 8;
                                xPos--;
                            }
                            if (xPos < 0) {
                                alert("Not solvable.");
                                return;
                            }
                        }
                    }
                    // when the above lines are finished and the 'pointer' is now at the previous box
                    // this sets the x for the loop to the current value of the previous box 
                    // the loop will then increment x and check the next values
                    x = puzzle[xPos][yPos];
                }
            }
            // this populates the boxes in the page with the correct numbers that solve the puzzle
            //document.getElementById(xPos + "," + yPos).value = puzzle[xPos][yPos];
            
        }

    }

						
					

   There is some more code that can be covered if anyone would like to check it out, but I will also post a link so you can try out the puzzle solver for yourself. It is far from perfect and still has some bugs to work out, but it is mostly functional and can solve puzzles as long as they are actually solvable puzzles.



My Sudoku Solver