使用 Linux 命令行解决 Wordle

使用 Linux grep 和 fgrep 命令来赢得您最喜欢的猜词游戏。
62 位读者喜欢这篇文章。
Linux keys on the keyboard for a desktop computer

我最近有点沉迷于一款在线猜词益智游戏,您有六次机会猜出一个随机的五个字母的单词。这个词每天都会更换,而且您每天只能玩一次。每次猜测后,您猜测的单词中的每个字母都会被高亮显示:灰色表示该字母未出现在谜底词中,黄色表示该字母出现在单词中但位置不正确,绿色表示该字母出现在单词中且位置正确。

以下是如何使用 Linux 命令行来帮助您玩像 Wordle 这样的猜词游戏。我使用这种方法来帮助我解决 1 月 6 日的谜题

第一次尝试

Linux 系统将单词字典保存在 /usr/share/dict/words 文件中。这是一个非常长的纯文本文件。我系统的单词文件包含超过 479,800 个条目。该文件包含普通单词和专有名词(名称、地点等等)。

为了开始我的第一次猜测,我只想得到一个正好是五个字母长的普通单词列表。为此,我使用这个 grep 命令

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

grep 命令使用正则表达式来执行搜索。您可以使用正则表达式做很多事情,但为了帮助我解决 Wordle,我只需要基本知识:^ 表示行的开头,$ 表示行的结尾。在两者之间,我指定了五个 [a-z] 实例,这表示从 a 到 z 的任何小写字母。

我还可以使用 wc 命令来查看我的可能单词列表“仅”有 15,000 个单词

$ wc -l myguess
15034 myguess

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

acres word attempt

Jim Hall (CC BY-SA 4.0)

第二次尝试

对于我的下一次猜测,我想要获得一个包含字母 a,但不在第一个位置的所有单词的列表。我的列表也不应包含字母 cres。让我们将此分解为几个步骤

为了获得所有包含字母 a 的单词列表,我使用 fgrep(固定字符串 grep)命令。fgrep 命令也像 grep 一样搜索文本,但不使用正则表达式

$ fgrep a myguess > myguess2

这使我的下一个猜测的可能列表从 15,000 个单词减少到 6,600 个单词

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

但这个单词列表也包括第一个位置的字母 a,这不是我想要的。游戏已经表明字母 a 存在于其他某个位置。我可以修改我的命令,使用 grep 来查找第一个位置包含其他字母的单词。这会将我的可能猜测范围缩小到仅 5,500 个单词

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

但我知道谜底词也不包含字母 cres。我可以使用另一个 grep 命令从搜索中省略这些字母

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

-v 选项表示反向搜索,因此 grep 将只返回与正则表达式 [cres] 或字母列表 cres 不匹配的行。通过这个额外的 grep 命令,我大大缩小了我的下一个猜测范围,仅剩下 1,200 个可能的单词,这些单词在某个位置包含字母 a,但不在第一个位置,并且不包含 cres

在查看列表后,我决定尝试单词 balmy

balmy word attempt

Jim Hall (CC BY-SA 4.0)

第三次尝试

这一次,字母 ba 以绿色突出显示,这意味着我的这些字母位置正确。字母 l 是黄色的,所以该字母存在于单词中的其他位置,但不在该位置。字母 my 是灰色的,所以我可以从我的下一次猜测中排除这些字母。

为了确定我的下一个可能的单词列表,我可以使用另一组 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 搜索来排除这些单词

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

其中一些单词可能包含字母 my,它们不在今天的谜底词中。我可以使用另一个反向 grep 搜索从我的猜测列表中删除这些单词

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

我的可能单词列表现在非常短,只有七个单词!

$ cat myguess3
babul
bailo
bakal
bakli
banal
bauld
baulk

我选择 banal 作为我下一次猜测的可能单词,结果碰巧是正确的。

banal word attempt

Jim Hall (CC BY-SA 4.0)

正则表达式的力量

Linux 命令行提供了强大的工具来帮助您完成实际工作。grepfgrep 命令在扫描单词列表时提供了极大的灵活性。对于猜词游戏,grep 帮助识别了 15,000 个可能的每日单词列表。在猜测并知道哪些字母出现和未出现在谜底词中之后,grepfgrep 帮助将选项缩小到 1,200 个单词,然后仅剩下七个单词。这就是命令行的力量。

接下来阅读什么
标签
photo of Jim Hall
Jim Hall 是一位开源软件倡导者和开发人员,以 GNOME 的可用性测试以及作为 FreeDOS 的创始人兼项目协调员而闻名。

1 条评论

哇,这真是一个巧妙的技巧!我从来没有想过这样使用 grep。谢谢你的精彩教程

Creative Commons License本作品根据 知识共享许可协议 4.0 版本国际许可协议进行许可。
© . All rights reserved.