用Go语言拆解数独365的第三天视频,一个编程爱好者的实战笔记
- NBA
- 2026-07-09 20:14:37
- 390
说实话,我一开始看到“数独365的第三天视频”这个关键词,第一反应是:这跟Go语言有啥关系? 后来一想,嘿,用Go写个数独求解器,不就是最好的学习方式吗?于是我就打开了那个视频,一边看一边写代码,结果发现第三天视频里讲的中级技巧——“唯余法”和“区块摒除法”——用Go实现起来特别有意思。
先搭个架子:数独棋盘的数据结构
视频里那个9×9的格子,在Go里怎么表示?我第一版写了个[9][9]int,但马上发现不够用——因为每个格子可能同时存多个候选数,于是改成了二维切片:
type Sudoku [9][9]int type Candidates [9][9][]int
你看,这就像视频里说的:每个空格里先填上1-9所有可能,对应到Go代码里,就是初始化一个Candidates,给每个空位塞个[]int{1,2,3,4,5,6,7,8,9},这一步做对了,后面就顺了。
核心逻辑:视频里教的“唯余法”怎么翻译成代码
第三天视频花了十来分钟讲唯余法,我当时在笔记本上画了个图,然后写了个函数:
func onlyOneLeft(c Candidates) bool {
for r := 0; r < 9; r++ {
for c := 0; c < 9; c++ {
if len(candidates[r][c]) == 1 {
// 这个格子里只剩下一个可能数字,填入!
sudoku[r][c] = candidates[r][c][0]
// 然后更新同行同列同宫的候选数
updateCandidates(r, c, sudoku[r][c])
return true
}
}
}
return false
}
这里有个坑:视频里演示的时候,一发现唯余就填,然后立刻更新,我一开始没写updateCandidates,结果填了数字也没去掉其他格子的候选,导致求解到一半就卡死了,改过来之后,跑了一遍视频里的那个例子——结果完全吻合!那种感觉就像解出那道题一样爽。
区块摒除法:代码比想象中绕
视频到后面讲到区块摒除,我卡了快一小时。区块摒除是什么? 简单说,就是某个数字在某个宫里只能出现在某一行(或某一列),那么这一行(或列)在其他宫里就不能出现这个数字。
我写了个很丑的函数:
| 步骤 | 做的事情 | Go代码片段 |
|---|---|---|
| 1 | 遍历每个宫 | for boxR := 0; boxR < 3; boxR++ { for boxC := 0; boxC < 3; boxC++ { ... } } |
| 2 | 对每个数字1-9,找出它在宫里可能出现的位置 | positions := findPossiblePositions(boxR, boxC, num) |
| 3 | 检查这些位置是否都在同一行 | allSameRow := checkSameRow(positions) |
| 4 | 如果都在同一行,则消除该行其他宫里这个数字的候选 | eliminateInOtherBoxes(boxR, boxC, row, num) |
写完之后,我对视频里的第三个例子做了测试。第7行第5列那个格子,之前一直解不出来,用了区块摒除后候选数从3个减成1个,直接填上了,那一刻我对着屏幕笑出声,跟视频弹幕里有人说“原来如此”时的心情一模一样。
一点小感悟:视频里的直觉,代码里的严谨
视频里演示的时候,很多步骤是靠“看”的——看一眼就发现某个宫里数字2只能出现在第三行,但计算机不会“看”,你得像教小学生一样,把每一步拆碎。
- 判断两个格子是否在同一行:
r1/3 == r2/3? 不对,应该是检查它们的行坐标是否相等 - 如何遍历一个3×3宫:起始行是
boxR*3,起始列是boxC*3 - 候选数更新的时机:每填一个数,就得立刻清理它影响到的所有格子
写代码的时候我一度觉得很烦:“视频里一眼就能看出来的东西,我为什么要写15行代码?” 但等到程序跑起来,看着控制台一行一行打印出求解过程,那感觉比直接用眼睛看视频要深刻得多,视频讲的是“是什么”,代码逼你想的是“为什么”。
最后聊点实在的
花了一个周末把“数独365第三天视频”里的技巧用Go实现了一遍,最大的收获不是学会了数独,而是学会了怎么把一个视觉化的逻辑拆解成计算机能执行的步骤,Go的强类型和简洁语法帮了大忙——你不会写出太绕的代码,因为编译器会盯着你。
如果你也想试试,我建议从最简单的[9][9]int开始,别一上来就搞候选数法,先写出一个暴力回溯版本,能解24道题;再用视频里的技巧优化,就能解全部365道,这个过程,就像从新手玩家变成了创造者。
视频看完了,代码写完了,回头再看“数独365的第三天视频”那几个字,感觉不一样了——它不再是一个视频标题,而是一段被我用Go语言重新理解和表达过的逻辑,没别的,就是写给自己看看。
