A cool algorithm to check a Sudoku field?

前端 未结 25 743
清酒与你
清酒与你 2021-01-30 09:19

Does anyone know a simple algorithm to check if a Sudoku-Configuration is valid? The simplest algorithm I came up with is (for a board of size n) in Pseudocode

f         


        
相关标签:
25条回答
  • 2021-01-30 10:00

    if the sum and the multiplication of a row/col equals to the right number 45/362880

    0 讨论(0)
  • 2021-01-30 10:00
    array = [1,2,3,4,5,6,7,8,9]  
    sudoku = int [][]
    puzzle = 9 #9x9
    columns = map []
    units = map [] # box    
    unit_l = 3 # box width/height
    check_puzzle()    
    
    
    def strike_numbers(line, line_num, columns, units, unit_l):
        count = 0
        for n in line:
            # check which unit we're in
            unit = ceil(n / unit_l) + ceil(line_num / unit_l) # this line is wrong - rushed
            if units[unit].contains(n): #is n in unit already?
                 return columns, units, 1
            units[unit].add(n)
            if columns[count].contains(n): #is n in column already?
                return columns, units, 1
            columns[count].add(n)
            line.remove(n) #remove num from temp row
        return columns, units, line.length # was a number not eliminated?
    
    def check_puzzle(columns, sudoku, puzzle, array, units):
        for (i=0;i< puzzle;i++):
            columns, units, left_over = strike_numbers(sudoku[i], i, columns, units) # iterate through rows
            if (left_over > 0): return false
    

    Without thoroughly checking, off the top of my head, this should work (with a bit of debugging) while only looping twice. O(n^2) instead of O(3(n^2))

    0 讨论(0)
  • 2021-01-30 10:01

    Here is what I just did for this:

    boolean checkers=true;
    String checking="";
        if(a.length/3==1){}
        else{
           for(int l=1; l<a.length/3; l++){
                for(int n=0;n<3*l;n++){
                    for(int lm=1; lm<a[n].length/3; lm++){
                        for(int m=0;m<3*l;m++){
                        System.out.print("    "+a[n][m]);
                        if(a[n][m]<=0){
                        System.out.print("        (Values must be positive!)        ");
                        }
                        if(n==0){
                            if(m!=0){
                            checking+=", "+a[n][m];
                        }
                        else{
                            checking+=a[n][m];
                        }
                    }
                    else{
                        checking+=", "+a[n][m];
                    }
                }
                        }
                System.out.print("        "+checking);
                System.out.println();
                    }
           }
                for (int i=1;i<=a.length*a[1].length;i++){
            if(checking.contains(Integer.toString(i))){
    
            }
            else{
                checkers=false;
            }
                }
            }
        checkers=checkCol(a);
        if(checking.contains("-")&&!checking.contains("--")){
            checkers=false;
        }
        System.out.println();
        if(checkers==true){
            System.out.println("This is correct! YAY!");
        }
        else{
            System.out.println("Sorry, it's not right. :-(");
        }
    }
    private static boolean checkCol(int[][]a){
        boolean checkers=true;
        int[][]col=new int[][]{{0,0,0},{0,0,0},{0,0,0}};
        for(int i=0; i<a.length; i++){
            for(int j=0; j<a[i].length; j++){
                if(a[i][j]>9||a[i][j]<1){
                    checkers=false;
                    break;
                }
                else{
                    col[a[i].length-j][i]=a[i][j];
                }
            }
        }
        String alia="";
        for(int i=0; i<col.length; i++){
            for(int j=1; j<=col[i].length; j++){
                alia=a[i].toString();
                if(alia.contains(""+j)){
                    alia=col[i].toString();
                    if(alia.contains(""+j)){}
                    else{
                        checkers=false;
                    }   
                }
                else{
                    checkers=false;
                }
            }
        }
        return checkers;
    }
    
    0 讨论(0)
  • 2021-01-30 10:02

    You need to check for all the constraints of Sudoku :

    • check the sum on each row
    • check the sum on each column
    • check for sum on each box
    • check for duplicate numbers on each row
    • check for duplicate numbers on each column
    • check for duplicate numbers on each box

    that's 6 checks altogether.. using a brute force approach.

    Some sort of mathematical optimization can be used if you know the size of the board (ie 3x3 or 9x9)

    Edit: explanation for the sum constraint: Checking for the sum first (and stoping if the sum is not 45) is much faster (and simpler) than checking for duplicates. It provides an easy way of discarding a wrong solution.

    0 讨论(0)
  • 2021-01-30 10:04

    Some time ago, I wrote a sudoku checker that checks for duplicate number on each row, duplicate number on each column & duplicate number on each box. I would love it if someone could come up one with like a few lines of Linq code though.

    char VerifySudoku(char grid[81])
    {
        for (char r = 0; r < 9; ++r)
        {
            unsigned int bigFlags = 0;
    
            for (char c = 0; c < 9; ++c)
            {
                unsigned short buffer = r/3*3+c/3;
    
                            // check horizontally
                bitFlags |= 1 << (27-grid[(r<<3)+r+c]) 
                            // check vertically
                         |  1 << (18-grid[(c<<3)+c+r])
                            // check subgrids
                         |  1 << (9-grid[(buffer<<3)+buffer+r%3*3+c%3]);
    
            }
    
            if (bitFlags != 0x7ffffff)
                return 0; // invalid
        }
    
        return 1; // valid
    }
    
    0 讨论(0)
  • 2021-01-30 10:07

    Create an array of booleans for every row, column, and square. The array's index represents the value that got placed into that row, column, or square. In other words, if you add a 5 to the second row, first column, you would set rows[2][5] to true, along with columns[1][5] and squares[4][5], to indicate that the row, column, and square now have a 5 value.

    Regardless of how your original board is being represented, this can be a simple and very fast way to check it for completeness and correctness. Simply take the numbers in the order that they appear on the board, and begin building this data structure. As you place numbers in the board, it becomes a O(1) operation to determine whether any values are being duplicated in a given row, column, or square. (You'll also want to check that each value is a legitimate number: if they give you a blank or a too-high number, you know that the board is not complete.) When you get to the end of the board, you'll know that all the values are correct, and there is no more checking required.

    Someone also pointed out that you can use any form of Set to do this. Arrays arranged in this manner are just a particularly lightweight and performant form of a Set that works well for a small, consecutive, fixed set of numbers. If you know the size of your board, you could also choose to do bit-masking, but that's probably a little overly tedious considering that efficiency isn't that big a deal to you.

    0 讨论(0)
提交回复
热议问题