<p>如果您希望在纯python中检查数独的所有约束,最好将所有约束生成为可以总结的值列表:</p>
<pre><code>def check_constraints(constraints, target_sum):
for _constraint in constraints:
if sum(_constraint) != target_sum:
return False
return True
</code></pre>
<p>要提取以行列表形式组织的网格的子矩阵,对一组水平范围和一组垂直范围进行嵌套迭代就足够了:</p>
^{pr2}$
<p>这两组范围由函数<code>make_ranges</code>生成:</p>
<pre><code>def make_ranges(h_step, v_step, length):
return (make_range(h_step, length), make_range(v_step, length))
</code></pre>
<p>它为每个方向调用<code>make_range</code>:</p>
<pre><code>def make_range(step, width):
range_ = []
_start = 0
for _end in range(step, width+1, step):
range_.append((_start, _end))
_start = _end
return range_
</code></pre>
<p>为了保持算法的灵活性,网格参数被定义为变量:</p>
<pre><code>SUDOKU_WIDTH = 3
SUDOKU_HEIGHT = 3
CONSTRAINT_LEN = SUDOKU_WIDTH * SUDOKU_HEIGHT
CONSTRAINT_SUM = sum(range(CONSTRAINT_LEN + 1))
</code></pre>
<p>通用范围集创建为:</p>
<pre><code>row_ranges = make_ranges(CONSTRAINT_LEN, 1, CONSTRAINT_LEN)
col_ranges = make_ranges(1, CONSTRAINT_LEN, CONSTRAINT_LEN)
quad_ranges = make_ranges(SUDOKU_WIDTH, SUDOKU_HEIGHT, CONSTRAINT_LEN)
</code></pre>
<p>从网格中提取相应的约束:</p>
<pre><code>rows = get_grid_constraints(GRID, *row_ranges)
cols = get_grid_constraints(GRID, *col_ranges)
quads = get_grid_constraints(GRID, *quad_ranges)
</code></pre>
<p>检查<code>CONSTRAINT_SUM</code>:</p>
^{8}$
<p>这允许详细的调试输出来验证算法的正确操作:</p>
<pre><code>dbg_fwid = 11
dbg_sep = '\n {1:<{0}s}'.format(dbg_fwid, '')
def dbg_lists(lists):
return dbg_sep.join((str(_l) for _l in lists))
def sformat(fmt, *args, **kwargs):
return fmt.format(*args, **kwargs)
print(sformat("# "":DBG: {1:<{0}s}: ]{2!s}[", dbg_fwid, "CONSTRAINT_SUM", (CONSTRAINT_SUM)))
print(sformat("# "":DBG: {1:<{0}s}: ]{2!s}[", dbg_fwid, "row_ranges", (row_ranges)))
print(sformat("# "":DBG: {1:<{0}s}: ]{2!s}[", dbg_fwid, "col_ranges", (col_ranges)))
print(sformat("# "":DBG: {1:<{0}s}: ]{2!s}[", dbg_fwid, "quad_ranges", (quad_ranges)))
print(sformat("# "":DBG: {1:<{0}s}: ]{2!s}[", dbg_fwid, "rows", dbg_lists(rows)))
print(sformat("# "":DBG: {1:<{0}s}: ]{2!s}[", dbg_fwid, "cols", dbg_lists(cols)))
print(sformat("# "":DBG: {1:<{0}s}: ]{2!s}[", dbg_fwid, "quads", dbg_lists(quads)))
print(sformat("# "":DBG: {1:<{0}s}: ]{2!s}[", dbg_fwid, "is_valid", (is_valid)))
</code></pre>
<p>这表明:</p>
<pre><code>CONSTRAINT_SUM: ]45[
row_ranges : ]([(0, 9)], [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9)])[
col_ranges : ]([(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9)], [(0, 9)])[
quad_ranges: ]([(0, 3), (3, 6), (6, 9)], [(0, 3), (3, 6), (6, 9)])[
rows : ][1, 3, 2, 5, 4, 6, 9, 8, 7]
[4, 6, 5, 8, 7, 9, 3, 2, 1]
[7, 9, 8, 2, 1, 3, 6, 5, 4]
[9, 2, 1, 4, 3, 5, 8, 7, 6]
[3, 5, 4, 7, 6, 8, 2, 1, 9]
[6, 8, 7, 1, 9, 2, 5, 4, 3]
[5, 7, 6, 9, 8, 1, 4, 3, 2]
[2, 4, 3, 6, 5, 7, 1, 9, 8]
[8, 1, 9, 3, 2, 4, 7, 6, 5][
cols : ][1, 4, 7, 9, 3, 6, 5, 2, 8]
[3, 6, 9, 2, 5, 8, 7, 4, 1]
[2, 5, 8, 1, 4, 7, 6, 3, 9]
[5, 8, 2, 4, 7, 1, 9, 6, 3]
[4, 7, 1, 3, 6, 9, 8, 5, 2]
[6, 9, 3, 5, 8, 2, 1, 7, 4]
[9, 3, 6, 8, 2, 5, 4, 1, 7]
[8, 2, 5, 7, 1, 4, 3, 9, 6]
[7, 1, 4, 6, 9, 3, 2, 8, 5][
quads : ][1, 3, 2, 4, 6, 5, 7, 9, 8]
[9, 2, 1, 3, 5, 4, 6, 8, 7]
[5, 7, 6, 2, 4, 3, 8, 1, 9]
[5, 4, 6, 8, 7, 9, 2, 1, 3]
[4, 3, 5, 7, 6, 8, 1, 9, 2]
[9, 8, 1, 6, 5, 7, 3, 2, 4]
[9, 8, 7, 3, 2, 1, 6, 5, 4]
[8, 7, 6, 2, 1, 9, 5, 4, 3]
[4, 3, 2, 1, 9, 8, 7, 6, 5][
is_valid : ]True[
</code></pre>