SudokuSolver 2.6 的新功能及相关分析

SudokuSolver 2.6 的命令清单如下:

H:\Read\num\Release>sudoku.exe

Order please:

Sudoku Solver 2.6 2021/10/30 by readalps

Order List:
load-quiz <file>: load quiz from file
show: show quiz info
levels: show info about guess levels
run-mode [1|2|0]: query or change working mode
guess-mode [1|0]: query or change guessing mode
step: step forward
run: run till the end or a new solution met
runtil <steps>: run till certain steps run
runrun <sum>: run till the end or certain new solutions met
bye: quit Order please:

以 用C++实现的数独解题程序 SudokuSolver 2.4 及实例分析 里用过的 另一道数独题 为例说明一下 2.6 版的新功能:

005 300 000
800 000 020
070 010 500
400 005 300
010 070 006
003 200 080
060 500 009
004 000 030
000 009 700

最大猜测级别信息展示

H:\Read\num\Release>sudoku.exe

Order please:
load-quiz h:\s.txt
Quiz loaded.

Order please:
run
2) row 2 complete shrunken by group
...
81) Guess [1,7] level 9 at 1 out of 2
84) Guess [2,6] level 10 at 1 out of 2
87) row 9 complete shrunken by group
89) col 4 complete shrunken by group
92) Guess [4,2] level 11 at 1 out of 2
...
127) Guess [1,5] level 6 at 1 out of 2
145 327 698
839 654 127
672 918 543

496 185 372
218 473 956
753 296 481

367 542 819
984 761 235
521 839 764

Fine [steps:131, solution sum:1].
Run time: 131 milliseconds; steps: 131, solution sum: 1.
 Biggest level on this run(til): 11

Order please:

上面的示例是加载完 quiz 接着就给了一条 run 命令,即求出一个解时停下来。最后的 biggest level on this run(til): 11 信息输出是新版增加的,给出在这次 run(或 runtil)命令的求解过程中出现过最大猜测级别是 11 级。这个信息可以很直观地衡量数独题的难度,猜测级别越大,难度越大。当然,另一个很直观地衡量数独题的难度的信息是求解步数。综合这两个信息就可以基本客观地衡量数独题的难度。

通过仔细查看 run 命令输出的求解过程信息,可以看出达到猜测级别 11 是在走到 92 步时发生的,且只发生过一次(即降下来之后没有再次升到过 11 级)。下面介绍一种更快更容易的方法来界定这个结论。

既然 131 步完成一个求解的过程中最大猜测级别为 11 级,考虑用二分法看走完前 131/2 = 65 步时的最大猜测级别是多少,具体如下:

Order please:
bye H:\Read\num\Release>sudoku.exe Order please:
load-quiz h:\s.txt
Quiz loaded. Order please:
runtil 65

2) row 2 complete shrunken by group
...
At guess level 7 [1,8] 2
Run time: 129 milliseconds; steps: 65, solution sum: 0.
Biggest level on this run(til): 7 Order please:

65 步时所经历的最大猜测级别是 7。继续用二分法,(66+130)/2 = 98,接着运行 runtil 98:

Order please:
runtil 98
67) row 2 complete shrunken by group
...
At guess level 3 [2,3] 2
Run time: 109 milliseconds; steps: 98, solution sum: 0.
Biggest level on this run(til): 11 Order please:

66 步到 98 步之间有过最大猜测级别 11。进一步用二分法缩小范围,(66+98)/2 = 82:

Order please:
bye H:\Read\num\Release>sudoku.exe Order please:
load-quiz h:\s.txt
Quiz loaded. Order please:
runtil 82

2) row 2 complete shrunken by group
...
At guess level 9 [1,7] 1
Run time: 96 milliseconds; steps: 82, solution sum: 0.
Biggest level on this run(til): 9 Order please:

1 到 82 步之间最高猜测级别仅为 9,说明 11 级猜测发生在 83 步到 98 步之间,(83+98)/2 = 90,接着运行 runtil 90:

Order please:
runtil 90

84) Guess [2,6] level 10 at 1 out of 2
...
At guess level 10 [2,6] 1
Run time: 55 milliseconds; steps: 90, solution sum: 0.
Biggest level on this run(til): 10 Order please:

这时已经界定出 11 级猜测发生在 91 步到 98 步之间。直接接着运行 runtil 98,看一下这几步的输出信息即可知道 11 级猜测具体发生在哪一步:

Order please:
runtil 98
92) Guess [4,2] level 11 at 1 out of 2

92) shrinking 8 from [8,7] went wrong
93) Forward guess [4,2] level 11 at 2 out of 2
93) shrinking 5 from [8,1] went wrong
94) Upward guess [2,6] level 10 at 2 out of 2
95) shrinking 5 from [9,9] went wrong
96) Upward guess [1,7] level 9 at 2 out of 2
96) shrinking 4 from blk[6,9] went wrong
97) Upward guess [1,5] level 8 at 2 out of 2
97) shrinking 7 from [2,9] went wrong
98) Upward guess [2,3] level 3 at 2 out of 2
...
At guess level 3 [2,3] 2
Run time: 100 milliseconds; steps: 98, solution sum: 0.
Biggest level on this run(til): 11 Order please:

这样,就轻易地界定出走到 92 步时达到了 11 级猜测。从随后几行输出信息又可看出,第 11 级猜测的两个候选值都会引发错误(went wrong),之后依次逐级下降到第 8 级,然后一下降到第 3 级。这个过程的具体分析放到后面。这里继续界定最高的 11 级猜测有没有再次发生。在走完 98 步的情形下,直接给一个 run 命令:

Order please:
run
102) row 3 complete shrunken by group
...
Fine [steps:131, solution sum:1].
Run time: 50 milliseconds; steps: 131, solution sum: 1.
Biggest level on this run(til): 6 Order please:

从 98 步到 131 步之间最大猜测级别为 6,不到 11 级。再给一次 run 命令:

Order please:
run
132) Forward guess [1,5] level 6 at 2 out of 2
...
Invalid quiz [steps:284] - no more solution (solution sum is 1)
Run time: 154 milliseconds; steps: 284, solution sum: 1.
Biggest level on this run(til): 7 Order please:

从 132 步走到最后求解完成,期间最大猜测级别为 7。于是可以界定整个求解过程只有一次达到 11 级猜测。

levels 命令:查看当前各级猜测相关的信息

以下这段是上面 runtil 90 执行完之后的 runtil 98 的输出信息:

92) Guess [4,2] level 11 at 1 out of 2
92) shrinking 8 from [8,7] went wrong
93) Forward guess [4,2] level 11 at 2 out of 2
93) shrinking 5 from [8,1] went wrong
94) Upward guess [2,6] level 10 at 2 out of 2
95) shrinking 5 from [9,9] went wrong
96) Upward guess [1,7] level 9 at 2 out of 2
96) shrinking 4 from blk[6,9] went wrong
97) Upward guess [1,5] level 8 at 2 out of 2
97) shrinking 7 from [2,9] went wrong
98) Upward guess [2,3] level 3 at 2 out of 2

以下借助新增的 levels 命令来具体分析一下这一段信息对应的行为。

92) Guess [4,2] level 11 at 1 out of 2

这一行是说对第 4 行第 2 列对应的空位的两个候选值做 2 猜 1 的处理,在此之前已对 10 个空位做了猜值处理,所以这一次猜测属于第 11 级猜测。从头求解,用 runtil 90 进到当时的上下文:

Order please:
runtil 90
...
76) Guess [1,5] level 8 at 1 out of 2
78) row 1 complete shrunken by group
81) Guess [1,7] level 9 at 1 out of 2
84) Guess [2,6] level 10 at 1 out of 2
87) row 9 complete shrunken by group
89) col 4 complete shrunken by group
645 327 198
831 954 627
279 618 543 406 095 370
910 073 056
753 200 980 367 502 019
094 700 030
000 039 760 Steps:90
Candidates:
[4,2]: 2 8 [4,4]: 1 8 [4,9]: 1 2
[5,3]: 2 8 [5,4]: 4 8 [5,7]: 2 4
[6,5]: 4 6 [6,6]: 1 6 [6,9]: 1 4
[7,5]: 4 8 [7,7]: 4 8 [8,1]: 1 5
[8,5]: 6 8 [8,6]: 1 6 [8,7]: 2 8
[8,9]: 2 5 [9,1]: 1 5 [9,2]: 2 8
[9,3]: 2 8 [9,4]: 1 4 [9,9]: 4 5
The foremost cell with 2 candidate(s) at [4,2] At guess level 10 [2,6] 1
Run time: 139 milliseconds; steps: 90, solution sum: 0.
Biggest level on this run(til): 10 Order please:

从中可以看到,当时还有 21 个空位,且每个空位的候选值都是两个,其中最靠前的位置是 [4,2],它的候选值集合为 {2, 8}。当时已处在猜测级别 10。对照上面的信息可知,随后会在 [4,2] 位置进行第 11 级猜测。

运行 step 命令,新的上下文信息为:

Order please:
step
92) Guess [4,2] level 11 at 1 out of 2
645 327 198
831 954 627
279 618 543 426 095 370
910 073 056
753 200 980 367 502 019
094 700 030
000 039 760 Steps:92
Candidates:
[4,4]: 1 8 [4,9]: 1 [5,3]: 8
[5,4]: 4 8 [5,7]: 2 4 [6,5]: 4 6
[6,6]: 1 6 [6,9]: 1 4 [7,5]: 4 8
[7,7]: 4 8 [8,1]: 1 5 [8,5]: 6 8
[8,6]: 1 6 [8,7]: 2 8 [8,9]: 2 5
[9,1]: 1 5 [9,2]: 8 [9,3]: 2 8
[9,4]: 1 4 [9,9]: 4 5
The foremost cell with 1 candidate(s) at [4,9] At guess level 11 [4,2] 1 Order please:

仔细看会发现这里有一个看似很蹊跷的问题:90 步怎么直接跳到了 92 步,是不是程序有 bug,哪里多算了一次?

这个问题需要结合程序实现解释一下,在走完 90 步时,上下文有如下一行信息:

The foremost cell with 2 candidate(s) at [4,2]

即所有的空位中,候选值个数最小为 2(实际上如上面所述,每个空位的候选值个数都为 2),不能直接填值,而这种情形下会调用 filterCandidates 接口尝试对这些空位的候选值做收缩处理,前文所述的 grp 和 ply 收缩算法都在这个接口里施行,这个接口每调用一次,步数都会加一。因此,每当施行了 grp 和 ply 收缩算却又不能达到完全收缩或不完全收缩时,对应的这一步就不会有任何输出信息,随后一步输出新的猜测信息,故而造成视觉上的跳步错觉。当然,程序可以再改进一下,让 filterCandidates 在白忙一场时也输出一行信息,刷一下存在感,比如:

91) No shrink happened

继续上下文分析。因为 [4,2] 位置上已经填上了 2,此时还有 20 个空位,且其中有三个位置的候选值数量降为 1,即可以直接填值。下一步:

Order please:
step
92) shrinking 8 from [8,7] went wrong
93) Forward guess [4,2] level 11 at 2 out of 2
645 327 198
831 954 627
279 618 543 486 095 370
910 073 056
753 200 980 367 502 019
094 700 030
000 039 760 Steps:93
Candidates:
[4,4]: 1 [4,9]: 1 2 [5,3]: 2
[5,4]: 4 8 [5,7]: 2 4 [6,5]: 4 6
[6,6]: 1 6 [6,9]: 1 4 [7,5]: 4 8
[7,7]: 4 8 [8,1]: 1 5 [8,5]: 6 8
[8,6]: 1 6 [8,7]: 2 8 [8,9]: 2 5
[9,1]: 1 5 [9,2]: 2 [9,3]: 2 8
[9,4]: 1 4 [9,9]: 4 5
The foremost cell with 1 candidate(s) at [4,4] At guess level 11 [4,2] 2 Order please:

提交 step 命令后输出的头两行信息是:

92) shrinking 8 from [8,7] went wrong
93) Forward guess [4,2] level 11 at 2 out of 2

第一行是说从第 8 行第 7 列的空位上把其候选值 8 收缩掉时会出现矛盾,第二行是说对 [4,2] 空位上的猜值做调整,即填上第二个候选值。

第二行是好懂的,因为 92 步一开始猜测 [4,2] = 2,随后在对其它空位填值时出现了矛盾,说明 [4,2] ≠ 2,于是接着猜测 [4,2] = 8。

具体看一下 [4,2] = 2 时怎么推出的矛盾。接着看 92 步时的上下文,在 [4,2] 填入 2 后,如下三个空位可以直接填值:

[4,9]: 1    [5,3]: 8
[9,2]: 8

即:

645 327 198
831 954 627
279 618 543
426 095 371
918 073 056
753 200 980
367 502 019
094 700 030
080 039 760

此时对剩余空位的候选值做调整处理,即对第 4 行、第 9 列、第 6 宫做去 1 处理;对第 5 行、第 3 列、第 4 宫做去 8 处理;对第 9 行、第 2 列、第 7 宫做去 8 处理):

[4,4]: 1 8
[5,4]: 4 8 [5,7]: 2 4 [6,5]: 4 6
[6,6]: 1 6 [6,9]: 1 4 [7,5]: 4 8
[7,7]: 4 8 [8,1]: 1 5 [8,5]: 6 8
[8,6]: 1 6 [8,7]: 2 8 [8,9]: 2 5
[9,1]: 1 5 [9,3]: 2 8
[9,4]: 1 4 [9,9]: 4 5

对单候选值空位直接做填值处理,即有:

645 327 198
831 954 627
279 618 543
426 895 371
918 473 056
753 200 980
367 502 019
094 700 030
082 039 760

同上类似,再对剩余空位的候选值做调整处理:

              [5,7]: 2 4    [6,5]: 4 6
[6,6]: 1 6 [6,9]: 1 4 [7,5]: 4 8
[7,7]: 4 8 [8,1]: 1 5 [8,5]: 6 8
[8,6]: 1 6 [8,7]: 2 8 [8,9]: 2 5
[9,1]: 1 5
[9,4]: 1 4 [9,9]: 4 5

对单候选值空位直接做填值处理,即有:

645 327 198
831 954 627
279 618 543
426 895 371
918 473 256
753 260 980
367 502 019
094 700 030
082 139 760

再对剩余空位的候选值做调整处理:

[6,6]: 1 6    [6,9]: 1 4    [7,5]: 4 8
[7,7]: 4 8 [8,1]: 1 5 [8,5]: 6 8
[8,6]: 1 6 [8,7]: 2 8 [8,9]: 2 5
[9,1]: 1 5 [9,9]: 4 5

可以看到 [8,5] 和 [8,7] 的候选值都只剩下 8,它们同属第 8 行,前者填入 8 后,会对相关联的同行、同列、同宫空位做去 8 处理,于是 [8,7] 的候选值集合被收缩为空集,即 [8,7] 位置上无值可填,导致矛盾。

以上花了一些篇幅分析由猜测 [4,2] = 2 引发矛盾的详细过程。回到 93 步的上下文:

645 327 198
831 954 627
279 618 543 486 095 370
910 073 056
753 200 980 367 502 019
094 700 030
000 039 760 Steps:93
Candidates:
[4,4]: 1 [4,9]: 1 2 [5,3]: 2
[5,4]: 4 8 [5,7]: 2 4 [6,5]: 4 6
[6,6]: 1 6 [6,9]: 1 4 [7,5]: 4 8
[7,7]: 4 8 [8,1]: 1 5 [8,5]: 6 8
[8,6]: 1 6 [8,7]: 2 8 [8,9]: 2 5
[9,1]: 1 5 [9,2]: 2 [9,3]: 2 8
[9,4]: 1 4 [9,9]: 4 5
The foremost cell with 1 candidate(s) at [4,4] At guess level 11 [4,2] 2

这时,已调整为 [4,2] = 8,即处在第 11 级猜测的第二个候选值;此时也有不少空位可以直接填值。继续看下一步:

Order please:
step
93) shrinking 5 from [8,1] went wrong
94) Upward guess [2,6] level 10 at 2 out of 2
...
The foremost cell with 1 candidate(s) at [2,7] At guess level 10 [2,6] 2 Order please:

头两行输出信息为:

93) shrinking 5 from [8,1] went wrong
94) Upward guess [2,6] level 10 at 2 out of 2

由第一行的信息可知又出现了矛盾,这里不再详细分析导致矛盾的具体过程。这次出现矛盾说明 [4,2] 上也不能填 8,即 2 和 8 两个候选值都不能填,这就说明之前的猜测链条上至少有一个环节有问题。因此要调整上级的猜测,这里是第 10 级做出调整,[2,6] 位置上的填值由第一个候选值调整为第二个候选值。

但是如果要仔细分析猜测级别的调整过程,这里给出的上下文信息是不够的。比如此时知道处在第 10 级猜测,但并不知道前面 9 级猜测是哪些位置上哪些取值,是可以在前面的输出信息里找到,但是很零散。因此,2.6 版新增了一个 levels 命令来提供这个额外的上下文信息。具体看一下:

Order please:
levels
At guess level 10:
Level 10 [2,6]=6 (2 out of 2)
Level 9 [1,7]=1 (1 out of 2)
Level 8 [1,5]=2 (1 out of 2)
Level 7 [1,8]=9 (2 out of 2)
Level 6 [1,2]=4 (2 out of 2)
Level 5 [1,1]=6 (2 out of 2)
Level 4 [3,3]=9 (2 out of 2)
Level 3 [2,3]=1 (1 out of 2)
Level 2 [4,3]=6 (1 out of 2)
Level 1 [6,2]=5 (1 out of 2) Order please:

这个命令提供了当前各级猜测的信息,比如第 4 级猜测位置在 [3,3],猜测值为 9,是两个候选值中的第二个。

接下来的两步:

Order please:
step
...
The foremost cell with 1 candidate(s) at [4,9] At guess level 10 [2,6] 2 Order please:
step
95) shrinking 5 from [9,9] went wrong
96) Upward guess [1,7] level 9 at 2 out of 2
...
The foremost cell with 1 candidate(s) at [1,9] At guess level 9 [1,7] 2 Order please:

第 10 级猜测的第二个候选值出现矛盾,向上级调整,第 9 级猜测位置 [1,7] 调整为取第二个候选值。

下一步以及 levels 信息:

Order please:
step
96) shrinking 4 from blk[6,9] went wrong
97) Upward guess [1,5] level 8 at 2 out of 2
...
The foremost cell with 1 candidate(s) at [1,7] At guess level 8 [1,5] 2 Order please:
levels
At guess level 8:
Level 8 [1,5]=8 (2 out of 2)
Level 7 [1,8]=9 (2 out of 2)
Level 6 [1,2]=4 (2 out of 2)
Level 5 [1,1]=6 (2 out of 2)
Level 4 [3,3]=9 (2 out of 2)
Level 3 [2,3]=1 (1 out of 2)
Level 2 [4,3]=6 (1 out of 2)
Level 1 [6,2]=5 (1 out of 2)

第 9 级猜测的第二个候选值出现矛盾,向上级调整,第 8 级猜测位置 [1,5] 调整为取第二个候选值。

从 levels 输出的信息可以看出 4、5、6、7、8 级猜测取值都在各自的最后一个候选值上。

再下一步以及 levels 信息:

Order please:
step
97) shrinking 7 from [2,9] went wrong
98) Upward guess [2,3] level 3 at 2 out of 2
005 300 000
809 050 020
070 010 500 406 005 300
010 073 056
753 200 080 067 500 009
004 000 030
000 009 700 Steps:98
Candidates:
[1,1]: 1 2 6 [1,2]: 2 4 [1,5]: 2 4 6 8 9
[1,6]: 2 4 6 7 8 [1,7]: 1 4 6 8 9 [1,8]: 1 4 6 7 9
[1,9]: 1 4 7 8 [2,2]: 3 4 [2,4]: 4 6 7
[2,6]: 4 6 7 [2,7]: 1 4 6 [2,9]: 1 3 4 7
[3,1]: 2 3 6 [3,3]: 2 [3,4]: 4 6 8 9
[3,6]: 2 4 6 8 [3,8]: 4 6 9 [3,9]: 3 4 8
[4,2]: 2 8 9 [4,4]: 1 8 9 [4,5]: 8 9
[4,8]: 1 7 9 [4,9]: 1 2 7 [5,1]: 2 9
[5,3]: 2 8 [5,4]: 4 8 9 [5,7]: 2 4 9
[6,5]: 4 6 9 [6,6]: 1 4 6 [6,7]: 1 4 9
[6,9]: 1 4 [7,1]: 1 2 3 [7,5]: 2 3 4 8
[7,6]: 1 2 4 8 [7,7]: 1 2 4 8 [7,8]: 1 4
[8,1]: 1 2 5 9 [8,2]: 2 8 9 [8,4]: 1 6 7 8
[8,5]: 2 6 8 [8,6]: 1 2 6 7 8 [8,7]: 1 2 6 8
[8,9]: 1 2 5 8 [9,1]: 1 2 3 5 [9,2]: 2 3 8
[9,3]: 1 2 8 [9,4]: 1 4 6 8 [9,5]: 2 3 4 6 8
[9,8]: 1 4 6 [9,9]: 1 2 4 5 8
The foremost cell with 1 candidate(s) at [3,3] At guess level 3 [2,3] 2 Order please:
levels
At guess level 3:
Level 3 [2,3]=9 (2 out of 2)
Level 2 [4,3]=6 (1 out of 2)
Level 1 [6,2]=5 (1 out of 2)

第 8 级猜测的第二个候选值出现矛盾,向上级调整,第 7 级猜测位置已经是其最后一个候选值,只能再往上级调整,一直调整到第 3 级猜测位置取其第二个候选值为止。

交互式猜测功能

从最初的 1.0 版到 2.5 版,每一级猜测都是程序按照预设的规则自动进行的,预设的规则也很简单:

(1)优先对候选值个数少的位置做猜测;

(2)候选值个数少的位置有多处,则选位置最靠前的位置做猜测;

(3)同一个猜测位置的不同候选值按顺序遍历调整。

2.6 版引入的交互式猜测功能打破了规则(1)和规则(2),可以人为干预故意猜对或猜错,也可以故意挑候选值多的位置做猜测。这样方便考察一些极端情形下求解的最大猜测级别。

以下采用每次都猜对的做法来看一下求解过程中的最大猜测级别是什么情况。

进入交互式猜测模式:

H:\Read\num\Release>sudoku.exe

Order please:
load-quiz h:\s.txt
Quiz loaded. Order please:
guess-mode
In interactive guessing mode:0 (0:no; other:yes) Order please:
guess-mode 1

In interactive guessing mode:1 (0:no; other:yes) Order please:

用 step 命令逐步进行求解,碰到需要新猜测的情形程序会停下来:

...
Candidates:
[1,1]: 1 2 6 9 [1,2]: 2 4 9 [1,5]: 2 4 6 8 9
[1,6]: 2 4 6 7 8 [1,7]: 1 4 6 8 9 [1,8]: 1 4 6 7 9
[1,9]: 1 4 7 8 [2,2]: 3 4 9 [2,3]: 1 6 9
[2,4]: 4 6 7 9 [2,6]: 4 6 7 [2,7]: 1 4 6 9
[2,9]: 1 3 4 7 [3,1]: 2 3 6 9 [3,3]: 2 6 9
[3,4]: 4 6 8 9 [3,6]: 2 4 6 8 [3,8]: 4 6 9
[3,9]: 3 4 8 [4,2]: 2 8 9 [4,3]: 2 6 7 8 9
[4,4]: 1 6 8 9 [4,5]: 6 8 9 [4,8]: 1 7 9
[4,9]: 1 2 7 [5,1]: 2 5 9 [5,3]: 2 8 9
[5,4]: 4 8 9 [5,7]: 2 4 9 [5,8]: 4 5 9
[6,1]: 5 6 7 9 [6,2]: 5 9 [6,5]: 4 6 9
[6,6]: 1 4 6 [6,7]: 1 4 9 [6,9]: 1 4 5 7
[7,1]: 1 2 3 7 [7,3]: 1 2 7 8 [7,5]: 2 3 4 8
[7,6]: 1 2 4 7 8 [7,7]: 1 2 4 8 [7,8]: 1 4
[8,1]: 1 2 5 7 9 [8,2]: 2 5 8 9 [8,4]: 1 6 7 8
[8,5]: 2 6 8 [8,6]: 1 2 6 7 8 [8,7]: 1 2 6 8
[8,9]: 1 2 5 8 [9,1]: 1 2 3 5 [9,2]: 2 3 5 8
[9,3]: 1 2 8 [9,4]: 1 4 6 8 [9,5]: 2 3 4 6 8
[9,8]: 1 4 5 6 [9,9]: 1 2 4 5 8
The foremost cell with 2 candidate(s) at [6,2] Order please:
step
2GW: 2 shrunken out of [4,3]
2GW: 8 shrunken out of [4,3]
2GW: 9 shrunken out of [4,3]
2GW: 5 shrunken out of [6,1]
2GW: 9 shrunken out of [6,1]
CelSet: [4,3] [6,1] ValSet: 6 7
6) blk 4 incomplete shrunken by group
Take a guess please, by default it will be [6,2]=5:

这个题已经知道唯一求解,即:

145 327 698
839 654 127
672 918 543
496 185 372
218 473 956
753 296 481
367 542 819
984 761 235
521 839 764

的确有 [6,2]=5,于是直接回车,再用 step 逐步求解:

Steps:9
Candidates:
[1,1]: 1 2 6 9 [1,2]: 2 4 9 [1,5]: 2 4 6 8 9
[1,6]: 2 4 6 7 8 [1,7]: 1 4 6 8 9 [1,8]: 1 4 6 7 9
[1,9]: 1 4 7 8 [2,2]: 3 4 9 [2,3]: 1 6 9
[2,4]: 4 6 7 9 [2,6]: 4 6 7 [2,7]: 1 4 6 9
[2,9]: 1 3 4 7 [3,1]: 2 3 6 9 [3,3]: 2 6 9
[3,4]: 4 6 8 9 [3,6]: 2 4 6 8 [3,8]: 4 6 9
[3,9]: 3 4 8 [4,2]: 2 8 9 [4,3]: 6 7
[4,4]: 1 6 8 9 [4,5]: 6 8 9 [4,8]: 1 7 9
[4,9]: 1 2 7 [5,1]: 2 9 [5,3]: 2 8 9
[5,4]: 4 8 9 [5,7]: 2 4 9 [6,1]: 6 7
[6,5]: 4 6 9 [6,6]: 1 4 6 [6,7]: 1 4 9
[6,9]: 1 4 7 [7,1]: 1 2 3 7 [7,3]: 1 2 7 8
[7,5]: 2 3 4 8 [7,6]: 1 2 4 7 8 [7,7]: 1 2 4 8
[7,8]: 1 4 [8,1]: 1 2 5 7 9 [8,2]: 2 8 9
[8,4]: 1 6 7 8 [8,5]: 2 6 8 [8,6]: 1 2 6 7 8
[8,7]: 1 2 6 8 [8,9]: 1 2 5 8 [9,1]: 1 2 3 5
[9,2]: 2 3 8 [9,3]: 1 2 8 [9,4]: 1 4 6 8
[9,5]: 2 3 4 6 8 [9,8]: 1 4 6 [9,9]: 1 2 4 5 8
The foremost cell with 2 candidate(s) at [4,3] At guess level 1 [6,2] 1 Order please:
step
Take a guess please, by default it will be [4,3]=6:

对照答案,的确有 [4,3]=6,回车,继续 step:

Steps:14
Candidates:
[1,1]: 1 2 6 9 [1,2]: 2 4 9 [1,5]: 2 4 6 8 9
[1,6]: 2 4 6 7 8 [1,7]: 1 4 6 8 9 [1,8]: 1 4 6 7 9
[1,9]: 1 4 7 8 [2,2]: 3 4 9 [2,3]: 1 9
[2,4]: 4 6 7 9 [2,6]: 4 6 7 [2,7]: 1 4 6 9
[2,9]: 1 3 4 7 [3,1]: 2 3 6 9 [3,3]: 2 9
[3,4]: 4 6 8 9 [3,6]: 2 4 6 8 [3,8]: 4 6 9
[3,9]: 3 4 8 [4,2]: 2 8 9 [4,4]: 1 8 9
[4,5]: 8 9 [4,8]: 1 7 9 [4,9]: 1 2 7
[5,1]: 2 9 [5,3]: 2 8 9 [5,4]: 4 8 9
[5,7]: 2 4 9 [6,5]: 4 6 9 [6,6]: 1 4 6
[6,7]: 1 4 9 [6,9]: 1 4 [7,1]: 1 2 3
[7,5]: 2 3 4 8 [7,6]: 1 2 4 8 [7,7]: 1 2 4 8
[7,8]: 1 4 [8,1]: 1 2 5 9 [8,2]: 2 8 9
[8,4]: 1 6 7 8 [8,5]: 2 6 8 [8,6]: 1 2 6 7 8
[8,7]: 1 2 6 8 [8,9]: 1 2 5 8 [9,1]: 1 2 3 5
[9,2]: 2 3 8 [9,3]: 1 2 8 [9,4]: 1 4 6 8
[9,5]: 2 3 4 6 8 [9,8]: 1 4 6 [9,9]: 1 2 4 5 8
The foremost cell with 2 candidate(s) at [2,3] At guess level 2 [4,3] 1 Order please:
step
Take a guess please, by default it will be [2,3]=1:

输出正确答案 [2,3]=9,继续 step:

Take a guess please, by default it will be [2,3]=1:
[2,3]=9
16) Guess [2,3] level 3 at 1 out of 2
...
Steps:21
Candidates:
[1,5]: 2 6 8 9 [1,6]: 2 6 7 8 [1,7]: 6 8 9
[1,8]: 6 7 9 [1,9]: 7 8 [2,4]: 4 6 7
[2,6]: 4 6 7 [2,7]: 1 4 6 [2,9]: 1 4 7
[3,4]: 4 8 9 [3,6]: 4 8 [3,8]: 4 9
[4,2]: 2 9 [4,4]: 1 8 9 [4,5]: 8 9
[4,8]: 1 7 9 [4,9]: 1 2 7 [5,1]: 2 9
[5,4]: 4 9 [5,7]: 2 4 9 [6,5]: 4 6 9
[6,6]: 1 4 6 [6,7]: 1 4 9 [6,9]: 1 4
[7,1]: 2 3 [7,5]: 2 3 4 8 [7,6]: 1 2 4 8
[7,7]: 1 2 4 8 [7,8]: 1 4 [8,1]: 2 5 9
[8,2]: 2 8 9 [8,4]: 1 6 7 8 [8,5]: 2 6 8
[8,6]: 1 2 6 7 8 [8,7]: 1 2 6 8 [8,9]: 1 2 5 8
[9,1]: 2 3 5 [9,2]: 2 8 [9,4]: 4 6 8
[9,5]: 2 3 4 6 8 [9,8]: 4 6 [9,9]: 2 4 5 8
The foremost cell with 2 candidate(s) at [1,9] At guess level 3 [2,3] 1 Order please:
step
Take a guess please, by default it will be [1,9]=7:

这次故意选个候选值多的猜:[1,6]: 2 6 7 8

按答案输入 [1,6]=7,继续 step:

Take a guess please, by default it will be [1,9]=7:
[1,6]=7
23) Guess [1,6] level 4 at 1 out of 4
... Steps:39
Candidates:
[1,7]: 6 [2,4]: 6 [2,6]: 4
[3,4]: 9 [3,6]: 8
The foremost cell with 1 candidate(s) at [1,7] At guess level 4 [1,6] 1 Order please:
step
145 327 698
839 654 127
672 918 543 496 185 372
218 473 956
753 296 481 367 542 819
984 761 235
521 839 764 Fine [steps:40, solution sum:1]. Order please:
levels
At guess level 4:
Level 4 [1,6]=7 (1 out of 4)
Level 3 [2,3]=9 (1 out of 2)
Level 2 [4,3]=6 (1 out of 2)
Level 1 [6,2]=5 (1 out of 2) Order please:

求得一个解,使用步数为 40,最大猜测级别仅为 4 级。

关闭交互式猜测模式,并给一次 run 命令:

Order please:
guess-mode 0
In interactive guessing mode:0 (0:no; other:yes) Order please:
run
...
285) Upward guess [2,3] level 3 at 2 out of 2
289) row 5 complete shrunken by group
291) col 7 complete shrunken by group
292) shrinking 6 from [2,4] went wrong
293) No more solution (solution sum is 1).
145 300 900
839 050 127
672 018 543 426 005 371
518 473 296
793 261 485 067 500 819
954 000 632
081 609 750 Invalid quiz [steps:293] - no more solution (solution sum is 1)
Run time: 234 milliseconds; steps: 293, solution sum: 1.
Biggest level on this run(til): 11 Order please:

可以看到在求出一个解后到全部走完的过程,最大猜测级别是 11 级。

用C++实现的数独解题程序 SudokuSolver 2.6 的新功能及相关分析的更多相关文章

  1. 用C++实现的数独解题程序 SudokuSolver 2.3 及实例分析

    SudokuSolver 2.3 程序实现 用C++实现的数独解题程序 SudokuSolver 2.2 及实例分析 里新发现了一处可以改进 grp 算法的地方,本次版本实现了对应的改进 grp 算法 ...

  2. 用C++实现的数独解题程序 SudokuSolver 2.2 及实例分析

    SudokuSolver 2.2 程序实现 根据 用C++实现的数独解题程序 SudokuSolver 2.1 及实例分析 里分析,对 2.1 版做了一些改进和尝试. CQuizDealer 类声明部 ...

  3. 用C++实现的数独解题程序 SudokuSolver 2.4 及实例分析

    SudokuSolver 2.4 程序实现 本次版本实现了 用C++实现的数独解题程序 SudokuSolver 2.3 及实例分析 里发现的第三个不完全收缩 grp 算法 thirdGreenWor ...

  4. 用C++实现的数独解题程序 SudokuSolver 2.1 及实例分析

    SudokuSolver 2.1 程序实现 在 2.0 版的基础上,2.1 版在输出信息上做了一些改进,并增加了 runtil <steps> 命令,方便做实例分析. CQuizDeale ...

  5. 用C++实现的数独解题程序 SudokuSolver 2.7 及实例分析

    引言:一个 bug 的发现 在 MobaXterm 上看到有内置的 Sudoku 游戏,于是拿 SudokuSolver 求解,随机出题,一上来是个 medium 级别的题: 073 000 060 ...

  6. SudokuSolver 1.0:用C++实现的数独解题程序 【二】

    本篇是 SudokuSolver 1.0:用C++实现的数独解题程序 [一] 的续篇. CQuizDealer::loadQuiz 接口实现 1 CQuizDealer* CQuizDealer::s ...

  7. SudokuSolver 2.0:用C++实现的数独解题程序 【一】

    SudokuSolver 2.0 实现效果 H:\Read\num\Release>sudoku.exe Order please: Sudoku Solver 2.0 2021/10/2 by ...

  8. 微信小程序0.11.122100版本新功能解析

    微信小程序0.11.122100版本新功能解析   新版本就不再吐槽了,整的自己跟个愤青似的.人老了,喷不动了,把机会留给年轻人吧.下午随着新版本开放,微信居然破天荒的开放了开发者论坛.我很是担心官方 ...

  9. SudokuSolver 1.0:用C++实现的数独解题程序 【一】

    SudokuSolver 1.0 用法与实现效果 SudokuSolver 是一个提供命令交互的命令行程序,提供的命令清单有: H:\Read\num\Release>sudoku.exe Or ...

随机推荐

  1. 【第一篇】- Maven 系列教程之Spring Cloud直播商城 b2b2c电子商务技术总结

    Maven 教程 Maven 翻译为"专家"."内行",是 Apache 下的一个纯 Java 开发的开源项目.基于项目对象模型(缩写:POM)概念,Maven ...

  2. vue-cli 项目中使用 v-chart 及导出 chart 图片

    安装: npm i v-charts echarts -S 组件中使用: 1 <template> 2 <div class="app-chart"> 3 ...

  3. undefined和null

    undefined和null undefined的情景: 声明变量为赋值 var name; console.og(name); //undefined 访问对象上不存在的属性 var obj={} ...

  4. Apache Dolphin Scheduler - Dockerfile 详解

    Apache DolphinScheduler 是一个分布式去中心化,易扩展的可视化 DAG 工作流任务调度系统.简称 DS,包括 Web 及若干服务,它依赖 PostgreSQL 和 Zookeep ...

  5. 第七章:网络优化与正则化(Part1)

    任何数学技巧都不能弥补信息的缺失. --科尼利厄斯·兰佐斯(Cornelius Lanczos) 匈牙利数学家.物理学家 文章相关 1 第七章:网络优化与正则化(Part1) 2 第七章:网络优化与正 ...

  6. python IO流操作

    python IO流操作 学习完本篇,你将会独立完成 实现操作系统中文件及文件目录的拷贝功能. 将目标图片拷贝到指定的目录中 实现一个自动阅卷程序, Right.txt保存正确答案,xx(学生姓名). ...

  7. Python爬无止境,获得王者荣耀全部高清皮肤

    作为一名热爱王者两年的程序员,早就想爬取所有英雄皮肤的高清照片,在设个幻灯片放映,真香,这次只用16行代码就能实现,对于新手拿这个作为实战练手项目既简单又容易上手,快来尝试下. 百度"王者荣 ...

  8. IDL使用

    出错的问题,可能是因为路径,或者没有建立工程文件. 运行IDL并在preferences项里修改设置(如图中红框所示) (IDL 8.4中在) 2, 中文字符显示乱码,改为gb2312

  9. python学习笔记(五)-文件操作2

    一.文件修改 现有文件file.txt,内容如下:二十四节气歌春雨惊春清谷天,夏满芒夏暑相连.秋处露秋寒霜降,冬雪雪冬小大寒.上半年逢六廿一,下半年逢八廿三.每月两节日期定,最多相差一二天.要求:将文 ...

  10. 深度理解JVM

      1. 环境搭建 安装jdk 2. 内存溢出场景模拟 public class Test01 { public static void main(String[] args) { //测试内存溢出 ...