数独终结者

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

结果如下,搞定

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容