现在的位置: 首页 > 综合 > 正文

求解数独

2013年09月27日 ⁄ 综合 ⁄ 共 4019字 ⁄ 字号 评论关闭
 按照两个规则进行
#1 如果某个格X只能填入i,则X=i
#2 如果某个数字i只能填入格X,则X=i

后来发现只要#2就能够求出解了。
代码如下,接受一个包含81个数字的字符串,对应数独的81格,未知的格用0表示。
如果没有参数则自动生成一个测试用例。

  1. import sys
  2. import os
  3. import random
  4. from array import array
  5. testcase = "164973528257816943389452167471235896538649271692781435716524389845397612923168754"
  6. keeprate = float(35)
  7. def init_groups():
  8.     groups = [[] for i in range(27)]
  9.     for i in range(81):
  10.         x = i % 9
  11.         y = i / 9
  12.         groups[y].append(i)
  13.         groups[9 + x].append(i)
  14.         groups[18 + x / 3 + y - y % 3].append(i)
  15.     return tuple(tuple(l) for l in groups)
  16. def set_table(table, groups):
  17.     for group in groups:
  18.         num = set(table[i] for i in group if type(table[i]) == int)
  19.         for s in group:
  20.             if type(table[s]) == set:
  21.                 table[s] -= num
  22. def count_table(table):
  23.     return len([item for item in table if type(item) == int])
  24. def print_table(table):
  25.     str_tab = ["" for i in range(9)]
  26.     for y in range(9):
  27.         for x in range(9):
  28.             if x != 0 and x % 3 == 0:
  29.                 str_tab[y] += " "
  30.             if type(table[x + y * 9]) == int:
  31.                 str_tab[y] += "%d " % table[x + y * 9]
  32.             else:
  33.                 str_tab[y] += "%d'" % len(table[x + y * 9])
  34.     str_tab.insert(6, "")
  35.     str_tab.insert(3, "")
  36.     print "counter = %d" % count_table(table)
  37.     print "/n".join(str_tab)
  38.     print "-------------------"
  39. def set_value(table, groups, index, value):
  40.     table[index] = value
  41.     tmp = tuple(group for group in groups if index in group)
  42.     group = set()
  43.     for g in tmp:
  44.         group |= set(g)
  45.     for item in group:
  46.         if type(item) == set:
  47.             item.discard(value)  
  48. def sudoku(table):
  49.     for i in range(81):
  50.         if type(table[i]) == int and table[i] == 0:
  51.             table[i] = set(range(1,10))
  52.     groups = init_groups()
  53.     set_table(table, groups)
  54.     count = 0
  55.     stack = []
  56.     print_table(table)
  57.     while True:
  58.         if count_table(table) == 81:
  59.             break
  60.         
  61.         flag = True
  62. #        tmp = sorted(table, key = lambda x : 10 if type(x) == int else len(x))
  63. #        for i in tmp:
  64. #            if type(i) != set or len(i) != 1:
  65. #                break
  66. #            if len(i) == 0:
  67. #                table = stack.pop()
  68. #                print "pop stack"
  69. #            table[table.index(i)] = i.pop()
  70. #            set_table(table, groups)
  71. #            flag = False
  72. #            #set_value(table, groups, table.index(i), i.pop())
  73.         for group in groups:
  74.             num = set()
  75.             total = set()
  76.             for s in group:
  77.                 if type(table[s]) == set:
  78.                     num ^= table[s] - total
  79.                     total |= table[s] - num
  80.             for s in group:
  81.                 if type(table[s]) == set:
  82.                     temp = num & table[s]
  83.                     if len(temp) == 0:
  84.                         continue
  85.                     if len(temp) == 1:
  86.                         table[s] = temp.pop()
  87.                         set_table(table, groups)
  88.                         flag = False
  89.                     else:
  90.                         table = stack.pop()
  91.         
  92.         if flag:
  93.             tmp = sorted(table, key = lambda x : 10 if type(x) == int else len(x))
  94.             if len(tmp[0]) == 0:
  95.                 continue
  96.             v = tmp[0].pop()
  97.             newtable = table[:]
  98.             for i in range(len(newtable)):
  99.                 if type(newtable[i]) == set:
  100.                     newtable[i] = newtable[i].copy()
  101.             stack.append(newtable)
  102.             table[table.index(tmp[0])] = v
  103.             set_table(table, groups)
  104.         print_table(table)
  105.             
  106. if __name__ == "__main__":
  107.     if len(sys.argv) > 1:
  108.         if len(sys.argv[1]) == 81:
  109.             init = array("c", sys.argv[1])
  110.         else:
  111.             print "Argument error!"
  112.             sys.exit(-1)
  113.     else:
  114.         init = array("c", testcase)
  115.     if init.tostring() == testcase:
  116.         for i in range(len(init)):
  117.             if random.random() >= keeprate / 100:
  118.                 init[i] = "0"
  119.     table = [int(s) for s in init]
  120.     
  121.     #set_table()
  122.     #print_table(table)
  123.     sudoku(table)

抱歉!评论已关闭.