开源学村

使用 Linux 命令行解决Wordle 问题

使用 Linux 的 grep 命令和 fgrep 命令解开你喜欢的单词猜谜游戏。

我最近有点迷上了一个在线文字游戏,在这个游戏中,你有六次机会来猜一个随机的五个字母的单词。这个词每天都在变化,而且你每天只能玩一次。每次猜测后,你猜测中的每个字母都会被高亮显示:灰色表示该字母没有出现在神秘的单词中,黄色表示该字母出现在单词中,但不在那个位置,绿色表示该字母出现在该单词的正确位置。

以下是教你如何使用 Linux 命令行来帮助你玩猜谜游戏,如 Wordle。我用这个方法帮助我解决了1月6日的谜题:

第一次尝试

Linux 系统在 /usr/share/dict/words 文件中保存了一个单词词典。这是一个很长的纯文本文件。我系统的 words 文件有超过479800个条目。该文件既包含纯文字,也包含专有名词(名字、地点等等)。

为了开始我的第一个猜测,我只想要一个正好是五个字母长度的纯文字列表。要做到这点,我使用了 grep 命令:

$ grep '^[a-z][a-z][a-z][a-z][a-z]$' /usr/share/dict/words > myguess

grep 命令使用正则表达式进行搜索。你可以用正则表达式做很多事情,但为了帮助我解决 Wordle 问题,我只需要一些基础的知识点: ^ 表示行的开始, $ 表示行的结束。在这两者之间,我指定了5个 [a-z] 的实例,表示从 a 到 z 的任何小写字母。

我还可以使用 wc 命令看到可能的单词列表中“只有”15000个单词:

$ wc -l myguess
15034 myguess

从该列表中,我随机挑选了一个五个字母的单词: acres。 a 被设置为黄色,意味着该字母存在于神秘单词的某个位置,但不在第一位置。其他字母是灰色的,所以我知道它们不存在于今天的单词中。

第二次尝试

对于我的下一个猜测,我想得到一个包含 a,但不是在第一位置的所有单词的列表。我的列表也不应该包括字母 c, r, e 或 s。让我们把它分解为几个步骤:

为了得到所有带 a 的单词的列表,我使用 fgrep(fixed strings grep) 命令。 fgrep 命令也像 grep 一样搜索文本,但不使用正则表达式

$ fgrep a myguess > myguess2

这使我下一个可能的猜测列表从15000字降为6600字:

$ wc -l myguess myguess2
 15034 myguess
  6634 myguess2
 21668 total

但这个单词列表也包括了第一个位置的字母a,这是我不想要的。游戏已经表明字母 a 存在于其他位置。我可以用 grep 修改我的命令,寻找在第一个位置含有其他字母的词。这样我就把可能的猜测缩小到5500个单词:

$ fgrep a myguess | grep '^[b-z]' > myguess2
$ wc -l myguess myguess2
 15034 myguess
  5566 myguess2
 20600 total

但我知道这个神秘的词也不包括字母 c、 r、 e 和 s,所以我可以用另一个 grep 命令从搜索中省略这些字母:

$ fgrep a myguess | grep '^[b-z]' | grep -v '[cres]' > myguess2
$ wc -l myguess myguess2
15034 myguess
 1257 myguess2
16291 total

-v 选项表示反转搜索,因此 grep 将只返回不符合正则表达式 [cres] 或单列字母 c、 r、 e 或 s 的行。通过这个额外的 grep 命令,我已经将下一个猜测的范围大大缩小到只有1200个可能的单词,这些单词在某处有 a,但不在第一位置,并且不包含 c、 r、 e 或 s。

查看列表后,我决定尝试 balmy 这个词。

第三次尝试

这一次,字母 b 和 a 被高亮为绿色,这意味着我把这些字母放在了正确的位置。字母 l 是黄色的,所以这个字母存在于单词的其他地方,但不是在那个位置。字母 m 和 y 是灰色的,所以我可以在我的下一次猜测中排除这些。

为了确定我下一个可能的单词列表,我可以使用另一组 grep 命令。我知道这个词以 ba 开头,所以我可以从这里开始搜索:

$ grep '^ba' myguess2 > myguess3
$ wc -l myguess3
77 myguess3

这只有77个字!我可以通过寻找除第三位外还含有字母 l 的词来进一步缩小范围:

$ grep '^ba[^l]' myguess2 > myguess3
$ wc -l myguess3
61 myguess3

方括号[^l] 内的 ^ 意味着不是这个字母列表,所以不是字母 l。这使我的可能单词列降到61个,但并非所有单词都包含字母 l,我可以使用另一个 grep 搜索来消除字母 l:

$ grep '^ba[^l]' myguess2 | fgrep l > myguess3
$ wc -l myguess3
10 myguess3

其中一些单词可能含有字母 m 和 y,而这些字母并不在今天的神秘词中。我可以再进行一次倒置的 grep 搜索,把它们从我的猜测列表中删除:

$ grep '^ba[^l]' myguess2 | fgrep l | grep -v '[my]' > myguess3
$ wc -l myguess3
7 myguess3

我的可能词汇清单现在很短,只有7个词!

$ cat myguess3
babul
bailo
bakal
bakli
banal
bauld
baulk

我将选择 banal 作为我下一个猜测的单词,而这恰好是正确的。

正则表达式的力量

Linux 命令行提供了强大的工具来帮助您完成实际工作。 grep 和 fgrep 命令在扫描单词列表时提供了极大的灵活性。对于一个基于单词的猜谜游戏, grep 帮助确定了一个当天包含15000个可能的单词的列表。在猜测并知道哪些字母在神秘的单词中出现和没有出现之后, grep 和 fgrep 帮助将选项缩小到1200个单词,然后只剩下7个单词。这就是命令行的威力。


翻译:starstary
参考资料:Solve Wordle using the Linux command line

对这篇文章感觉如何?

太棒了
2
不错
0
爱死了
0
不太好
0
感觉很糟
0

You may also like

Leave a reply

您的邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

More in:开源学村

开源学村

SoCal Linux博览会回归20周年

现在已经是支持和推广FOSS社区的第20个年头了,SCaLE 20x - 南加州Linux博览会将于2023年3月9日至12日在帕萨迪纳会议中心举行。 这个为期4天的年度活动汇集了充满活力的开源用户社 […]
开源学村

如何在Linux上杀死僵尸进程

消灭僵尸进程! 也称为“defunct”或“dead”进程 - 简单来说,僵尸进程是指已经结束,但仍存在于系统进程表中的进程。理想情况下,一旦进程完成其工作/执行,它应该从进程表中清除。但由于某些原因 […]
开源学村

2022年,从学习Rust开始

Rust作为一个新语言,已经连续五年(2016,2017,2018,2019,2020)在Stack Overflow开发者调查的“最受喜爱编程语言”。Rust是一个值得学习的编程语言,它对安全的专注,会帮助你许多。学习Rust 从这本小小的Rust Cheat Sheet出发,了解Rust语言的基本操作。
开源学村

如何杀死 Linux 中的僵尸进程

在使用操作系统工作时,要时刻注意保持对系统中进程的掌控。一旦僵尸进程占满了你的资源,就只能依靠重新启动来挽回一切了。所以快来学习用 kill 指令来杀灭僵尸进程吧!