用C++实现的数独解题程序 SudokuSolver 2.4 及实例分析
阅读原文时间:2021年10月21日阅读:1

SudokuSolver 2.4 程序实现

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

class CQuizDealer
{
public:

void run(ulong tilsteps = 0);
void mode(std::string& ex) {
size_t pos = ex.find_first_not_of(" \t");
if (pos != std::string::npos) {
ex.erase(0, pos);
m_mode = (u8)strtoul(ex.c_str(), 0, 10);
}
printf("Working mode:%d (1:grp-only; 2:ply-only; other:both grp and ply)\n", (int)m_mode);
}

private:

CQuizDealer() : m_state(STA_UNLOADED), …, m_mode(0) {};

bool completeShrinkByGrp(u8* pGrp);
u8 incompleteShrinkByGrp(u8* pGrp);
u8 firstGreenWorld(u8* pGrp);
u8 incompleteShrinkBy1GW(u8 valSum, u8* pCelSumExs, u8* pGrp);
bool sameCandidates(u8 cel1, u8 cel2);
u8 anotherGreenWorld(u8* pGrp);
u8 incompleteShrinkByAGW(u8 times, u8* pTimesVals, u8* pValsCells, u8* pGrp);
u8 thirdGreenWorld(u8* pGrp);
u8 incompleteShrinkBy3GW(u8 sum, std::set& valSet, u8* pGrp);
bool unionValsByCombi(u8 sum, u8* pCombi, u8* pGrp, std::set& unionSet);

ulong m_steps;
u8 m_mode; // 1:grp-only; 2:ply-only; other:both

};

去掉了 setOnlyGrpMode 接口,新增了 mode 接口,相应地,原先的 onlygrp 命令换成了 mode [1|2|0] 命令。

增加了 thirdGreenWorld 等接口。

u8 CQuizDealer::filterCandidates()
{
incSteps();
u8 ret = RET_PENDING;
if (m_mode != 2) {
for (u8 row = 0; row < 9; ++row)
if (ret = filterRowGroup(row))
return ret;
for (u8 col = 0; col < 9; ++col)
if (ret = filterColGroup(col))
return ret;
for (u8 blk = 0; blk < 9; ++blk)
if (ret = filterBlkGroup(blk))
return ret;
}
if (m_mode != 1) {
for (u8 row = 0; row < 9; ++row) {
ret = filterRowCandidatesEx(row);
if (IsDone(ret))
return ret;
}
for (u8 col = 0; col < 9; ++col) {
ret = filterColCandidatesEx(col);
if (IsDone(ret))
return ret;
}
}
if (ret == RET_SHRUNKEN) {
printf("incomplete shrink met, filter again\n");
return filterCandidates();
}
return ret;
}

修改后,可以只使用 grp 算法求解,也可以只使用 ply 算法求解,缺省是两者都用。

1 u8 CQuizDealer::firstGreenWorld(u8* pGrp)
2 {
3 u8 size = pGrp[0];
4 u8 celSumExs[100] = {0};
5 for (u8 idx = 1; idx <= size; ++idx) {
6 u8 valSum = m_seqCell[pGrp[idx]].candidates[0];
7 u8 base = valSum * 10;
8 celSumExs[base] += 1;
9 u8 pos = base + celSumExs[base];
10 celSumExs[pos] = pGrp[idx];
11 }
12 for (u8 idx = 2; idx <= 6; ++idx) {
13 u8 ret = incompleteShrinkBy1GW(idx, celSumExs, pGrp);
14 if (ret != RET_PENDING)
15 return ret;
16 }
17 return RET_PENDING;
18 }

1 u8 CQuizDealer::incompleteShrinkBy1GW(u8 valSum, u8* pCelSumExs, u8* pGrp)
2 {
3 u8 base = valSum * 10;
4 if (pCelSumExs[base] < valSum) 5 return RET_PENDING; 6 u8 itemSum = 0; 7 Item items[9]; 8 for (u8 pos = 1; pos <= pCelSumExs[base]; ++pos) { 9 u8 idx = 0; 10 for (; idx < itemSum; ++idx) 11 if (sameCandidates(pCelSumExs[base + pos], items[idx].celIdxs[0])) { 12 items[idx].celIdxs[items[idx].sameSum] = pCelSumExs[base + pos]; 13 items[idx].sameSum++; 14 break; 15 } 16 if (idx == itemSum) { 17 items[itemSum].sameSum = 1; 18 items[itemSum].celIdxs[0] = pCelSumExs[base + pos]; 19 ++itemSum; 20 } 21 } 22 for (u8 idx = 0; idx < itemSum; ++idx) { 23 if (items[idx].sameSum > valSum)
24 return RET_WRONG;
25 }
26 bool shrunken = false;
27 for (u8 idx = 0; idx < itemSum; ++idx) {
28 if (items[idx].sameSum < valSum)
29 continue;
30 for (u8 pos = 1; pos <= pGrp[0]; ++pos) {
31 if (inSet(pGrp[pos], (u8*)&(items[idx])))
32 continue;
33 u8 isVals[10] = {0};
34 u8 cel1 = items[idx].celIdxs[0];
35 u8 cel2 = pGrp[pos];
36 intersection(m_seqCell[cel1].candidates, m_seqCell[cel2].candidates, isVals);
37 if (isVals[0] == 0)
38 continue;
39 shrunken = true;
40 for (u8 valIdx = 1; valIdx <= isVals[0]; ++valIdx) {
41 if (!removeVal(m_seqCell[cel2].candidates, isVals[valIdx]))
42 return RET_WRONG;
43 else
44 printf("1GW: %d shrunken out of [%d,%d]\n", (int)isVals[valIdx], (int)cel2 / 9 + 1, (int)cel2 % 9 + 1);
45 }
46 }
47 }
48 return (shrunken ? RET_SHRUNKEN : RET_PENDING);
49 }

1 u8 CQuizDealer::incompleteShrinkByGrp(u8* pGrp)
2 {
3 u8 ret = firstGreenWorld(pGrp);
4 if (ret != RET_PENDING)
5 return ret;
6 ret = anotherGreenWorld(pGrp);
7 if (ret != RET_PENDING)
8 return ret;
9 return thirdGreenWorld(pGrp);
10 }

u8 CQuizDealer::filterOneGroup(u8* pGrp)
{
return (completeShrinkByGrp(pGrp) ? RET_OK : incompleteShrinkByGrp(pGrp));
}

u8 CQuizDealer::incompleteShrinkByAGW(u8 times, u8* pTimesVals, u8* pValsCells, u8* pGrp)
{

while (true) {
u8 celSet[10] = {0};
u8 valSet[10] = {0};
if (matchValsCells(times, combi, pTimesVals, pValsCells, celSet, valSet)) {
valSet[0] = times;
bool shrunken = false;
for (u8 idx = 1; idx <= times; ++idx) {

if (candiSum < times) {
printf("2GW: [%d,%d] candidates %d lower than times %d!\n", (int)(cel / 9 + 1), (int)(cel % 9 + 1), (int)candiSum, (int)times);
return RET_WRONG;
}
shrunken = true;
for (u8 pos = 1; pos <= m_seqCell[cel].candidates[0];) {
u8 val = m_seqCell[cel].candidates[pos];
if (inSet(val, valSet))
++pos;
else {
removeVal(m_seqCell[cel].candidates, val);
printf("2GW: %d shrunken out of [%d,%d]\n", (int)val, (int)(cel / 9 + 1), (int)(cel % 9 + 1));
}
}
}

}
if (!move2NextCombi(times, combi))
break;
}
return RET_PENDING;
}

1 u8 CQuizDealer::thirdGreenWorld(u8* pGrp)
2 {
3 u8 grpSize = pGrp[0];
4 std::set valSet;
5 u8 lowSum = 9, highSum = 0;
6 for (u8 idx = 1; idx <= grpSize; ++idx) { 7 u8 valSum = m_seqCell[pGrp[idx]].candidates[0]; 8 if (valSum < lowSum) 9 lowSum = valSum; 10 if (valSum > highSum)
11 highSum = valSum;
12 for (u8 vidx = 1; vidx <= valSum; ++vidx) {
13 u8 val = m_seqCell[pGrp[idx]].candidates[vidx];
14 valSet.insert(val);
15 }
16 }
17 if (valSet.size() != grpSize) {
18 printf("3GW: shrink went wrong\n");
19 return RET_WRONG;
20 }
21 if (highSum == valSet.size())
22 --highSum;
23 for (u8 sum = lowSum; sum <= highSum; ++sum) {
24 u8 ret = incompleteShrinkBy3GW(sum, valSet, pGrp);
25 if (ret != RET_PENDING)
26 return ret;
27 }
28 return RET_PENDING;
29 }

1 u8 CQuizDealer::incompleteShrinkBy3GW(u8 sum, std::set& valSet, u8* pGrp)
2 {
3 u8 combi[10] = {0};
4 combi[0] = pGrp[0];
5 for (u8 idx = 0; idx < sum; ++idx) 6 combi[idx + 1] = idx; 7 while (true) { 8 std::set unionSet;
9 if (unionValsByCombi(sum, combi, pGrp, unionSet)) {
10 u8 compSet[10] = {0};
11 for (std::set::iterator it = valSet.begin(); it != valSet.end(); ++it)
12 if (unionSet.find(*it) == unionSet.end()) {
13 compSet[0] += 1;
14 compSet[compSet[0]] = *it;
15 }
16 combi[0] = sum; // for soon calling inSet properly
17 u8 cells[10] = {0};
18 for (u8 pos = 0; pos < pGrp[0]; ++pos) {
19 if (!inSet(pos, combi)) {
20 cells[0] += 1;
21 cells[cells[0]] = pos;
22 }
23 }
24 combi[0] = pGrp[0]; //back again
25 bool shrunken = false;
26 for (u8 idx = 1; idx <= cells[0]; ++idx) {
27 u8 pos = pGrp[cells[idx] + 1];
28 for (u8 inn = 1; inn <= m_seqCell[pos].candidates[0];) {
29 u8 val = m_seqCell[pos].candidates[inn];
30 if (inSet(val, compSet))
31 ++inn;
32 else {
33 shrunken = true;
34 removeVal(m_seqCell[pos].candidates, val);
35 printf("3GW: %d shrunken out of [%d,%d]\n", (int)val, (int)pos / 9 + 1, (int)pos % 9 + 1);
36 }
37 }
38 }
39 if (shrunken)
40 return RET_SHRUNKEN;
41 }
42 if (!move2NextCombi(sum, combi))
43 break;
44 }
45 return RET_PENDING;
46 }

1 bool CQuizDealer::unionValsByCombi(u8 sum, u8* pCombi, u8* pGrp, std::set& unionSet)
2 {
3 for (u8 idx = 1; idx <= sum; ++idx) { 4 u8 pos = pGrp[pCombi[idx] + 1]; 5 u8 valSum = m_seqCell[pos].candidates[0]; 6 if (valSum > sum)
7 return false;
8 for (u8 vidx = 1; vidx <= valSum; ++vidx) { 9 u8 val = m_seqCell[pos].candidates[vidx]; 10 unionSet.insert(val); 11 } 12 if (unionSet.size() > sum)
13 return false;
14 }
15 return (unionSet.size() == sum);
16 }

// 1.0 2021/9/20
// 2.0 2021/10/2
// 2.1 2021/10/4
// 2.2 2021/10/10
// 2.3 2021/10/17
#define STR_VER "Sudoku Solver 2.4 2021/10/19 by readalps\n\n"

void showOrderList()
{
printf(STR_VER);
printf("Order List:\n");
printf("load-quiz : load quiz from file\n");
printf("show: show quiz info\n");
printf("mode [1|2|0]: query or change working mode\n");
printf("step: step forward\n");
printf("run: run till the end or a new solution met\n");
printf("runtil : run till certain steps run\n");
printf("bye: quit\n");
}

void dealOrder(std::string& strOrder)
{
std::string strEx;
if ("bye" == strOrder)
setQuit();
else if (matchPrefixEx(strOrder, "load-quiz ", strEx))
CQuizDealer::instance()->loadQuiz(strEx);
else if ("show" == strOrder)
CQuizDealer::instance()->showQuiz();
else if (matchPrefixEx(strOrder, "mode", strEx))
CQuizDealer::instance()->mode(strEx);
else if ("step" == strOrder)
CQuizDealer::instance()->step();
else if ("run" == strOrder)
CQuizDealer::instance()->run();
else if (matchPrefixEx(strOrder, "runtil ", strEx)) {
ulong tilsteps = strtoul(strEx.c_str(), 0, 10);
CQuizDealer::instance()->run(tilsteps);
}
else
showOrderList();
}

实例分析

继续以 SudokuSolver 1.0:用C++实现的数独解题程序 【二】 里试验过的“最难”数独题为例做分析。

D:\read\num\Release>sudoku.exe

Order please:

Sudoku Solver 2.4 2021/10/19 by readalps

Order List:
load-quiz : load quiz from file
show: show quiz info
mode [1|2|0]: query or change working mode
step: step forward
run: run till the end or a new solution met
runtil : run till certain steps run
bye: quit

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

Order please:
run

1014) col 8 complete shrunken by group
1017) Guess [1,6] level 8 at 1 out of 2
1018) row 3 complete shrunken by group
1020) row 3 complete shrunken by group
1GW: 8 shrunken out of [2,7]
1022) row 2 incomplete shrunken by group
1023) Guess [1,8] level 9 at 1 out of 2
1026) row 9 complete shrunken by group
1028) col 6 complete shrunken by group
1031) Guess [2,5] level 10 at 1 out of 2
1034) shrinking 4 from [6,3] went wrong
1035) Forward guess [2,5] level 10 at 2 out of 2
812 753 649
943 682 175
675 491 283

154 237 896
369 845 721
287 169 534

521 974 368
438 526 917
796 318 452

Done [steps:1040, solution sum:1].
Run time: 430 milliseconds; steps: 1040, solution sum: 1.

Order please:

第二次 run 命令的输出信息为:

run

1GW: 2 shrunken out of [5,1]
1GW: 9 shrunken out of [5,1]
1GW: 2 shrunken out of [5,2]
1GW: 2 shrunken out of [5,4]
1GW: 9 shrunken out of [5,4]
1GW: 2 shrunken out of [5,8]
1GW: 9 shrunken out of [5,8]
1698) row 5 incomplete shrunken by group
1699) Guess [1,3] level 6 at 1 out of 2
1703) row 1 complete shrunken by group
1705) row 2 complete shrunken by group
1707) row 4 complete shrunken by group
1707) shrinking 9 from blk[5,1] went wrong
1708) Forward guess [1,3] level 6 at 2 out of 2
1709) shrinking 2 from [4,9] went wrong
1710) No more solution (solution sum is 1).
809 000 306
503 600 800
076 090 250

054 007 120
002 045 789
000 100 635

001 000 568
008 500 910
090 000 400

Invalid quiz [steps:1710] - no more solution (solution sum is 1)
Run time: 265 milliseconds; steps: 1710, solution sum: 1.

Order please:

从输出的完整信息看,不再有“ply”信息,说明求解过程中只用到了 grp 算法,而没有用到 ply 算法。

第一次 run 命令走了 1040 步,求得一个解,用时约 430 毫秒;第二次 run 命令用了约 265 毫秒得出结论此 quiz 只有一个解,两次 run 命令共走了 1710 步。

退出程序并重新进入交互,这次显式仅用 grp 算法模式求解:

Order please:
bye

D:\read\num\Release>sudoku.exe

Order please:
mode
Working mode:0 (1:grp-only; 2:ply-only; other:both grp and ply)

Order please:
mode 1
Working mode:1 (1:grp-only; 2:ply-only; other:both grp and ply)

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

Order please:
run

1GW: 8 shrunken out of [2,7]
1022) row 2 incomplete shrunken by group
1023) Guess [1,8] level 9 at 1 out of 2
1026) row 9 complete shrunken by group
1028) col 6 complete shrunken by group
1031) Guess [2,5] level 10 at 1 out of 2
1034) shrinking 4 from [6,3] went wrong
1035) Forward guess [2,5] level 10 at 2 out of 2
812 753 649
943 682 175
675 491 283

154 237 896
369 845 721
287 169 534

521 974 368
438 526 917
796 318 452

Done [steps:1040, solution sum:1].
Run time: 421 milliseconds; steps: 1040, solution sum: 1.

Order please:
run

1GW: 9 shrunken out of [5,8]
1698) row 5 incomplete shrunken by group
1699) Guess [1,3] level 6 at 1 out of 2
1703) row 1 complete shrunken by group
1705) row 2 complete shrunken by group
1707) row 4 complete shrunken by group
1707) shrinking 9 from blk[5,1] went wrong
1708) Forward guess [1,3] level 6 at 2 out of 2
1709) shrinking 2 from [4,9] went wrong
1710) No more solution (solution sum is 1).
809 000 306
503 600 800
076 090 250

054 007 120
002 045 789
000 100 635

001 000 568
008 500 910
090 000 400

Invalid quiz [steps:1710] - no more solution (solution sum is 1)
Run time: 265 milliseconds; steps: 1710, solution sum: 1.

Order please:
bye

D:\read\num\Release>

从输出信息看,除了第一次 run 命令用时比之前略微减少(从 430 减为 421)之外,其他信息完全一致。

再看一下显式仅用 ply 算法模式求解的输出信息:

D:\read\num\Release>sudoku.exe

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

Order please:
show
800 000 000
003 600 000
070 090 200

050 007 000
000 045 700
000 100 030

001 000 068
008 500 010
090 000 400

Order please:
mode 2
Working mode:2 (1:grp-only; 2:ply-only; other:both grp and ply)

Order please:
run

1054) col 6 shrunken ply-1 by vblk 2
[2,8]: 5 7 shrunken to 7 worked by col-ply1.
1056) col 8 shrunken ply-1 by vblk 1
1059) Guess [2,5] level 10 at 1 out of 2
1063) shrinking 8 from [4,7] went wrong
1064) Forward guess [2,5] level 10 at 2 out of 2
812 753 649
943 682 175
675 491 283

154 237 896
369 845 721
287 169 534

521 974 368
438 526 917
796 318 452

Done [steps:1069, solution sum:1].
Run time: 468 milliseconds; steps: 1069, solution sum: 1.

Order please:
run

1335) col 8 shrunken ply-2 by vblk 2
[4,9]: 1 2 4 6 9 shrunken to 1 4 6 9 worked by col-ply2.
[5,9]: 1 2 6 9 shrunken to 1 6 9 worked by col-ply2.
incomplete shrink met, filter again
1339) Guess [1,3] level 8 at 1 out of 2

2100) row 8 shrunken ply-1 by blk 2
[8,2]: 2 3 4 shrunken to 4 worked by row-ply2.
2102) row 8 shrunken ply-2 by blk 3
[6,1]: 2 7 9 shrunken to 7 worked by row-ply2.
[6,3]: 2 4 7 9 shrunken to 4 7 worked by row-ply2.
2104) row 6 shrunken ply-2 by blk 2
2104) shrinking 2 from [8,1] went wrong
2105) No more solution (solution sum is 1).
800 000 306
003 600 800
476 893 251

350 067 100
160 345 700
704 100 635

201 000 568
048 506 910
695 000 400

Invalid quiz [steps:2105] - no more solution (solution sum is 1)
Run time: 493 milliseconds; steps: 2105, solution sum: 1.

Order please:

可以看出,仅用 ply 算法求解,比起仅用 grp 算法求解,用时和步数都略有增加。第二次 run 命令的输出里有几次如下的信息输出:

incomplete shrink met, filter again

这正好对应 用C++实现的数独解题程序 SudokuSolver 2.1 及实例分析 里所言的:这样的两次关联收缩,倘若第一次不完全收缩发生在第五轮的 col-ply 筛查阶段,就会导致第二次的完全收缩接续不上,进而多加一次猜测行为。这是一个可改进之处。2.2 版本改进之后一直没有碰到这种情形,直到这里仅用 ply 算法求解时才碰到。

这一道据说也挺有难度:

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

把这 9 行数字放到一个文本文件(比如 D:\read\num\Release\s.txt)的头部位置。这次不对输出做删节处理,呈现完整的两次 run 命令输出:

D:\read\num\Release>sudoku.exe

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

Order please:
run
2) row 2 complete shrunken by group
4) row 5 complete shrunken by group
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
7) Guess [6,2] level 1 at 1 out of 2
8) row 5 complete shrunken by group
11) Guess [4,3] level 2 at 1 out of 2
13) col 3 complete shrunken by group
16) Guess [2,3] level 3 at 1 out of 2
18) Guess [3,3] level 4 at 1 out of 2
24) col 8 complete shrunken by group
28) row 3 complete shrunken by group
30) row 1 complete shrunken by group
32) row 1 complete shrunken by group
35) shrinking 1 from [9,1] went wrong
36) Forward guess [3,3] level 4 at 2 out of 2
2GW: 1 shrunken out of [1,8]
2GW: 4 shrunken out of [1,8]
2GW: 6 shrunken out of [1,8]
2GW: 1 shrunken out of [4,8]
CelSet: [1,8] [4,8] ValSet: 7 9
37) col 8 incomplete shrunken by group
38) Guess [1,1] level 5 at 1 out of 2
40) shrinking 9 from [2,4] went wrong
41) Forward guess [1,1] level 5 at 2 out of 2
43) Guess [1,2] level 6 at 1 out of 2
46) row 2 complete shrunken by group
48) row 3 complete shrunken by group
50) row 4 complete shrunken by group
52) row 4 complete shrunken by group
54) shrinking 8 from [9,4] went wrong
55) Forward guess [1,2] level 6 at 2 out of 2
57) row 3 complete shrunken by group
59) row 8 complete shrunken by group
1GW: 8 shrunken out of [9,4]
1GW: 2 shrunken out of [9,5]
1GW: 8 shrunken out of [9,5]
1GW: 2 shrunken out of [9,9]
1GW: 8 shrunken out of [9,9]
61) row 9 incomplete shrunken by group
62) Guess [1,8] level 7 at 1 out of 2
64) shrinking 9 from [1,5] went wrong
65) Forward guess [1,8] level 7 at 2 out of 2
67) row 2 complete shrunken by group
69) row 4 complete shrunken by group
71) row 6 complete shrunken by group
73) col 4 complete shrunken by group
1GW: 4 shrunken out of [2,9]
75) blk 3 incomplete shrunken by group
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
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
102) row 3 complete shrunken by group
105) Guess [1,9] level 4 at 1 out of 2
106) row 4 complete shrunken by group
108) col 8 complete shrunken by group
2GW: 6 shrunken out of [8,4]
2GW: 8 shrunken out of [8,4]
2GW: 2 shrunken out of [8,6]
2GW: 6 shrunken out of [8,6]
2GW: 8 shrunken out of [8,6]
CelSet: [8,4] [8,6] ValSet: 1 7
110) row 8 incomplete shrunken by group
111) Guess [1,8] level 5 at 1 out of 2
117) shrinking 2 from [4,2] went wrong
118) Forward guess [1,8] level 5 at 2 out of 2
120) shrinking 8 from [9,9] went wrong
121) Upward guess [1,9] level 4 at 2 out of 2
123) Guess [1,7] level 5 at 1 out of 2
124) col 8 complete shrunken by group
2GW: 4 shrunken out of [2,4]
2GW: 1 shrunken out of [8,4]
2GW: 8 shrunken out of [8,4]
CelSet: [2,4] [8,4] ValSet: 6 7
126) col 4 incomplete shrunken by group
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

Done [steps:131, solution sum:1].
Run time: 46 milliseconds; steps: 131, solution sum: 1.

Order please:
run
132) Forward guess [1,5] level 6 at 2 out of 2
1GW: 4 shrunken out of [2,6]
135) row 2 incomplete shrunken by group
136) Guess [2,4] level 7 at 1 out of 2
138) row 3 complete shrunken by group
139) shrinking 8 from blk[8,7] went wrong
140) Forward guess [2,4] level 7 at 2 out of 2
142) row 3 complete shrunken by group
143) shrinking 8 from blk[8,7] went wrong
144) Upward guess [1,7] level 5 at 2 out of 2
146) shrinking 8 from [9,4] went wrong
147) Upward guess [4,3] level 2 at 2 out of 2
149) row 6 complete shrunken by group
151) col 8 complete shrunken by group
154) Guess [4,8] level 3 at 1 out of 2
157) row 6 complete shrunken by group
1GW: 4 shrunken out of [1,7]
1GW: 4 shrunken out of [2,7]
159) col 7 incomplete shrunken by group
160) Guess [3,1] level 4 at 1 out of 2
163) shrinking 8 from [9,5] went wrong
164) Forward guess [3,1] level 4 at 2 out of 2
165) row 2 complete shrunken by group
167) row 7 complete shrunken by group
169) row 9 complete shrunken by group
172) Guess [2,2] level 5 at 1 out of 2
174) Guess [1,2] level 6 at 1 out of 2
176) row 3 complete shrunken by group
178) col 6 complete shrunken by group
180) row 5 complete shrunken by group
183) row 8 complete shrunken by group
184) shrinking 2 from [8,7] went wrong
185) Forward guess [1,2] level 6 at 2 out of 2
187) row 2 complete shrunken by group
189) shrinking 5 from [9,1] went wrong
190) Upward guess [2,2] level 5 at 2 out of 2
193) row 1 complete shrunken by group
194) shrinking 6 from [8,6] went wrong
195) Upward guess [4,8] level 3 at 2 out of 2
196) row 6 complete shrunken by group
199) Guess [3,8] level 4 at 1 out of 2
2GW: 1 shrunken out of [1,7]
2GW: 8 shrunken out of [1,7]
2GW: 1 shrunken out of [2,7]
CelSet: [1,7] [2,7] ValSet: 6 9
201) col 7 incomplete shrunken by group
202) Guess [1,9] level 5 at 1 out of 2
203) shrinking 1 from [4,4] went wrong
204) Forward guess [1,9] level 5 at 2 out of 2
206) shrinking 1 from [4,4] went wrong
207) Upward guess [3,8] level 4 at 2 out of 2
208) col 3 complete shrunken by group
210) col 7 complete shrunken by group
212) col 6 complete shrunken by group
214) blk 1 complete shrunken by group
1GW: 1 shrunken out of [7,7]
1GW: 4 shrunken out of [7,7]
1GW: 1 shrunken out of [8,9]
1GW: 1 shrunken out of [9,9]
1GW: 4 shrunken out of [9,9]
216) blk 9 incomplete shrunken by group
217) Guess [1,9] level 5 at 1 out of 2
218) col 2 complete shrunken by group
221) shrinking 9 from [5,3] went wrong
222) Forward guess [1,9] level 5 at 2 out of 2
223) col 7 complete shrunken by group
225) col 7 complete shrunken by group
230) shrinking 8 from [4,4] went wrong
231) Upward guess [6,2] level 1 at 2 out of 2
232) row 6 complete shrunken by group
234) row 5 complete shrunken by group
236) row 6 complete shrunken by group
239) row 8 complete shrunken by group
241) row 9 complete shrunken by group
243) col 3 complete shrunken by group
245) blk 9 complete shrunken by group
248) Guess [1,2] level 2 at 1 out of 2
251) shrinking 7 from [1,9] went wrong
252) Forward guess [1,2] level 2 at 2 out of 2
254) row 3 complete shrunken by group
257) Guess [2,3] level 3 at 1 out of 2
1GW: 2 shrunken out of [9,1]
1GW: 8 shrunken out of [9,4]
1GW: 2 shrunken out of [9,5]
1GW: 8 shrunken out of [9,5]
1GW: 2 shrunken out of [9,9]
1GW: 8 shrunken out of [9,9]
258) row 9 incomplete shrunken by group
259) Guess [1,1] level 4 at 1 out of 2
260) shrinking 6 from [2,4] went wrong
261) Forward guess [1,1] level 4 at 2 out of 2
3GW: 2 shrunken out of [7,5]
3GW: 8 shrunken out of [7,5]
263) col 5 incomplete shrunken by group
264) Guess [2,7] level 5 at 1 out of 2
266) shrinking 2 from [7,7] went wrong
267) Forward guess [2,7] level 5 at 2 out of 2
268) row 1 complete shrunken by group
271) row 1 complete shrunken by group
273) row 5 complete shrunken by group
3GW: shrink went wrong
275) row 7 shrink by group went WRONG
276) Upward guess [2,3] level 3 at 2 out of 2
280) row 5 complete shrunken by group
282) col 7 complete shrunken by group
283) shrinking 6 from [2,4] went wrong
284) 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:284] - no more solution (solution sum is 1)
Run time: 63 milliseconds; steps: 284, solution sum: 1.

Order please:
bye

D:\read\num\Release>

可以看到,这个 quiz 的求解过程,出现的最深猜测级别为 11 级:

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

仅比前面那个 quiz 少一级。但从用时和步数看,这个 quiz 要容易不少。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章