【Codewars】Sudoku Solution Validator 实现数独验证器

原题描述Description:


Sudoku Background

Sudoku is a game played on a 9x9 grid. The goal of the game is to fill all cells of the grid with digits from 1 to 9, so that each column, each row, and each of the nine 3x3 sub-grids (also known as blocks) contain all of the digits from 1 to 9. 
(More info at: http://en.wikipedia.org/wiki/Sudoku)

Sudoku Solution Validator

Write a function validSolution that accepts a 2D array representing a Sudoku board, and returns true if it is a valid solution, or false otherwise. The cells of the sudoku board may also contain 0's, which will represent empty cells. Boards containing one or more zeroes are considered to be invalid solutions.

题意就是让同学们做一个数独验证器,能够检测输入的一个简单二位数组(board)是否是一个已经完成(没有0,0表示未完成的空格)且正确(符合数独规则,即横竖、9个小宫格里面都有且只有1-9)


这道题目从大方向上来说应该用验证性的方法,即有错就return False,排错到最后return True


下面是几种思路:

1.活用sorted()函数可以免去排序的麻烦

correct = [1, 2, 3, 4, 5, 6, 7, 8, 9]


def validSolution(board):
    # check rows
    for row in board:
        if sorted(row) != correct:
            return False
    
    # check columns
    for column in zip(*board):
        if sorted(column) != correct:
            return False
    
    # check regions
    for i in range(3):
        for j in range(3):
            region = []
            for line in board[i*3:(i+1)*3]:
                region += line[j*3:(j+1)*3]
            
            if sorted(region) != correct:
                return False
    
    # if everything correct
    return True

这里有个小技巧就是zip(*board),因为zip()这个内建函数对board进行并行遍历,从而纵向打包,其中*号是用于接收board内的子列表


2.def validSolution(board):
    for x in range(9):
        arr = [board[y][x] for y in range(9)]
        arr2 = [board[x][y] for y in range(9)]
        arr3 = [board[i][y] for y in range(((x%3)*3),(((x%3)*3)+3)) for i in range((int(x/3)*3),(int(x/3)*3)+3)]
        for i in range(9):
            if arr[i] in arr[(i+1):]: return False
            if arr2[i] in arr2[(i+1):]: return False
            if arr3[i] in arr3[(i+1):]: return False
        return True


依次检查第x行第x列,每3步长检测一个九宫格,arr[i:]表示从arr[i]后的所有字符,但是这个方法的效率可想而知不是最高的。


3.def validSolution(board):
    blocks = [[board[x+a][y+b] for a in (0, 1, 2) for b in (0, 1, 2)] for x in (0, 3, 6) for y in (0, 3, 6)]
    return not filter(lambda x: set(x) != set(range(1, 10)), board + zip(*board) + blocks)

其中set()函数提供去重的无序不重复序列,逻辑关系其实看起来很清晰就不一一解释了。再次验证了大神的写法和普通人的距离= _ =

你可能感兴趣的:(【Codewars】Sudoku Solution Validator 实现数独验证器)