您的工作是用下列任何语言编写程序(或两个单独的程序):
注意:使用数独的规则对你有利,这就是这个挑战背后的想法。
维基百科上的数独规则
如果你有任何问题或关切,你可以要求澄清或在评论中提出建议。
得分=所有十个测试用例的字符数之和
最低分获胜。
你可以用这些来测试你的程序运行得有多好。
9 7 3 5 8 1 4 2 6
5 2 6 4 7 3 1 9 8
1 8 4 2 9 6 7 5 3
2 4 7 8 6 5 3 1 9
3 9 8 1 2 4 6 7 5
6 5 1 7 3 9 8 4 2
8 1 9 3 4 2 5 6 7
7 6 5 9 1 8 2 3 4
4 3 2 6 5 7 9 8 1
7 2 4 8 6 5 1 9 3
1 6 9 2 4 3 8 7 5
3 8 5 1 9 7 2 4 6
8 9 6 7 2 4 3 5 1
2 7 3 9 5 1 6 8 4
4 5 1 3 8 6 9 2 7
5 4 2 6 3 9 7 1 8
6 1 8 5 7 2 4 3 9
9 3 7 4 1 8 5 6 2
1 5 7 6 8 2 3 4 9
4 3 2 5 1 9 6 8 7
6 9 8 3 4 7 2 5 1
8 2 5 4 7 6 1 9 3
7 1 3 9 2 8 4 6 5
9 6 4 1 3 5 7 2 8
5 4 1 2 9 3 8 7 6
2 8 9 7 6 1 5 3 4
3 7 6 8 5 4 9 1 2
8 3 5 4 1 6 9 2 7
2 9 6 8 5 7 4 3 1
4 1 7 2 9 3 6 5 8
5 6 9 1 3 4 7 8 2
1 2 3 6 7 8 5 4 9
7 4 8 5 2 9 1 6 3
6 5 2 7 8 1 3 9 4
9 8 1 3 4 5 2 7 6
3 7 4 9 6 2 8 1 5
6 2 8 4 5 1 7 9 3
5 9 4 7 3 2 6 8 1
7 1 3 6 8 9 5 4 2
2 4 7 3 1 5 8 6 9
9 6 1 8 2 7 3 5 4
3 8 5 9 6 4 2 1 7
1 5 6 2 4 3 9 7 8
4 3 9 5 7 8 1 2 6
8 7 2 1 9 6 4 3 5
1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 1 4 3 6 5 8 9 7
3 6 5 8 9 7 2 1 4
8 9 7 2 1 4 3 6 5
5 3 1 6 4 8 9 7 2
6 4 8 9 7 2 5 3 1
9 7 2 5 3 1 6 4 8
1 4 5 7 9 2 8 3 6
3 7 6 5 8 4 1 9 2
2 9 8 3 6 1 7 5 4
7 3 1 9 2 8 6 4 5
8 5 9 6 4 7 3 2 1
4 6 2 1 3 5 9 8 7
6 2 4 8 7 3 5 1 9
5 8 7 4 1 9 2 6 3
9 1 3 2 5 6 4 7 8
5 2 7 4 1 6 9 3 8
8 6 4 3 2 9 1 5 7
1 3 9 5 7 8 6 4 2
2 9 1 8 5 4 3 7 6
3 4 8 6 9 7 5 2 1
6 7 5 1 3 2 4 8 9
7 1 2 9 4 5 8 6 3
4 8 3 2 6 1 7 9 5
9 5 6 7 8 3 2 1 4
2 4 6 7 1 3 9 8 5
1 8 5 4 9 6 7 3 2
9 3 7 8 2 5 1 4 6
6 7 8 5 4 2 3 9 1
4 9 3 1 6 8 2 5 7
5 1 2 3 7 9 4 6 8
8 2 4 9 5 7 6 1 3
7 5 9 6 3 1 8 2 4
3 6 1 2 8 4 5 7 9
8 6 1 2 9 4 5 7 3
4 7 5 3 1 8 6 9 2
3 9 2 5 6 7 8 1 4
2 3 6 4 5 9 7 8 1
1 5 4 7 8 3 2 6 9
9 8 7 6 2 1 3 4 5
5 2 9 1 7 6 4 3 8
6 4 8 9 3 2 1 5 7
7 1 3 8 4 5 9 2 6其中一些归功于http://www.opensky.ca/~jdhildeb/software/sudokugen/
如果您发现测试用例有任何问题,请告诉我。
发布于 2014-11-16 14:28:21
具有top+left约束的3x3平方的TL;DR蛮力计数
测试用例:
import itertools
inputs = """
9 7 3 5 8 1 4 2 6
5 2 6 4 7 3 1 9 8
1 8 4 2 9 6 7 5 3
2 4 7 8 6 5 3 1 9
3 9 8 1 2 4 6 7 5
6 5 1 7 3 9 8 4 2
8 1 9 3 4 2 5 6 7
7 6 5 9 1 8 2 3 4
4 3 2 6 5 7 9 8 1
7 2 4 8 6 5 1 9 3
1 6 9 2 4 3 8 7 5
3 8 5 1 9 7 2 4 6
8 9 6 7 2 4 3 5 1
2 7 3 9 5 1 6 8 4
4 5 1 3 8 6 9 2 7
5 4 2 6 3 9 7 1 8
6 1 8 5 7 2 4 3 9
9 3 7 4 1 8 5 6 2
1 5 7 6 8 2 3 4 9
4 3 2 5 1 9 6 8 7
6 9 8 3 4 7 2 5 1
8 2 5 4 7 6 1 9 3
7 1 3 9 2 8 4 6 5
9 6 4 1 3 5 7 2 8
5 4 1 2 9 3 8 7 6
2 8 9 7 6 1 5 3 4
3 7 6 8 5 4 9 1 2
8 3 5 4 1 6 9 2 7
2 9 6 8 5 7 4 3 1
4 1 7 2 9 3 6 5 8
5 6 9 1 3 4 7 8 2
1 2 3 6 7 8 5 4 9
7 4 8 5 2 9 1 6 3
6 5 2 7 8 1 3 9 4
9 8 1 3 4 5 2 7 6
3 7 4 9 6 2 8 1 5
6 2 8 4 5 1 7 9 3
5 9 4 7 3 2 6 8 1
7 1 3 6 8 9 5 4 2
2 4 7 3 1 5 8 6 9
9 6 1 8 2 7 3 5 4
3 8 5 9 6 4 2 1 7
1 5 6 2 4 3 9 7 8
4 3 9 5 7 8 1 2 6
8 7 2 1 9 6 4 3 5
1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 1 4 3 6 5 8 9 7
3 6 5 8 9 7 2 1 4
8 9 7 2 1 4 3 6 5
5 3 1 6 4 8 9 7 2
6 4 8 9 7 2 5 3 1
9 7 2 5 3 1 6 4 8
1 4 5 7 9 2 8 3 6
3 7 6 5 8 4 1 9 2
2 9 8 3 6 1 7 5 4
7 3 1 9 2 8 6 4 5
8 5 9 6 4 7 3 2 1
4 6 2 1 3 5 9 8 7
6 2 4 8 7 3 5 1 9
5 8 7 4 1 9 2 6 3
9 1 3 2 5 6 4 7 8
5 2 7 4 1 6 9 3 8
8 6 4 3 2 9 1 5 7
1 3 9 5 7 8 6 4 2
2 9 1 8 5 4 3 7 6
3 4 8 6 9 7 5 2 1
6 7 5 1 3 2 4 8 9
7 1 2 9 4 5 8 6 3
4 8 3 2 6 1 7 9 5
9 5 6 7 8 3 2 1 4
2 4 6 7 1 3 9 8 5
1 8 5 4 9 6 7 3 2
9 3 7 8 2 5 1 4 6
6 7 8 5 4 2 3 9 1
4 9 3 1 6 8 2 5 7
5 1 2 3 7 9 4 6 8
8 2 4 9 5 7 6 1 3
7 5 9 6 3 1 8 2 4
3 6 1 2 8 4 5 7 9
8 6 1 2 9 4 5 7 3
4 7 5 3 1 8 6 9 2
3 9 2 5 6 7 8 1 4
2 3 6 4 5 9 7 8 1
1 5 4 7 8 3 2 6 9
9 8 7 6 2 1 3 4 5
5 2 9 1 7 6 4 3 8
6 4 8 9 3 2 1 5 7
7 1 3 8 4 5 9 2 6
""".strip().split('\n\n')辅助函数打印sudoku
def print_sudoku(m):
for k in m:
print' '.join(str(i) for i in k)生成给定上述和左约束的所有可能的平方。
有关详细信息,请参阅代码注释。
def potential_squares(u1, u2, u3, l1, l2, l3):
"""
returns generator of possible squares given lists of digits above and below
u1 u2 u3
| | |
l1 -- a b c
l2 -- d e f
l3 -- g h i
if no items exist the empty list must be given
"""
for a, b, c, d, e, f, g, h, i in itertools.permutations(xrange(1, 10)):
if a not in u1 and a not in l1 and b not in u2 and b not in l1 and c not in u3 and c not in l1 and d not in u1 and d not in l2 and e not in u2 and e not in l2 and f not in u3 and f not in l2 and g not in u1 and g not in l3 and h not in u2 and h not in l3 and i not in u3 and i not in l3:
yield (a, b, c, d, e, f, g, h, i)从sudoku板中提取所有正方形作为元组
有关详细信息,请参阅代码注释。
def board_to_squares(board):
"""
finds 9 squares in a 9x9 board in this order:
1 1 1 2 2 2 3 3 3
1 1 1 2 2 2 3 3 3
1 1 1 2 2 2 3 3 3
4 4 4 5 5 5 6 6 6
4 4 4 5 5 5 6 6 6
4 4 4 5 5 5 6 6 6
7 7 7 8 8 8 9 9 9
7 7 7 8 8 8 9 9 9
7 7 7 8 8 8 9 9 9
returns tuple for each square as follows:
a b c
d e f --> (a,b,c,d,e,f,g,h,i)
g h i
"""
labels = [[3 * i + 1] * 3 + [3 * i + 2] * 3 + [3 * i + 3] * 3 for i in [0, 0, 0, 1, 1, 1, 2, 2, 2]]
labelled_board = zip(sum(board, []), sum(labels, []))
return [tuple(a for a, b in labelled_board if b == sq) for sq in xrange(1, 10)]将正方形转换为sudoku板
基本上是上述函数的逆函数。
def squares_to_board(squares):
"""
inverse of above
"""
board = [[i / 3 * 27 + i % 3 * 3 + j / 3 * 9 + j % 3 for j in range(9)] for i in range(9)]
flattened = sum([list(square) for square in squares], [])
for i in range(9):
for j in range(9):
board[i][j] = flattened[board[i][j]]
return board给定左平方,返回约束
有关详细信息,请参阅代码注释。
def sum_rows(*squares):
"""
takes tuples for squares and returns lists corresponding to the rows:
l1 -- a b c j k l
l2 -- d e f m n o ...
l3 -- g h i p q r
"""
l1 = []
l2 = []
l3 = []
if len(squares):
for a, b, c, d, e, f, g, h, i in squares:
l1 += [a, b, c]
l2 += [d, e, f]
l3 += [g, h, i]
return l1, l2, l3
return [], [], []给定上面的平方,返回约束
有关详细信息,请参阅代码注释。
def sum_cols(*squares):
"""
takes tuples for squares and returns lists corresponding to the cols:
u1 u2 u3
| | |
a b c
d e f
g h i
j k l
m n o
p q r
...
"""
u1 = []
u2 = []
u3 = []
if len(squares):
for a, b, c, d, e, f, g, h, i in squares:
u1 += [a, d, g]
u2 += [b, e, h]
u3 += [c, f, i]
return u1, u2, u3
return [], [], []制造一条线
def base95(A):
if type(A) is int or type(A) is long:
s = ''
while A > 0:
s += chr(32 + A % 95)
A /= 95
return s
if type(A) is str:
return sum((ord(c) - 32) * (95 ** i) for i, c in enumerate(A))这是每个平方的依赖项的硬编码列表。
有关详细信息,请参阅代码注释。
"""
dependencies: every square as labeled
1 2 3
4 5 6
7 8 9
is dependent on those above and to the left
in a dictionary, it is:
square: ([above],[left])
"""
dependencies = {1: ([], []), 2: ([], [1]), 3: ([], [1, 2]), 4: ([1], []), 5: ([2], [4]), 6: ([3], [4, 5]),
7: ([1, 4], []), 8: ([2, 5], [7]), 9: ([3, 6], [7, 8])}这是一个硬编码列表,列出了每个平方的最大可能选项数。
有关详细信息,请参阅代码注释。
"""
max possible options for a given element
9 8 7 ? ? ? 3 2 1
6 5 4 (12096) 3 2 1
3 2 1 ? ? ? 3 2 1
? ? ? ? ? ? 2 2 1
(12096) (448) 2 1 1 (limits for squares 2,4 determined via brute-force enumeration)
? ? ? ? ? ? 1 1 1 (limit for square 5 determined via sampling and enumeration)
3 3 3 2 2 1 1 1 1
2 2 2 2 1 1 1 1 1
1 1 1 1 1 1 1 1 1
"""
possibilities = [362880, 12096, 216, 12096, 448, 8, 216, 8, 1]它们将上述功能结合起来,并将板转换为整数列表。
def factorize_sudoku(board):
squares = board_to_squares(board)
factors = []
for label in xrange(1, 10):
above, left = dependencies[label]
u1, u2, u3 = sum_cols(*[sq for i, sq in enumerate(squares) if i + 1 in above])
l1, l2, l3 = sum_rows(*[sq for i, sq in enumerate(squares) if i + 1 in left])
for i, k in enumerate(potential_squares(u1, u2, u3, l1, l2, l3)):
if k == squares[label - 1]:
factors.append(i)
continue
return factors回到董事会
def unfactorize_sudoku(factors):
squares = []
for label in xrange(1, 10):
factor = factors[label - 1]
above, left = dependencies[label]
u1, u2, u3 = sum_cols(*[sq for i, sq in enumerate(squares) if i + 1 in above])
l1, l2, l3 = sum_rows(*[sq for i, sq in enumerate(squares) if i + 1 in left])
for i, k in enumerate(potential_squares(u1, u2, u3, l1, l2, l3)):
if i == factor:
squares.append(k)
continue
return squares好的,这是所有的功能
对于每个板,制作字符串并打印出来。
strings = []
for sudoku in inputs:
board = [[int(x) for x in line.split()] for line in sudoku.strip().split('\n')]
print_sudoku(board)
factors = factorize_sudoku(board)
i = 0
for item, modulus in zip(factors, possibilities):
i *= modulus
i += item
strings.append(base95(i))
print 'integral representation:', i
print 'bits of entropy:', i.bit_length()
print 'base95 representation:', strings[-1]
print ''现在打印所有字符串的总长度。
print 'overall output:', strings
print 'total length:', len(''.join(strings))
print ''不紧张,为了证明这不是单向压缩
for string in strings:
print 'from:', string
i = base95(string)
retrieved = []
for base in possibilities[::-1]:
retrieved.append(i % base)
i /= base
squares = unfactorize_sudoku(retrieved[::-1])
print_sudoku(squares_to_board(squares))
print ''产出:
9 7 3 5 8 1 4 2 6
5 2 6 4 7 3 1 9 8
1 8 4 2 9 6 7 5 3
2 4 7 8 6 5 3 1 9
3 9 8 1 2 4 6 7 5
6 5 1 7 3 9 8 4 2
8 1 9 3 4 2 5 6 7
7 6 5 9 1 8 2 3 4
4 3 2 6 5 7 9 8 1
integral representation: 69411889624053450486136
bits of entropy: 76
base95 representation: q`3T/v50 =3,
7 2 4 8 6 5 1 9 3
1 6 9 2 4 3 8 7 5
3 8 5 1 9 7 2 4 6
8 9 6 7 2 4 3 5 1
2 7 3 9 5 1 6 8 4
4 5 1 3 8 6 9 2 7
5 4 2 6 3 9 7 1 8
6 1 8 5 7 2 4 3 9
9 3 7 4 1 8 5 6 2
integral representation: 48631663773869605020107
bits of entropy: 76
base95 representation: ^0NK(F4(V6T(
1 5 7 6 8 2 3 4 9
4 3 2 5 1 9 6 8 7
6 9 8 3 4 7 2 5 1
8 2 5 4 7 6 1 9 3
7 1 3 9 2 8 4 6 5
9 6 4 1 3 5 7 2 8
5 4 1 2 9 3 8 7 6
2 8 9 7 6 1 5 3 4
3 7 6 8 5 4 9 1 2
integral representation: 3575058942398222501018
bits of entropy: 72
base95 representation: d KTTB{pJc[
8 3 5 4 1 6 9 2 7
2 9 6 8 5 7 4 3 1
4 1 7 2 9 3 6 5 8
5 6 9 1 3 4 7 8 2
1 2 3 6 7 8 5 4 9
7 4 8 5 2 9 1 6 3
6 5 2 7 8 1 3 9 4
9 8 1 3 4 5 2 7 6
3 7 4 9 6 2 8 1 5
integral representation: 57682547793421214045879
bits of entropy: 76
base95 representation: B]^v[omnBF-*
6 2 8 4 5 1 7 9 3
5 9 4 7 3 2 6 8 1
7 1 3 6 8 9 5 4 2
2 4 7 3 1 5 8 6 9
9 6 1 8 2 7 3 5 4
3 8 5 9 6 4 2 1 7
1 5 6 2 4 3 9 7 8
4 3 9 5 7 8 1 2 6
8 7 2 1 9 6 4 3 5
integral representation: 41241947159502331128265
bits of entropy: 76
base95 representation: WZslDPbcOm7'
1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 1 4 3 6 5 8 9 7
3 6 5 8 9 7 2 1 4
8 9 7 2 1 4 3 6 5
5 3 1 6 4 8 9 7 2
6 4 8 9 7 2 5 3 1
9 7 2 5 3 1 6 4 8
integral representation: 9
bits of entropy: 4
base95 representation: )
1 4 5 7 9 2 8 3 6
3 7 6 5 8 4 1 9 2
2 9 8 3 6 1 7 5 4
7 3 1 9 2 8 6 4 5
8 5 9 6 4 7 3 2 1
4 6 2 1 3 5 9 8 7
6 2 4 8 7 3 5 1 9
5 8 7 4 1 9 2 6 3
9 1 3 2 5 6 4 7 8
integral representation: 2289142964266107350685
bits of entropy: 71
base95 representation: ukVl2x/[+6F
5 2 7 4 1 6 9 3 8
8 6 4 3 2 9 1 5 7
1 3 9 5 7 8 6 4 2
2 9 1 8 5 4 3 7 6
3 4 8 6 9 7 5 2 1
6 7 5 1 3 2 4 8 9
7 1 2 9 4 5 8 6 3
4 8 3 2 6 1 7 9 5
9 5 6 7 8 3 2 1 4
integral representation: 33227336099857838436306
bits of entropy: 75
base95 representation: qzw>GjmPxzo%
2 4 6 7 1 3 9 8 5
1 8 5 4 9 6 7 3 2
9 3 7 8 2 5 1 4 6
6 7 8 5 4 2 3 9 1
4 9 3 1 6 8 2 5 7
5 1 2 3 7 9 4 6 8
8 2 4 9 5 7 6 1 3
7 5 9 6 3 1 8 2 4
3 6 1 2 8 4 5 7 9
integral representation: 10303519193492123417583
bits of entropy: 74
base95 representation: KE:*GH@H>(m!
8 6 1 2 9 4 5 7 3
4 7 5 3 1 8 6 9 2
3 9 2 5 6 7 8 1 4
2 3 6 4 5 9 7 8 1
1 5 4 7 8 3 2 6 9
9 8 7 6 2 1 3 4 5
5 2 9 1 7 6 4 3 8
6 4 8 9 3 2 1 5 7
7 1 3 8 4 5 9 2 6
integral representation: 60238104668684129814106
bits of entropy: 76
base95 representation: SeM=kA`'3(X*
overall output: ['q`3T/v50 =3,', '^0NK(F4(V6T(', 'd KTTB{pJc[', 'B]^v[omnBF-*', "WZslDPbcOm7'", ')', 'ukVl2x/[+6F', 'qzw>GjmPxzo%', 'KE:*GH@H>(m!', "SeM=kA`'3(X*"]
total length: 107
from: q`3T/v50 =3,
9 7 3 5 8 1 4 2 6
5 2 6 4 7 3 1 9 8
1 8 4 2 9 6 7 5 3
2 4 7 8 6 5 3 1 9
3 9 8 1 2 4 6 7 5
6 5 1 7 3 9 8 4 2
8 1 9 3 4 2 5 6 7
7 6 5 9 1 8 2 3 4
4 3 2 6 5 7 9 8 1
from: ^0NK(F4(V6T(
7 2 4 8 6 5 1 9 3
1 6 9 2 4 3 8 7 5
3 8 5 1 9 7 2 4 6
8 9 6 7 2 4 3 5 1
2 7 3 9 5 1 6 8 4
4 5 1 3 8 6 9 2 7
5 4 2 6 3 9 7 1 8
6 1 8 5 7 2 4 3 9
9 3 7 4 1 8 5 6 2
from: d KTTB{pJc[
1 5 7 6 8 2 3 4 9
4 3 2 5 1 9 6 8 7
6 9 8 3 4 7 2 5 1
8 2 5 4 7 6 1 9 3
7 1 3 9 2 8 4 6 5
9 6 4 1 3 5 7 2 8
5 4 1 2 9 3 8 7 6
2 8 9 7 6 1 5 3 4
3 7 6 8 5 4 9 1 2
from: B]^v[omnBF-*
8 3 5 4 1 6 9 2 7
2 9 6 8 5 7 4 3 1
4 1 7 2 9 3 6 5 8
5 6 9 1 3 4 7 8 2
1 2 3 6 7 8 5 4 9
7 4 8 5 2 9 1 6 3
6 5 2 7 8 1 3 9 4
9 8 1 3 4 5 2 7 6
3 7 4 9 6 2 8 1 5
from: WZslDPbcOm7'
6 2 8 4 5 1 7 9 3
5 9 4 7 3 2 6 8 1
7 1 3 6 8 9 5 4 2
2 4 7 3 1 5 8 6 9
9 6 1 8 2 7 3 5 4
3 8 5 9 6 4 2 1 7
1 5 6 2 4 3 9 7 8
4 3 9 5 7 8 1 2 6
8 7 2 1 9 6 4 3 5
from: )
1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 1 4 3 6 5 8 9 7
3 6 5 8 9 7 2 1 4
8 9 7 2 1 4 3 6 5
5 3 1 6 4 8 9 7 2
6 4 8 9 7 2 5 3 1
9 7 2 5 3 1 6 4 8
from: ukVl2x/[+6F
1 4 5 7 9 2 8 3 6
3 7 6 5 8 4 1 9 2
2 9 8 3 6 1 7 5 4
7 3 1 9 2 8 6 4 5
8 5 9 6 4 7 3 2 1
4 6 2 1 3 5 9 8 7
6 2 4 8 7 3 5 1 9
5 8 7 4 1 9 2 6 3
9 1 3 2 5 6 4 7 8
from: qzw>GjmPxzo%
5 2 7 4 1 6 9 3 8
8 6 4 3 2 9 1 5 7
1 3 9 5 7 8 6 4 2
2 9 1 8 5 4 3 7 6
3 4 8 6 9 7 5 2 1
6 7 5 1 3 2 4 8 9
7 1 2 9 4 5 8 6 3
4 8 3 2 6 1 7 9 5
9 5 6 7 8 3 2 1 4
from: KE:*GH@H>(m!
2 4 6 7 1 3 9 8 5
1 8 5 4 9 6 7 3 2
9 3 7 8 2 5 1 4 6
6 7 8 5 4 2 3 9 1
4 9 3 1 6 8 2 5 7
5 1 2 3 7 9 4 6 8
8 2 4 9 5 7 6 1 3
7 5 9 6 3 1 8 2 4
3 6 1 2 8 4 5 7 9
from: SeM=kA`'3(X*
8 6 1 2 9 4 5 7 3
4 7 5 3 1 8 6 9 2
3 9 2 5 6 7 8 1 4
2 3 6 4 5 9 7 8 1
1 5 4 7 8 3 2 6 9
9 8 7 6 2 1 3 4 5
5 2 9 1 7 6 4 3 8
6 4 8 9 3 2 1 5 7
7 1 3 8 4 5 9 2 6发布于 2014-11-15 18:18:02
代码:
emptysud=[[' ']*9 for l in range(9)]
def encconfig(dig,sud):
conf1=[(sud[i].index(dig),i) for i in range(9)]; out=[]
for xgroup in range(3):
a=filter(lambda (x,y): xgroup*3<=x<(xgroup+1)*3, conf1)
b=[x-xgroup*3 for (x,y) in sorted(a,key = lambda (x,y): y)]
out.append([[0,1,2],[0,2,1],[1,0,2],[1,2,0],[2,0,1],[2,1,0]].index(b))
for ygroup in range(3):
a=filter(lambda (x,y): ygroup*3<=y<(ygroup+1)*3, conf1)
b=[y-ygroup*3 for (x,y) in sorted(a,key = lambda (x,y): x)]
out.append([[0,1,2],[0,2,1],[1,0,2],[1,2,0],[2,0,1],[2,1,0]].index(b))
return sum([out[i]*(6**i) for i in range(6)])
def decconfig(conf,dig,sud=emptysud):
inp=[]; conf1=[]; sud=[line[:] for line in sud]
for i in range(6):
inp.append([[0,1,2],[0,2,1],[1,0,2],[1,2,0],[2,0,1],[2,1,0]][conf%6]); conf/=6
for groupx in range(3):
for groupy in range(3):
conf1.append((groupx*3+inp[groupx][groupy],groupy*3+inp[groupy+3][groupx]))
for (x,y) in conf1: sud[y][x]=dig
return sud
def compatible(sud,conf,dig):
a=reduce(lambda x,y: x+y, sud)
b=decconfig(conf,dig,sud)
c=reduce(lambda x,y: x+y, b)
return a.count(' ')-c.count(' ')==9
def encode(sud):
k=[encconfig(str(i),sud) for i in range(1,10)]; m=k[0]; p=6**6
cursud=decconfig(k[0],'1')
for i in range(1,9):
t=filter(lambda u: compatible(cursud,u,str(i+1)), range(6**6))
m=m+p*t.index(k[i]); p*=len(t)
cursud=decconfig(k[i],str(i+1),cursud)
return m
def decode(n):
k=[n%46656]; n/=46656; cursud=decconfig(k[-1],'1')
for i in range(2,10):
t=filter(lambda u: compatible(cursud,u,str(i)), range(6**6))
k.append(n%len(t)); n/=len(t); cursud=decconfig(t[k[-1]],str(i),cursud)
return cursud
def base95(n):
out=''
while n: out+=chr(32+n%95); n/=95
return out[::-1]
def base10(s): s=s[::-1]; return sum([(ord(s[i])-32)*(95**i) for i in range(len(s))])
import time
t0=time.clock()
for part in file('sudoku.txt','rb+').read().split('\r\n\r\n'):
sudoku=[line.split(' ') for line in part.split('\r\n')]
encsud=base95(encode(sudoku)); sud2=decode(base10(encsud))
print encsud,sud2==sudoku
print time.clock()-t0结果:
!|/FC,">;&3z
rUH">FLSgT|
)3#m|:&Zxl1c
jh _N@MG/zr
%Iye;U(6(p;0
!21.+KD0//yG
"O\B*O@8,h`y
APython2.5,116个点代码:emptysud=[[' ']*9 for l in range(9)]
def encconfig(dig,sud):
conf1=[(sud[i].index(dig),i) for i in range(9)]; out=[]
for xgroup in range(3):
a=filter(lambda (x,y): xgroup*3<=x<(xgroup+1)*3, conf1)
b=[x-xgroup*3 for (x,y) in sorted(a,key = lambda (x,y): y)]
out.append([[0,1,2],[0,2,1],[1,0,2],[1,2,0],[2,0,1],[2,1,0]].index(b))
for ygroup in range(3):
a=filter(lambda (x,y): ygroup*3<=y<(ygroup+1)*3, conf1)
b=[y-ygroup*3 for (x,y) in sorted(a,key = lambda (x,y): x)]
out.append([[0,1,2],[0,2,1],[1,0,2],[1,2,0],[2,0,1],[2,1,0]].index(b))
return sum([out[i]*(6**i) for i in range(6)])
def decconfig(conf,dig,sud=emptysud):
inp=[]; conf1=[]; sud=[line[:] for line in sud]
for i in range(6):
inp.append([[0,1,2],[0,2,1],[1,0,2],[1,2,0],[2,0,1],[2,1,0]][conf%6]); conf/=6
for groupx in range(3):
for groupy in range(3):
conf1.append((groupx*3+inp[groupx][groupy],groupy*3+inp[groupy+3][groupx]))
for (x,y) in conf1: sud[y][x]=dig
return sud
def compatible(sud,conf,dig):
a=reduce(lambda x,y: x+y, sud)
b=decconfig(conf,dig,sud)
c=reduce(lambda x,y: x+y, b)
return a.count(' ')-c.count(' ')==9
def encode(sud):
k=[encconfig(str(i),sud) for i in range(1,10)]; m=k[0]; p=6**6
cursud=decconfig(k[0],'1')
for i in range(1,9):
t=filter(lambda u: compatible(cursud,u,str(i+1)), range(6**6))
m=m+p*t.index(k[i]); p*=len(t)
cursud=decconfig(k[i],str(i+1),cursud)
return m
def decode(n):
k=[n%46656]; n/=46656; cursud=decconfig(k[-1],'1')
for i in range(2,10):
t=filter(lambda u: compatible(cursud,u,str(i)), range(6**6))
k.append(n%len(t)); n/=len(t); cursud=decconfig(t[k[-1]],str(i),cursud)
return cursud
def base95(n):
out=''
while n: out+=chr(32+n%95); n/=95
return out[::-1]
def base10(s): s=s[::-1]; return sum([(ord(s[i])-32)*(95**i) for i in range(len(s))])
import time
t0=time.clock()
for part in file('sudoku.txt','rb+').read().split('\r\n\r\n'):
sudoku=[line.split(' ') for line in part.split('\r\n')]
encsud=base95(encode(sudoku)); sud2=decode(base10(encsud))
print encsud,sud2==sudoku
print time.clock()-t0结果:TUE#rsQu
J}ANCYXX*y5
".u2KV#4K|%a非常慢。在我的机器上运行和验证花了517秒。
encconfig采用sudoku板和1-9中的一个数字,列出该数字出现的x-y坐标,并输出一个表示这些坐标的范围(6**6)的数字。(“数字配置”)
decconfig是相反的函数。它需要一个范围内的数字(6**6)、一个数字和一个sudoku板(默认为空)。它输出与数字配置叠加的sudoku板。如果数字配置中的一个位置已经在输入的sudoku板中占据,则该位置中的数字将被新数字覆盖。
兼容采用sudoku板和数字配置(由conf和dig定义),在sudoku板上覆盖数字配置并检查冲突。然后根据结果返回True或False。
编码是压缩函数。它需要一个sudoku板并输出一个代表它的数字。为了做到这一点,它首先将1's的位置复制到一个空板上,然后列出与1-配置兼容的数字2的所有配置(这些配置不会占用1‘S已经占据的任何位置)。然后,它在列表中找到董事会实际2-配置的顺序,并将其存储起来,然后将该配置复制到新的板上,新董事会现在只包含1's和2's,然后列出所有与1‘0和2’的位置兼容的数字3的配置,等等。
解码是相反的功能。
Python 2.5
发布于 2014-11-16 17:24:37
KYxnUjIpNe/YDnA
F97LclGuqeTcT2c
i6D1SvMVkS0jPlQ
32FOiIoUHpz5GGs
aAazPo2RJiH+IWQ
CwAA5NIMyNzSt1I
Cc2jOjU1+buCtVM
OgQv3Dz3PqsRvGA
eSxaW3wY5e6NGFc
olQvtpDOUPJXKGw它生成123456789的所有可能排列并记住它们。然后将排列与sudoku中的行进行比较。当为给定行找到匹配的排列时,它会记住该排列的索引。在每一行之后,它将删除至少有一个字符位于与当前行相同位置的所有排列。这确保了每个数字在其列中都是唯一的。然后,它取出所有的排列不再工作的盒子-标准。因为最后一行是琐碎的,所以它会生成8个数字。我测试了每个数字的最大值是什么,并为这些数字的每个位置生成了一个数字计数掩码。{ 6,5,3,5,3,1,2,1,1 }第一种明显是最长的,有362880个排列。使用数字掩码,我构造了一个带前导1的BigInteger,使其长28位。这将导致总计11个字节。然后将这些字节转换为base64。为了保存一个字符,我移除结尾处的=符号。
重新构造的工作原理类似。
它从BigInteger中重新构造base64string,然后再将其转换为字符串,然后使用into数字计数掩码再次将其拆分。这些字符串被解析回索引。
然后算法做的几乎一样,不是在排列中找到行--它只是使用索引来获取行--其余的工作原理是一样的。
也许这可能会更好,真正使用94可能的字符,而不是仅仅64,但我缺乏头脑来做这件事。
来源:复制和可压,使它运行与10个例子。..dotNet Fiddle告诉我,这超出了内存限制,所以您需要在机器上运行它来发送文本。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
public class Programm
{
public static void Main(string[] args)
{
string[] input = new[] {
"973581426526473198184296753247865319398124675651739842819342567765918234432657981",
"724865193169243875385197246896724351273951684451386927542639718618572439937418562",
"157682349432519687698347251825476193713928465964135728541293876289761534376854912",
"835416927296857431417293658569134782123678549748529163652781394981345276374962815",
"628451793594732681713689542247315869961827354385964217156243978439578126872196435",
"123456789456789123789123456214365897365897214897214365531648972648972531972531648",
"145792836376584192298361754731928645859647321462135987624873519587419263913256478",
"527416938864329157139578642291854376348697521675132489712945863483261795956783214",
"246713985185496732937825146678542391493168257512379468824957613759631824361284579",
"861294573475318692392567814236459781154783269987621345529176438648932157713845926" };
string[] permutations = GetPermutations();
foreach (string sudoku in input)
{
int[] indices = _compressSudoku(sudoku, permutations).ToArray();
string compressedRepresentation = _toCompressedRepresentation(indices);
Console.WriteLine(compressedRepresentation);
indices = _fromCompressedRepresentation(compressedRepresentation);
string decompressedSudoku = _decompressSudoku(indices, permutations);
if (decompressedSudoku != sudoku)
throw new Exception();
}
Console.ReadKey();
}
static int[] _digitMask = new int[] { 6, 5, 3, 5, 3, 1, 2, 1, 1 };
private static int[] _fromCompressedRepresentation(string compressedRepresentation)
{
BigInteger big = new BigInteger(Convert.FromBase64String(compressedRepresentation + "="));
string stringValue = big.ToString().Substring(1);
List<int> indexes = new List<int>();
int i = 0;
while (stringValue.Length > 0)
{
int length = _digitMask[i++];
string current = stringValue.Substring(0, length);
stringValue = stringValue.Substring(length);
indexes.Add(int.Parse(current));
}
return indexes.ToArray(); ;
}
private static string _toCompressedRepresentation(int[] indices)
{
StringBuilder builder = new StringBuilder("1");
int i = 0;
foreach (int index in indices)
{
string mask = "{0:D" + _digitMask[i++].ToString() + "}";
builder.AppendFormat(mask, index);
}
string base64 = Convert.ToBase64String(BigInteger.Parse(builder.ToString()).ToByteArray());
return base64.Substring(0, base64.Length - 1); // remove the = at the end.
}
private static IEnumerable<int> _compressSudoku(string input, string[] remainingPermutations)
{
string[] localRemainingPermutations = null;
List<HashSet<char>> localUsed = null;
for (int i = 0; i < 8; i++)
{
string currentRow = _getCurrentRow(input, i);
if (i % 3 == 0)
{
localRemainingPermutations = remainingPermutations;
localUsed = _initLocalUsed();
}
int index = 0;
foreach (string permutation in localRemainingPermutations)
{
if (permutation == currentRow)
{
yield return index;
break;
}
index++;
}
remainingPermutations = remainingPermutations.Where(permutation => _isStillValidPermutation(currentRow, permutation)).ToArray();
if (i % 3 < 2)
{
for (int j = 0; j < 9; j++)
localUsed[j / 3].Add(currentRow[j]);
localRemainingPermutations = localRemainingPermutations.Where(permutation => _isStillValidLocalPermutation(permutation, localUsed)).ToArray();
}
}
}
private static string _decompressSudoku(int[] indices, string[] remainingPermutations)
{
StringBuilder result = new StringBuilder();
string[] localRemainingPermutations = null;
List<HashSet<char>> localUsed = null;
for (int i = 0; i < 9; i++)
{
if (i % 3 == 0)
{
localRemainingPermutations = remainingPermutations;
localUsed = _initLocalUsed();
}
string currentRow = localRemainingPermutations[i < indices.Length ? indices[i] : 0];
result.Append(currentRow);
remainingPermutations = remainingPermutations.Where(permutation => _isStillValidPermutation(currentRow, permutation)).ToArray();
if (i % 3 < 2)
{
for (int j = 0; j < 9; j++)
localUsed[j / 3].Add(currentRow[j]);
localRemainingPermutations = localRemainingPermutations.Where(permutation => _isStillValidLocalPermutation(permutation, localUsed)).ToArray();
}
}
return result.ToString();
}
private static string _getCurrentRow(string input, int i)
{
return new string(input.Skip(i * 9).Take(9).ToArray());
}
private static List<HashSet<char>> _initLocalUsed()
{
return new List<HashSet<char>> { new HashSet<char>(), new HashSet<char>(), new HashSet<char>() };
}
private static bool _isStillValidLocalPermutation(string permutation, List<HashSet<char>> localUsed)
{
for (int i = 0; i < 9; i++)
{
if (localUsed[i / 3].Contains(permutation[i]))
return false;
}
return true;
}
private static bool _isStillValidPermutation(string currentRow, string permutation)
{
return permutation.Select((c, j) => c != currentRow[j]).All(b => b);
}
static string[] GetPermutations(char[] chars = null)
{
if (chars == null)
chars = new[] { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
if (chars.Length == 2)
return new[] { new String(chars), new String(chars.Reverse().ToArray()) };
return chars.SelectMany(c => GetPermutations(chars.Where(sc => sc != c).ToArray()), (c, s) => c + s).ToArray();
}
}https://codegolf.stackexchange.com/questions/41523
复制相似问题