1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| __author__ = 'chen'
from pprint import pprint import numpy as np import itertools
def readClue(loc_file): with open(loc_file, 'rb') as handle: data = list(handle) data = filter(lambda l: l[0] != '#' and l.strip(), data) data.pop(0) data = [i.strip().split() for i in data] for i in range(len(data)): data[i] = [int(item) for item in data[i]] clues = {} clues['row'] = data[ : len(data) / 2 ] clues['col'] = data[len(data) / 2 :] return clues
def getClue(clues, idx): if idx % 2 == 0: return clues['col'][idx // 2] else: return clues['row'][(idx - 1) // 2]
def getMask(picMat, idx): if idx % 2 == 0: ret = picMat[:, idx // 2] else: ret = picMat[(idx - 1) //2, :] ret = [str(i) for i in ret] return ''.join(ret)
def candidate(picMat, clue, idx, LEN): freeNum = LEN - (sum(clue) + len(clue) - 1) if freeNum < 0: return -1 p = freeNum * ['0'] + len(clue) * ['#'] options = set(list(itertools.permutations(p, len(p)))) options = [''.join(i).split('#') for i in options] patterns = [] for op in options: patt = '' for i in range(len(clue)): patt += op[i] + '1'*clue[i] + '0' patt = patt[:-1] patt += op[-1] if check(idx, patt, picMat): patterns.append(patt) return patterns
def check(idx, patt, picMat): if idx % 2 == 0: idx = idx // 2 restrict = picMat[:idx, idx] else: idx = (idx - 1) // 2 restrict = picMat[idx, :idx+1] restrict = [str(i) for i in restrict] restrict = ''.join(restrict) return patt[:len(restrict)] == restrict
def resetMat(picMat, idx): if idx % 2 == 0: picMat[:, idx // 2] = 0 else: picMat[(idx - 1) // 2, :] = 0
def fillMat(picMat, idx, patt): patt = [int(i) for i in patt] if idx % 2 == 0: picMat[:, idx // 2] = patt else: picMat[(idx - 1) // 2, :] = patt
def solve(): LEN = 9 clues = readClue('data/warmup.txt') picMat = np.zeros((LEN, LEN), dtype=np.int8) patt_l = [] patt_l.append(candidate(picMat, getClue(clues, 0), 0, LEN)) while patt_l and len(patt_l) != 2*LEN: curIdx = len(patt_l) - 1 print curIdx if len(patt_l[curIdx]) <= 0: patt_l.pop(curIdx) continue else: patt = patt_l[curIdx].pop(0) fillMat(picMat, curIdx, patt) nextCandidates = candidate(picMat, getClue(clues, curIdx+1), curIdx+1, LEN) if nextCandidates != -1 and nextCandidates: patt_l.append(nextCandidates) return picMat
if __name__ == "__main__" : print(solve())
|