美文网首页
数独终结者

数独终结者

作者: faithefeng | 来源:发表于2017-03-31 20:43 被阅读0次

这篇文章简单介绍下“数独求解器”怎么用程序实现??
文章背景图片是一个比较难的数独问题,感兴趣的可以试着手动求解啊。
这里暂时不多解释,直接贴代码,等有时间了详细解释下具体怎么实现的。代码使用python写的,总共大概一页纸。

import collections
def cross(A,B):
    "Cross product of elements in A and elements in B"
    return [a+b for a in A for b in B]

def parse_Grid(values):
    '''Convert grid to a dicf of values {square:digits}, 
    and a dict of possible values {square:digits}, 
    or return False if a contradiction is detected. That is, no possible value
    '''
    # Input is a string of with length of 81
    digits = '123456789'
    if not values:
        return False,False
    if isinstance(values, str):
        chars = [c for c in values if c in digits or c in '0.']
        values = dict(zip(squares, chars))
    elif isinstance(values, dict):
        values  = values
    values_Possible = dict((s,'') for s in squares)
    for s,d in values.items():
        if d in '0.':
            #Also, this line will implement the contradiction check!!!
            values_Possible[s] = ''.join(set(digits)-set(values[s2] for s2 in peers[s] if values[s2] in digits))
            if len(values_Possible[s]) == 0:
                return False,False

    return values, values_Possible

def display(values):
    "Display these values as a 2-D grid"
    digits = '123456789'
    if isinstance(values, str):
        chars = [c for c in values if c in digits or c in '0.']
        values = dict(zip(squares, chars))
    for s,d in values.items():
        if d in '0.':
            values[s] = ''
    width = 1+max(len(values[s]) for s in squares)
    line = '+'.join(['-'*(width*3)]*3)
    for r in rows:
        print(''.join(values[r+c].center(width) + ('|' if c in '36' else '') for c in cols))
        if r in 'CF':print(line)
    #return values

def solver(values):
    # This is the solver!!!
    values, values_Possible = parse_Grid(values)
    if not values_Possible:
        return False
    display(values)
    print('-'*30)
    if not all(len(d) == 0 for s,d in values_Possible.items()):
        n,s = min((len(d),s) for s,d in values_Possible.items() if len(d)!=0)
        print(n,s,values_Possible[s])
        return some(solver(assign(values.copy(),s, d)) for d in values_Possible[s]) # This is a generator!!!
    return values
def some (seq):
    if isinstance(seq, collections.Iterable):
        for e in seq:
            print(e)
            if e: 
                return e
    else:
        if seq:
            return seq
    return False
def assign(values, s, d):
    values[s] = d
    return values

# some constants
digits = '123456789'
cols = '123456789'
rows = 'ABCDEFGHI'
squares = cross(rows,cols)
unitlist = ([cross(a,cols) for a in rows] +
           [cross(rows,b) for b in cols] + 
           [cross(rb,cb) for rb in ('ABC','DEF','GHI') for cb in ('123','456','789')])
units = dict((s,[u for u in unitlist if s in u]) for s in squares)

peers = dict((s,set(sum(units[s],[]))-set([s])) for s in squares)

然后输入要求解的问题,

puzzle = '''005300000
            800000020
            070010500
            400005300
            010070006
            003200080
            060500009
            004000030
            000009700'''

求解

a = solver(values)

然后输出

display(a)

结果如下,搞定

相关文章

  • 数独终结者

    这篇文章简单介绍下“数独求解器”怎么用程序实现??文章背景图片是一个比较难的数独问题,感兴趣的可以试着手动求解啊。...

  • 数独数独

    想找人一起玩数独,你在哪?

  • 数独数独我爱你

    好久没玩数独了,昨天在图书馆借书时突发奇想查了有关数独的书,有好多!借了一本非常数独,回家就迫不及待地翻阅,哇塞,...

  • 数独

    一款拥有几十年历史的数字益智游戏,5种宫格,3种难度,适合各种水平,最接地气的数独游戏。 游戏特性: -- 每种难...

  • 数独

    现在,我每周天几乎都上的数独,直到上周天我全部学完了数独的六堂课。 在课上,我们学习了四宫格与六宫...

  • 数独

    学习目标 1、经历填数游戏活动,初步提高分析推理能力。 2、在探索、尝试、交流等活动中,体会填数游...

  • 数独

    这是一款集合了数独、方块、圈圈消消乐以及疯狂球球的合集游戏,画面精美,操作简单,经典数独与球球考验思维、方块与圈圈...

  • 数独

    全新数独游戏,无限个数独关卡,简单操作下的无穷乐趣! 玩好数独游戏首先要了解它的特点、要求,然后要运用一些原则和技...

  • 数独

    最近我参加了一个数独班,虽然我之前有学过一点点的基础,但是应该用什么规律来解,我并不是很清楚。而刚好通过...

  • 数独

    数独游戏是对智慧和毅力的考验。在这看似简单的小小一方九宫格上,用自己所有的想象力、逻辑推理和创新思维,去感悟游走在...

网友评论

      本文标题:数独终结者

      本文链接:https://www.haomeiwen.com/subject/omavottx.html