用 Linux 命令行解決 Wordle 問(wèn)題
我最近有點(diǎn)迷戀上了一個(gè)在線單詞猜謎游戲,在這個(gè)游戲中,你有六次機(jī)會(huì)來(lái)猜一個(gè)隨機(jī)的五個(gè)字母的單詞。這個(gè)詞每天都在變化,而且你每天只能玩一次。每次猜測(cè)后,你猜測(cè)中的每個(gè)字母都會(huì)被高亮顯示:灰色表示該字母沒(méi)有出現(xiàn)在神秘單詞中,黃色表示該字母出現(xiàn)在單詞中,但不在那個(gè)位置,綠色表示該字母出現(xiàn)在單詞中的那個(gè)正確位置。
下面是你如何使用 Linux 命令行來(lái)幫助你玩像 Wordle 這樣的猜測(cè)游戲。我用這個(gè)方法來(lái)幫助我解決 1 月 6 日的謎題:
第一次嘗試
Linux 系統(tǒng)在 /usr/share/dict/words 文件中保存了一個(gè)單詞詞典。這是一個(gè)很長(zhǎng)的純文本文件。我的系統(tǒng)的單詞文件里有超過(guò) 479,800 個(gè)條目。該文件既包含純文本,也包含專(zhuān)有名詞(名字、地點(diǎn)等等)。
為了開(kāi)始我的第一次猜測(cè),我只想得到一個(gè)長(zhǎng)度正好是五個(gè)字母的純文本詞的列表。要做到這一點(diǎn),我使用這個(gè) grep 命令:
$ grep '^[a-z][a-z][a-z][a-z][a-z]$' /usr/share/dict/words > myguess
grep 命令使用正則表達(dá)式來(lái)進(jìn)行搜索。你可以用正則表達(dá)式做很多事情,但為了幫助我解決 Wordle 問(wèn)題,我只需要基本的東西。^ 表示一行的開(kāi)始,$ 表示一行的結(jié)束。在兩者之間,我指定了五個(gè) [a-z] 的實(shí)例,表示從 a 到 z 的任何小寫(xiě)字母。
我還可以使用 wc 命令來(lái)查看我的可能單詞列表,“只有” 15,000 個(gè)單詞:
$ wc -l myguess
15034 myguess
從這個(gè)列表中,我隨機(jī)挑選了一個(gè)五個(gè)字母的單詞:acres。a 被設(shè)置為黃色,意味著該字母存在于神秘單詞的某處,但不在第一位置。其他字母是灰色的,所以我知道它們并不存在于今天的單詞中。
acres word attempt
第二次嘗試
對(duì)于我的下一個(gè)猜測(cè),我想得到一個(gè)包含 a 的所有單詞的列表,但不是在第一位置。我的列表也不應(yīng)該包括字母 c、r、e 或 s。讓我們把這個(gè)問(wèn)題分解成幾個(gè)步驟。
為了得到所有帶 a 的單詞的列表,我使用 fgrep(固定字符串 grep)命令。fgrep 命令也像 grep 一樣搜索文本,但不使用正則表達(dá)式:
$ fgrep a myguess > myguess2
這使我的下一個(gè)猜測(cè)的可能列表從 15,000 個(gè)字下降到 6,600 個(gè)字:
$ wc -l myguess myguess2
15034 myguess
6634 myguess2
21668 total
但是這個(gè)單詞列表中的第一個(gè)位置也有字母 a,這是我不想要的。游戲已經(jīng)表明字母 a 存在于其他位置。我可以用 grep 修改我的命令,以尋找在第一個(gè)位置包含其他字母的詞。這就把我可能的猜測(cè)縮小到了 5500 個(gè)單詞:
$ wc -l myguess myguess2
15034 myguess
6634 myguess2
21668 total
但我知道這個(gè)神秘的詞也不包括字母 c、r、e 或 s。我可以使用另一個(gè) grep 命令,在搜索中省略這些字母:
$ fgrep a myguess | grep '^[b-z]' | grep -v '[cres]' > myguess2
$ wc -l myguess myguess2
15034 myguess
1257 myguess2
16291 total
-v 選項(xiàng)意味著反轉(zhuǎn)搜索,所以 grep 將只返回不符合正則表達(dá)式 [cres] 或單列字母 c、r、e 或 s 的行。有了這個(gè)額外的 grep 命令,我把下一個(gè)猜測(cè)的范圍大大縮小到只有 1200 個(gè)可能的單詞,這些單詞在某處有一個(gè) a,但不在第一位置,并且不包含 c、r、e、或 s。
在查看了這個(gè)列表后,我決定嘗試一下 balmy 這個(gè)詞。
balmy word attempt
第三次嘗試
這一次,字母 b 和 a 被高亮顯示為綠色,意味著我把這些字母放在了正確的位置。字母 l 是黃色的,所以這個(gè)字母存在于單詞的其他地方,但不是在那個(gè)位置。字母 m 和 y 是灰色的,所以我可以從我的下一個(gè)猜測(cè)中排除這些。
為了確定下一個(gè)可能的單詞列表,我可以使用另一組 grep 命令。我知道這個(gè)詞以 ba 開(kāi)頭,所以我可以從這里開(kāi)始搜索:
$ grep '^ba' myguess2 > myguess3
$ wc -l myguess3
77 myguess3
這只有 77 個(gè)詞! 我可以進(jìn)一步縮小范圍,尋找除第三位外還包含字母 l 的詞:
$ grep '^ba[^l]' myguess2 > myguess3
$ wc -l myguess3
61 myguess3
方括號(hào) [^l] 內(nèi)的 ^ 表示不是這個(gè)字母列表,即不是字母 l。這使我的可能單詞列表達(dá)到 61 個(gè),并非所有的單詞都包含字母 l,我可以用另一個(gè) grep 搜索來(lái)消除這些單詞:
$ grep '^ba[^l]' myguess2 | fgrep l > myguess3
$ wc -l myguess3
10 myguess3
這些詞中有些可能包含字母 m 和 y,而這些字母并不在今天的神秘詞中。我可以再進(jìn)行一次反轉(zhuǎn) grep 搜索,將它們從我的猜測(cè)列表中刪除:
$ grep '^ba[^l]' myguess2 | fgrep l | grep -v '[my]' > myguess3
$ wc -l myguess3
7 myguess3
我的可能的單詞列表現(xiàn)在非常短,只有七個(gè)單詞!
我選擇 banal 作為我下一次猜測(cè)的可能的詞,而這恰好是正確的。
$ cat myguess3
babul
bailo
bakal
bakli
banal
bauld
baulk
我選擇 banal 作為我下一次猜測(cè)的可能的詞,而這恰好是正確的。
banal word attempt
正則表達(dá)式的力量
Linux 的命令行提供了強(qiáng)大的工具來(lái)幫助你完成實(shí)際工作。grep 和 fgrep 命令在掃描單詞列表方面提供了極大的靈活性。對(duì)于一個(gè)基于單詞的猜測(cè)游戲,grep 幫助識(shí)別了一個(gè)包含 15000 個(gè)可能的單詞的列表。在猜測(cè)并知道哪些字母出現(xiàn)在神秘的單詞中,哪些沒(méi)有,grep 和 fgrep 幫助將選項(xiàng)縮小到 1200 個(gè)單詞,然后只剩下 7 個(gè)單詞。這就是命令行的力量。