python解数独

input_text = """
[
   [8,0,0,0,0,0,0,0,0],
   [0,0,3,6,0,0,0,0,0],
   [0,7,0,0,9,0,2,0,0],
   [0,5,0,0,0,7,0,0,0],
   [0,0,0,0,4,5,7,0,0],
   [0,0,0,1,0,0,0,3,0],
   [0,0,1,0,0,0,0,6,8],
   [0,0,8,5,0,0,0,1,0],
   [0,9,0,0,0,0,4,0,0]
]

"""

def copy(li):
    li_ = list(range(len(li)))
    for i in range(len(li)):
        li_[i] = list(range(len(li[i])))
    for x in range(len(li)):
        for y in range(len(li[x])):
            li_[x][y] = li[x][y]
    return li_

def insert(num, x, y, board, limit, level=9):
    board[x][y] = num
    bit = num_to_bit(num)
    # row limit
    for x_ in range(level):
        limit[x_][y] |= bit
    for y_ in range(level):
        limit[x][y_] |= bit
    leftTop_x = x // 3 * 3
    leftTop_y = y // 3 * 3
    for x_ in range(leftTop_x, leftTop_x + 3):
        for y_ in range(leftTop_y, leftTop_y + 3):
            limit[x_][y_] |= bit

def num_to_bit(num):
    return 1 << (num-1)

def conflict(ul):
    rs = False
    for x,y,post_list in ul:
        if len(post_list) == 0:
            rs = True
            break
    return rs

def list_potential(limit_factor, level=9):
    l = limit_factor
    result = []
    for i in range(1, level + 1):
        x = l & 1
        if not x:
            result.append(i)
        l = l >> 1
    return result

def fill(board, limit):
    bf,lf = copy(board),copy(limit)
    continue__ = False
    unknown_li = unknown_list(board,limit)
    for x, y,pos_list in unknown_li:
        if len(pos_list) == 1:
            insert(pos_list[0], x, y, bf, lf)
            continue__ = True
            break
    if continue__:
        fill(bf, lf)
    return bf,lf

def unknown_list(board,limit):
    rs = []
    for x in range(0, 9):
        for y in range(0, 9):
            if board[x][y] == 0:
                rs.append((x, y,list_potential(limit[x][y])))
    return sorted(rs,key=lambda i:len(i[-1]))
## 验证方法
def valid(board):
    def square(tlx,tly):
        return [board[a][b] for a in range(tlx,tlx+3) for b in range(tly,tly+3)]
    def valid__(li):
        for i in range(len(li)):
            for j in range(i+1,len(li)):
                if li[j] == li[i]:return False
        return True
    rs = True
    for r in board:
        rs = rs and valid__(r)
    for x in [[board[j][i] for i in range(9)] for j in range(9)]:
        rs = rs and valid__(x)
    xy = [(x,y)for x in range(0,7,3) for y in range(0,7,3)]
    for x,y in xy:
        rs = rs and valid__(square(x,y))
    return rs

def search(board,limit):
    rs = []
    done = False
    def search__(board,limit):
        nonlocal done
        nonlocal rs
        if done == True:
            return
        bf,lf = fill(board,limit)
        ul = unknown_list(bf,lf)
        if conflict(ul):
            return
        elif len(ul) == 0 :
            done = True
            rs = bf
            return
        else:
            x,y,pos_list = ul[0]
            for num in pos_list:
                bc__,lc__ = copy(bf),copy(lf)
                insert(num,x,y,bc__,lc__)
                search__(bc__,lc__)

    search__(board,limit)
    return rs
def output(input_text):
    b = eval(input_text)
    board = [
       [0 for x in range(9)]
            for y in range(9)
    ]

    l =[
        [0 for i in range(9)]for j in range(9)
    ]

    for i in range(len(b)):
        for j in range(len(b[i])):
            if b[i][j]:
                insert(b[i][j],i,j,board,l)

    rs = search(board,l)
    return rs
## 测试并验证
if __name__ == '__main__':
    o = output(input_text)
    print(o)
    print(valid(o))
posted @ 2016-07-17 22:19  Salaku  阅读(323)  评论(0编辑  收藏  举报