A cool algorithm to check a Sudoku field?

前端 未结 25 745
清酒与你
清酒与你 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:08

    Check each row, column and box such that it contains the numbers 1-9 each, with no duplicates. Most answers here already discuss this.

    But how to do that efficiently? Answer: Use a loop like

    result=0;
    for each entry:
      result |= 1<<(value-1)
    return (result==511);
    

    Each number will set one bit of the result. If all 9 numbers are unique, the lowest 9 bits will be set. So the "check for duplicates" test is just a check that all 9 bits are set, which is the same as testing result==511. You need to do 27 of these checks.. one for each row, column, and box.

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

    Here is mine in C. Only pass each square once.

    int checkSudoku(int board[]) {
      int i;
      int check[13] = { 0 };
    
      for (i = 0; i < 81; i++) {
        if (i % 9 == 0) {
          check[9] = 0;
          if (i % 27 == 0) {
            check[10] = 0;
            check[11] = 0;
            check[12] = 0;
          }
        }
    
        if (check[i % 9] & (1 << board[i])) {
          return 0;
        }
        check[i % 9] |= (1 << board[i]);
    
        if (check[9] & (1 << board[i])) {
          return 0;
        }
        check[9] |= (1 << board[i]);
    
        if (i % 9 < 3) {
          if (check[10] & (1 << board[i])) {
            return 0;
          }
          check[10] |= (1 << board[i]);
        } else if (i % 9 < 6) {
          if (check[11] & (1 << board[i])) {
            return 0;
          }
          check[11] |= (1 << board[i]);
        } else {
          if (check[12] & (1 << board[i])) {
            return 0;
          }
          check[12] |= (1 << board[i]);
        }
      }
    }
    
    0 讨论(0)
  • 2021-01-30 10:09

    One minor optimization you can make is that you can check for duplicates in a row, column, or box in O(n) time rather than O(n^2): as you iterate through the set of numbers, you add each one to a hashset. Depending on the language, you may actually be able to use a true hashset, which is constant time lookup and insertion; then checking for duplicates can be done in the same step by seeing if the insertion was successful or not. It's a minor improvement in the code, but going from O(n^2) to O(n) is a significant optimization.

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

    I'd write an interface that has functions that receive the sudoku field and returns true/false if it's a solution. Then implement the constraints as single validation classes per constraint.

    To verify just iterate through all constraint classes and when all pass the sudoku is correct. To speedup put the ones that most likely fail to the front and stop in the first result that points to invalid field.

    Pretty generic pattern. ;-)

    You can of course enhance this to provide hints which field is presumably wrong and so on.

    First constraint, just check if all fields are filled out. (Simple loop) Second check if all numbers are in each block (nested loops) Third check for complete rows and columns (almost same procedure as above but different access scheme)

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

    Peter Norvig has a great article on solving sudoku puzzles (with python),

    https://norvig.com/sudoku.html

    Maybe it's too much for what you want to do, but it's a great read anyway

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

    You could extract all values in a set (row, column, box) into a list, sort it, then compare to '(1, 2, 3, 4, 5, 6, 7, 8, 9)

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