简体   繁体   中英

Java Sudoku brute force solver, how does it work?

So you find the code below here. Most of the code I understand, but there is one bit I don't. The place where we create the boolean array called digits and the bit after that 3 * (x / 3) .

I think it's used to check if each square in the sudoku has 9 unique numbers as well, but I'm not sure on how I can explain this to let's say someone next to me.

Why do I need the array of boolean here? Can someone explain to me what it is doing and why?

Kind regards!

public int[][] solvePuzzle(int[][] matrix) {
    int x, y = 0;

    boolean found = false;

    // First we check if the matrix contains any zeros.
    // If it does we break out of the for loop and continue to solving the puzzle.
    for (x = 0; x < 9; x++) {
        for (y = 0; y < 9; y++) {
            if (matrix[x][y] == 0) {
                found = true;
                break;
            }
        }

        if (found) {
            break;
        }
    }

    // If the puzzle doesn't contain any zeros we return the matrix
    // We now know that this is the solved version of the puzzle
    if (!found) {
        return matrix;
    }

    boolean digits[] = new boolean[11];

    for (int i = 0; i < 9; i++) {
        digits[matrix[x][i]] = true;
        digits[matrix[i][y]] = true;
    }

    int boxX = 3 * (x / 3), boxY = 3 * (y / 3);
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            digits[matrix[boxX + i][boxY + j]] = true;
        }
    }

    // We loop over all the numbers we have to check if the next number fits in the puzzle
    // We update the matrix and check recursively by calling the same function again to check if the puzzle is correct
    // If it's not correct we reset the matrix field to 0 and continue with the next number in the for loop
    for (int i = 1; i <= 9; i++) {
        if (!digits[i]) {
            matrix[x][y] = i;

            if (solvePuzzle(matrix) != null) {
                return matrix;
            }

            matrix[x][y] = 0;
        }
    }

    // The puzzle can't be solved so we return null
    return null;
}

I have added some explanation as comments inline:

//we need to know what digits are we still allowed to use
//(not used in this row, not used in this column, not used in
//the same 3x3 "sub-box")
boolean digits[] = new boolean[11];

//so we run through the rows/coumns around the place (x,y)
//we want to fill in this iteration
for (int i = 0; i < 9; i++) {
    //take a used number from the row of x (matrix[x][i]) and mark it
    // as used
    digits[matrix[x][i]] = true;
    //take a used number from the column of y (matrix[i][y]) and mark it
    // as used
    digits[matrix[i][y]] = true;
}

//find the top-left corner of the sub-box for the position (x,y) we
//want to fill in
//example: x is 8 -> 3 * 8/3 -> 6, so we start from 6
int boxX = 3 * (x / 3), boxY = 3 * (y / 3);

//iterate through the sub-box horizontally and vertically
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
    //take a used number from the sub-box and mark it
    // as used
        digits[matrix[boxX + i][boxY + j]] = true;
    }
}

There seem to be two issues you are unclear on:

  1. The boolean array - this array is used to track which digits have been used already on a specific row or column. So imagine a row of tick boxes each with a digit written next to it (the array index) - these boxes are checked or unchecked to show a digit has been used or not.

  2. The expressions 3* (x/3) and 3 * (y/3) - what you need to remember here is that this is integer division (that means the result of the division is always rounded down to an integer. For example if x=1 then 3 (x/3) is 3 (1/3) is 3 * (0) =0 (whereas if this was float division the result would be 3*(0.3333)=1. So these maths expressions essentially change you number to the next lowest multiple of three - that is 1 -> 0, 2 -> 0, 3 -> 3, 4 -> 3 etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM