Java Sudoku Solver选择消除错误

时间:2016-07-29 18:04:45

标签: java debugging sudoku

我使用四维数组在Java中编写数独求解器,其中维度描述了单元格在板上的位置,分配给它们的值是单元格可能的数字。 Sudoku Wikipedia, for reference

为了清晰起见,我编写了打印电路板的Unicode艺术表示的方法,以及打印电路板上每个单元的所有选项的方法。这些方法有效。但是,我从单个行,列和框中的其他单元格中消除单例的方法无法正常工作(从未知单元格中移除同一行/列/框中的所有已知单元格)。请注意,左上角的单元格(choiceArray[0][0][0][0])应该是字符串467,而是23478。这是我写的代码。数独板输入为81个字符的字符串,其中0' s表示初始板中的空单元格。

(除了回答这个问题之外,我还会欣赏来自比我更有经验的程序员的风格/程序建议,因为我非常喜欢初学者)

public class SudokuSolver {
    public static void main(String[] args) {

        String initialBoard = "020501090800203006030060070001000600540000019002000700090030080200804007010907060";

        //Parsing the input to make sure that it is valid
        if (!(initialBoard.matches("[0-9]+") && initialBoard.length() == 81)) {
            System.err.println("Input board was not valid.");
            System.exit(0);
        }

        //Generating the sudoku board
        printBoard(initialBoard);

        //Generating an array for the given information
        String[][][][] choiceArray = new String[3][3][3][3];
        for(int i = 0; i < 3; i++) { //row of box
            for(int j = 0; j < 3; j++) { //column of box
                for(int k = 0; k < 3; k++) { //row in box
                    for(int l = 0; l < 3; l++) { //column in box
                        int cellNumber = 27 * i + 3 * j + 9 * k + l;
                        char cellContents = initialBoard.charAt(cellNumber);

                        if(cellContents == '0') {
                            choiceArray[i][j][k][l] = "123456789";
                        }
                        else {
                            choiceArray[i][j][k][l] = Character.toString(cellContents);
                        }
                    }
                }
            }
        }

        //Removing singletons
        while(!(puzzleIsSolved(choiceArray))) {
            boolean boardChanges = false;

            for(int i = 0; i < 3; i++) { //row of box
                for(int j = 0; j < 3; j++) { //column of box
                    for(int k = 0; k < 3; k++) { //row in box
                        for(int l = 0; l < 3; l++) { //column in box
                            if(choiceArray[i][j][k][l].length() == 1) {
                                String solvedCell = choiceArray[i][j][k][l];

                                //Removing choice from row (i, k constant)
                                for(int a = 0; a < 3; a++) {
                                    for(int b = 0; b < 3; b++) {
                                        if(a != j && b != l) {
                                            if(choiceArray[i][a][k][b].contains(solvedCell)) {
                                                choiceArray[i][a][k][b] = removeChoice(choiceArray[i][a][k][b], solvedCell);
                                                boardChanges = true;
                                            }
                                        }
                                    }
                                }

                                //Removing choice from column (j, l constant)
                                for(int a = 0; a < 3; a++) {
                                    for(int b = 0; b < 3; b++) {
                                        if(a != i && b != k) {
                                            if(choiceArray[a][j][b][l].contains(solvedCell)) {
                                                choiceArray[a][j][b][l] = removeChoice(choiceArray[a][j][b][l], solvedCell);
                                                boardChanges = true;
                                            }
                                        }
                                    }
                                }

                                //Removing choice from box (i, j constant)
                                for(int a = 0; a < 3; a++) {
                                    for(int b = 0; b < 3; b++) {
                                        if(a != i && b != j) {
                                            if(choiceArray[a][b][k][l].contains(solvedCell)) {
                                                choiceArray[a][b][k][l] = removeChoice(choiceArray[a][b][k][l], solvedCell);
                                                boardChanges = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if(!boardChanges) {
                break;
            }
        }

        System.out.println(choiceArray[0][0][0][0]);
        //expected: 467
        //actual:   23478
    }

    //Printing the current state of the sudoku
    public static void printBoard(String input) {
        String rowA = "╔═══╤═══╤═══╦═══╤═══╤═══╦═══╤═══╤═══╗";
        String rowB = "╟───┼───┼───╫───┼───┼───╫───┼───┼───╢";
        String rowC = "╠═══╪═══╪═══╬═══╪═══╪═══╬═══╪═══╪═══╣";
        String rowD = "╚═══╧═══╧═══╩═══╧═══╧═══╩═══╧═══╧═══╝";

        input = input.replaceAll("0", " ");

        System.out.println(rowA);
        for(int row = 0; row < 9; row++) {
            for(int box = 0; box < 3; box++) {
                System.out.print("║");
                for(int cell = 0; cell < 3; cell++) {
                    System.out.print(" " + input.charAt(9 * row + 3 * box + cell) + " ");
                    if(cell != 2) {
                        System.out.print("│");
                    }
                }
            }
            System.out.println("║");
            if(row % 3 == 2 && row != 8) {
                System.out.println(rowC);
            }
            else if(row != 8){
                System.out.println(rowB);
            }
            else {
                System.out.println(rowD);
            }
        }
    }

    //Print all possible choices in all cells in sudoku (good for debugging)
    public static void printAllChoices(String[][][][] choiceArray) {
        for(int i = 0; i < 3; i++) { //row of box
            for(int k = 0; k < 3; k++) { //row in box
                for(int j = 0; j < 3; j++) { //column of box
                    for(int l = 0; l < 3; l++) { //column in box
                        int cellNumber = 27 * i + 3 * j + 9 * k + l + 1;
                        System.out.println(cellNumber + ": " + choiceArray[i][j][k][l]);
                    }
                }
            }
        }
    }

    //Check if all cells only have one choice left
    public static boolean puzzleIsSolved(String[][][][] choiceArray) {
        for(int i = 0; i < 3; i++) {
            for(int j = 0; j < 3; j++) {
                for(int k = 0; k < 3; k++) {
                    for(int l = 0; l < 3; l++) {
                        if(choiceArray[i][j][k][l].length() > 1) {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }

    //Removing choice from cell
    public static String removeChoice(String initialChoices, String choiceToRemove) {
        String finalChoices = "";
        for(int i = 0; i < initialChoices.length(); i++) {
            if(initialChoices.charAt(i) != choiceToRemove.charAt(0)) {
                finalChoices += initialChoices.charAt(i);
            }
        }

        return finalChoices;
    }
}

0 个答案:

没有答案