我是美国密码协会的成员。这本双月刊杂志包含了超过100种不同类型的密码。其中大约有15个是“密码学”——用字母代替数字的各种类型的算术问题。其中两三个是数独游戏,只不过是字母而不是数字。当网格完成后,九个不同的字母将在网格中的某个地方以某条线、对角线、螺旋线等方式拼出一个或多个单词。
我不用铅笔,也不用手写,而是从他们网站的会员区下载问题。
在处理这些数独游戏时,我使用vi,只是因为我使用了vi所具有的其他编辑器所没有的功能。主要是在把字母网格转换成有编号的网格,因为我觉得这样更容易解决,然后把完成的有编号的网格转换回字母网格中,找到解单词或单词。
这个问题被格式化为9组,每组9个字母,-s代表空格,写在两行中。第一步是将它们格式化成每行9个字符的9行。这没有什么特别的,只是在适当的位置插入8个换行符。
结果如下所示:
T-O-----C
-E-----S-
--AT--N-L
---NASO--
---E-T---
--SPCL---
E-T--OS--
-A-----P-
S-----C-T
So, first step in converting this into numbers is to make a list of the distinct letters. First, I make a copy of the block. I position the cursor at the top of the block, then type :y}}p. : puts me in command mode, y yanks the next movement command. Since } is a move to the end of the next paragraph, y} yanks the paragraph. } then moves the cursor to the end of the paragraph, and p pastes what we had yanked just after the cursor. So y}}p creates a copy of the next paragraph, and ends up with the cursor between the two copies.
接下来,我要把其中一个副本变成一个不同字母的列表。这个命令有点复杂:
:!}tr -cd A-Z | sed 's/\(.\)/\1\n/g' | sort -u | tr -d '\n'
: again puts me in command mode. ! indicates that the content of the next yank should be piped through a command line. } yanks the next paragraph, and the command line then uses the tr command to strip out everything except for upper-case letters, the sed command to print each letter on a single line, and the sort command to sort those lines, removing duplicates, and then tr strips out the newlines, leaving the nine distinct letters in a single line, replacing the nine lines that had made up the paragraph originally. In this case, the letters are: ACELNOPST.
下一步是制作网格的另一个副本。然后用我刚刚确定的字母把这些字母替换成1到9之间的数字。很简单::!}tr ACELNOPST 0-9。结果是:
8-5-----1
-2-----7-
--08--4-3
---4075--
---2-8---
--7613---
2-8--57--
-0-----6-
7-----1-8
这可以用通常的方式解决,或者输入任何你喜欢的数独求解器。然后,完成的解决方案可以转换回字母:!}tr 1-9 ACELNOPST。
vi的强大是很少有其他工具能比拟的。最大的问题是,只有极少数的vi教程书籍、网站、帮助文件等,几乎触及了可能的表面。