A cool algorithm to check a Sudoku field?

前端 未结 25 744
清酒与你
清酒与你 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 09:53

    Create cell sets, where each set contains 9 cells, and create sets for vertical columns, horizontal rows, and 3x3 squares.

    Then for each cell, simply identify the sets it's part of and analyze those.

    0 讨论(0)
  • 2021-01-30 09:55

    It would be very interesting to check if:

    when the sum of each row/column/box equals n*(n+1)/2
    and the product equals n!
    with n = number of rows or columns
    

    this suffices the rules of a sudoku. Because that would allow for an algorithm of O(n^2), summing and multiplying the correct cells.

    Looking at n = 9, the sums should be 45, the products 362880.

    You would do something like:

    for i = 0 to n-1 do
      boxsum[i] := 0;
      colsum[i] := 0;
      rowsum[i] := 0;
      boxprod[i] := 1;
      colprod[i] := 1;
      rowprod[i] := 1;    
    end;
    
    for i = 0 to n-1 do
      for j = 0 to n-1 do
        box := (i div n^1/2) + (j div n^1/2)*n^1/2;
        boxsum[box] := boxsum[box] + cell[i,j];
        boxprod[box] := boxprod[box] * cell[i,j];
        colsum[i] := colsum[i] + cell[i,j];
        colprod[i] := colprod[i] * cell[i,j];
        rowsum[j] := colsum[j] + cell[i,j];
        rowprod[j] := colprod[j] * cell[i,j];
       end;
    end;
    
    for i = 0 to n-1 do
      if boxsum[i] <> 45
      or colsum[i] <> 45
      or rowsum[i] <> 45
      or boxprod[i] <> 362880
      or colprod[i] <> 362880
      or rowprod[i] <> 362880
       return false;
    
    0 讨论(0)
  • 2021-01-30 09:57

    Let's say int sudoku[0..8,0..8] is the sudoku field.

    bool CheckSudoku(int[,] sudoku)
    {
        int flag = 0;
    
    // Check rows
    for(int row = 0; row < 9; row++)
    {
        flag = 0;
        for (int col = 0; col < 9; col++)
        {
            // edited : check range step (see comments)
            if ((sudoku[row, col] < 1)||(sudoku[row, col] > 9)) 
            {
                return false;
            }
    
            // if n-th bit is set.. but you can use a bool array for readability
            if ((flag & (1 << sudoku[row, col])) != 0) 
            {
                return false;
            }
    
            // set the n-th bit
            flag |= (1 << sudoku[row, col]); 
        }
    }
    
    // Check columns
    for(int col= 0; col < 9; col++)
    {
        flag = 0;
        for (int row = 0; row < 9; row++)
        {
            if ((flag & (1 << sudoku[row, col])) != 0)
            {
                return false;
            }
            flag |= (1 << sudoku[row, col]);
        }
    }
    
    // Check 3x3 boxes
    for(int box= 0; box < 9; box++)
    {
        flag = 0;
        for (int ofs = 0; ofs < 9; ofs++)
        {
            int col = (box % 3) * 3;
            int row = ((int)(box / 3)) * 3;
    
            if ((flag & (1 << sudoku[row, col])) != 0)
            {
                return false;
            }
            flag |= (1 << sudoku[row, col]);
        }
    }
    return true;
    

    }

    0 讨论(0)
  • 2021-01-30 09:58

    Here is paper by math professor J.F. Crook: A Pencil-and-Paper Algorithm for Solving Sudoku Puzzles

    This paper was published in April 2009 and it got lots of publicity as definite Sudoku solution (check google for "J.F.Crook Sudoku" ).

    Besides algorithm, there is also a mathematical proof that algorithm works (professor admitted that he does not find Sudoku very interesting, so he threw some math in paper to make it more fun).

    0 讨论(0)
  • 2021-01-30 09:59
    def solution(board):
        for i in board:
            if sum(i) != 45:
                return "Incorrect"
    
        for i in range(9):
            temp2 = []
            for x in range(9):
                temp2.append(board[i][x])
    
            if sum(temp2) != 45:
                return "Incorrect"
    
        return "Correct"
    
    board = []
    for i in range(9):
        inp = raw_input()
        temp = [int(i) for i in inp]
        board.append(temp)
    
    print solution(board)
    
    
    0 讨论(0)
  • 2021-01-30 09:59

    You can check if sudoku is solved, in these two similar ways:

    • Check if the number is unique in each row, column and block.

    A naive solution would be to iterate trough every square and check if the number is unique in the row, column block that number occupies.

    But there is a better way.

    • Sudoku is solved if every row, column and block contains a permutation of the numbers (1 trough 9)

    This only requires to check every row, column and block, instead of doing that for every number. A simple implementation would be to have a bitfield of numbers 1 trough 9 and remove them when you iterate the columns, rows and blocks. If you try to remove a missing number or if the field isn't empty when you finish then sudoku isn't correctly solved.

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