A cool algorithm to check a Sudoku field?

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

    Just a thought: don't you need to also check the numbers in each 3x3 square?

    I'm trying to figure out if it is possible to have the rows and columns conditions satisfied without having a correct sudoku

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

    I did this once for a class project. I used a total of 27 sets to represent each row, column and box. I'd check the numbers as I added them to each set (each placement of a number causes the number to be added to 3 sets, a row, a column, and a box) to make sure the user only entered the digits 1-9. The only way a set could get filled is if it was properly filled with unique digits. If all 27 sets got filled, the puzzle was solved. Setting up the mappings from the user interface to the 27 sets was a bit tedious, but made the rest of the logic a breeze to implement.

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

    First, you would need to make a boolean, "correct". Then, make a for loop, as previously stated. The code for the loop and everything afterwards (in java) is as stated, where field is a 2D array with equal sides, col is another one with the same dimensions, and l is a 1D one:

    for(int i=0; i<field.length(); i++){
        for(int j=0; j<field[i].length; j++){
            if(field[i][j]>9||field[i][j]<1){
                checking=false;
                break;
            }
            else{
                col[field[i].length()-j][i]=field[i][j];
            }
        }
    }
    

    I don't know the exact algorithim to check the 3x3 boxes, but you should check all the rows in field and col with "/*array name goes here*/[i].contains(1)&&/*array name goes here*/[i].contains(2)" (continues until you reach the length of a row) inside another for loop.

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

    This is my solution in Python, I'm glad to see it's the shortest one yet :)

    The code:

    def check(sud):
        zippedsud = zip(*sud)
    
        boxedsud=[]
        for li,line in enumerate(sud):
            for box in range(3):
                if not li % 3: boxedsud.append([])    # build a new box every 3 lines
                boxedsud[box + li/3*3].extend(line[box*3:box*3+3])
    
        for li in range(9):
            if [x for x in [set(sud[li]), set(zippedsud[li]), set(boxedsud[li])] if x != set(range(1,10))]:
                return False
        return True  
    

    And the execution:

    sudoku=[
    [7, 5, 1,  8, 4, 3,  9, 2, 6],
    [8, 9, 3,  6, 2, 5,  1, 7, 4], 
    [6, 4, 2,  1, 7, 9,  5, 8, 3],
    [4, 2, 5,  3, 1, 6,  7, 9, 8],
    [1, 7, 6,  9, 8, 2,  3, 4, 5],
    [9, 3, 8,  7, 5, 4,  6, 1, 2],
    [3, 6, 4,  2, 9, 7,  8, 5, 1],
    [2, 8, 9,  5, 3, 1,  4, 6, 7],
    [5, 1, 7,  4, 6, 8,  2, 3, 9]]
    
    print check(sudoku)        
    
    0 讨论(0)
  • 2021-01-30 09:51

    Here's a nice readable approach in Python:

    from itertools import chain                                                                                            
    
    def valid(puzzle):                                                                                                     
        def get_block(x,y):                                                                                                
            return chain(*[puzzle[i][3*x:3*x+3] for i in range(3*y, 3*y+3)])                                               
        rows = [set(row) for row in puzzle]                                                                                
        columns = [set(column) for column in zip(*puzzle)]                                                                 
        blocks = [set(get_block(x,y)) for x in range(0,3) for y in range(0,3)]                                             
        return all(map(lambda s: s == set([1,2,3,4,5,6,7,8,9]), rows + columns + blocks))         
    

    Each 3x3 square is referred to as a block, and there are 9 of them in a 3x3 grid. It is assumed as the puzzle is input as a list of list, with each inner list being a row.

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

    Let's assume that your board goes from 1 - n.

    We'll create a verification array, fill it and then verify it.

    grid [0-(n-1)][0-(n-1)]; //this is the input grid
    //each verification takes n^2 bits, so three verifications gives us 3n^2
    boolean VArray (3*n*n) //make sure this is initialized to false
    
    
    for i = 0 to n
     for j = 0 to n
      /*
       each coordinate consists of three parts
       row/col/box start pos, index offset, val offset 
      */
    
      //to validate rows
      VArray( (0)     + (j*n)                             + (grid[i][j]-1) ) = 1
      //to validate cols
      VArray( (n*n)   + (i*n)                             + (grid[i][j]-1) ) = 1
      //to validate boxes
      VArray( (2*n*n) + (3*(floor (i/3)*n)+ floor(j/3)*n) + (grid[i][j]-1) ) = 1
     next    
    next
    
    if every array value is true then the solution is correct. 
    

    I think that will do the trick, although i'm sure i made a couple of stupid mistakes in there. I might even have missed the boat entirely.

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