python Python2中的Sudoku解算器,找不到原作者

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python Python2中的Sudoku解算器,找不到原作者相关的知识,希望对你有一定的参考价值。

#!/usr/bin/env python
#coding=utf-8
units = ([[j for j in range(81) if j%9 == i] for i in range(9)] +
        [[j for j in range(81) if j/9 == i] for i in range(9)] +
        [[j for j in range(81) if (j%9)/3+(j/27)*3 == i] for i in range(9)])
uindexs = [[j for j, u in enumerate(units) if i in u] for i in range(81)]


class Sudoku(object):

    conflict = False

    def set(self, gidx, value):
        try:
            self.known.add(gidx)
            self.grids[gidx] = set([value])
            for uidx in uindexs[gidx]:
                self.units[uidx].remove(value)
                self.changes.add(uidx)
        except KeyError:
            self.conflict = True

    def load(self, s):
        self.grids = [set(range(1, 10)) for i in range(81)]
        self.units = [set(range(1, 10)) for i in range(27)]
        self.known = set()
        self.changes = set()
        for gidx, c in enumerate(s):
            if c in '123456789':
                self.set(gidx, int(c))

    def detect(self):
        if self.conflict:
            return
        while self.changes:
            while self.changes:
                uidx = self.changes.pop()
                uset = self.units[uidx]
                for gidx in units[uidx]:
                    if gidx not in self.known:
                        gset = self.grids[gidx]
                        gset.intersection_update(uset)
                        length = len(gset)
                        if length == 0:
                            self.conflict = True
                            return
                        elif length == 1:
                            self.set(gidx, gset.pop())
            for uidx, uset in enumerate(self.units):
                map = dict((value, []) for value in uset)
                for gidx in units[uidx]:
                    for value in self.grids[gidx]:
                        if value in map:
                            map[value].append(gidx)
                for value, gidxs in map.iteritems():
                    length = len(gidxs)
                    if length == 1:
                        self.set(gidxs[0], value)
                    elif length == 0:
                        self.conflict = True
                        return

    def guess(self):
        count = 10
        gindex = -1
        for gidx, gset in enumerate(self.grids):
            if gidx not in self.known:
                if len(gset) < count:
                    gindex = gidx
                    count = len(gset)
                    if count == 2:
                        break
        gset = self.grids[gindex]
        for i in list(gset):
            sudoku = self.clone()
            sudoku.set(gindex, gset.pop())
            yield sudoku

    def solove(self):
        self.detect()
        if len(self.known) == 81:
            return self
        if self.conflict:
            return
        for sudoku in self.guess():
            sudoku = sudoku.solove()
            if sudoku is not None:
                return sudoku

    def clone(self):
        sudoku = Sudoku()
        sudoku.grids = [set(i) for i in self.grids]
        sudoku.units = [set(unit) for unit in self.units]
        sudoku.known = set(self.known)
        sudoku.changes = set()
        return sudoku

    def __str__(self):
        seq = ''.join(str(i)[5] for i in self.grids)
        return '\n'.join(seq[i:i+9] for i in range(0, 81, 9))
    __repr__ = __str__


def main():
    fen = '..............3.85..1.2.......5.7.....4...1...9.......5......73..2.1........4...9'
    sudoku = Sudoku()
    sudoku.load(fen)
    return sudoku.solove()

if __name__ == '__main__':
    import time
    t = time.time()
    for i in xrange(1000):
        main()
    print time.time() - t

以上是关于python Python2中的Sudoku解算器,找不到原作者的主要内容,如果未能解决你的问题,请参考以下文章

python 制作LP解算器

PROLOG中的填字游戏解算器

Python中的元组,字典计算器代码实例及python2与python3的区别

适用于MNIST的逻辑回归的最优解算器的选择

字谜解算器 C

用PYTHON2做个计算器,只要加减乘除