stefafafan の fa は3つです

"すてにゃん" こと id:stefafafan のブログです

Wordle の初手に使うと良さそうな単語を調べる

最近一部の界隈でWordleという英単語当てゲームが流行っています。

www.powerlanguage.co.uk

5文字の英単語を最大6回のチャンスで当てるというシンプルなゲームです。ただし適当な文字を打ち込んでも存在しない英単語だと弾かれます。1日1単語が出題されるため、SNS上でシェアしあって楽しむことができます。

初手で使う単語は何が良いのか

適当な単語を入れるとあってる文字もしくは位置が違うけど合ってる文字は色がついてヒントとして使えます。(逆に完全に外れている場合は黒色になるのでそれはそれでヒントとなります)。

ということは、初手で使う単語はこのヒントが最大限得られる単語を使えるとお得です。同じ文字が連続して使われている単語 (例: bloodとか)は論外です。

英単語といえば母音がよく使われているらしい。本当なんでしょうか。

en.wikipedia.org

本当っぽいですね。

ただ今回は「5文字の英単語」に限った話なのでちょっと割合は違うかもしれません。

5文字の英単語のリストがほしい

調べたらWordle作者のGitHubに単語リストがありました。はたしてこれをWordleにも使っているかは不明ですが、便利ですね。*1

github.com

word-list-raw.txt に単語がたくさん入っているので、手元にcloneしてきてまずは5文字の単語だけ抽出してみました。ついでに、アルファベットごとの数を以下のような雑なコマンドで数えてみました。

echo (echo -n "a: "; cat word-list-5-letters.txt | grep -c "a") >> alphabet-count.txt
echo (echo -n "b: "; cat word-list-5-letters.txt | grep -c "b") >> alphabet-count.txt
echo (echo -n "c: "; cat word-list-5-letters.txt | grep -c "c") >> alphabet-count.txt
echo (echo -n "d: "; cat word-list-5-letters.txt | grep -c "d") >> alphabet-count.txt
echo (echo -n "e: "; cat word-list-5-letters.txt | grep -c "e") >> alphabet-count.txt
echo (echo -n "f: "; cat word-list-5-letters.txt | grep -c "f") >> alphabet-count.txt
echo (echo -n "g: "; cat word-list-5-letters.txt | grep -c "g") >> alphabet-count.txt
echo (echo -n "h: "; cat word-list-5-letters.txt | grep -c "h") >> alphabet-count.txt
echo (echo -n "i: "; cat word-list-5-letters.txt | grep -c "i") >> alphabet-count.txt
echo (echo -n "j: "; cat word-list-5-letters.txt | grep -c "j") >> alphabet-count.txt
echo (echo -n "k: "; cat word-list-5-letters.txt | grep -c "k") >> alphabet-count.txt
echo (echo -n "l: "; cat word-list-5-letters.txt | grep -c "l") >> alphabet-count.txt
echo (echo -n "m: "; cat word-list-5-letters.txt | grep -c "m") >> alphabet-count.txt
echo (echo -n "n: "; cat word-list-5-letters.txt | grep -c "n") >> alphabet-count.txt
echo (echo -n "o: "; cat word-list-5-letters.txt | grep -c "o") >> alphabet-count.txt
echo (echo -n "p: "; cat word-list-5-letters.txt | grep -c "p") >> alphabet-count.txt
echo (echo -n "q: "; cat word-list-5-letters.txt | grep -c "q") >> alphabet-count.txt
echo (echo -n "r: "; cat word-list-5-letters.txt | grep -c "r") >> alphabet-count.txt
echo (echo -n "s: "; cat word-list-5-letters.txt | grep -c "s") >> alphabet-count.txt
echo (echo -n "t: "; cat word-list-5-letters.txt | grep -c "t") >> alphabet-count.txt
echo (echo -n "u: "; cat word-list-5-letters.txt | grep -c "u") >> alphabet-count.txt
echo (echo -n "v: "; cat word-list-5-letters.txt | grep -c "v") >> alphabet-count.txt
echo (echo -n "w: "; cat word-list-5-letters.txt | grep -c "w") >> alphabet-count.txt
echo (echo -n "x: "; cat word-list-5-letters.txt | grep -c "x") >> alphabet-count.txt
echo (echo -n "y: "; cat word-list-5-letters.txt | grep -c "y") >> alphabet-count.txt
echo (echo -n "z: "; cat word-list-5-letters.txt | grep -c "z") >> alphabet-count.txt

これで5文字の単語リストの中でそれぞれの文字ごとの件数がalphabet-count.txtにまとまりました。

最高の第一手が知りたい

コマンド技でなんとかするのは大変そうなのでGoでちょっとしたコードを書いてみました。

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
)

func main() {
        // 抽出した5文字の単語だけが入っているリストを読み込む
	file, err := os.Open("./word-list-5-letters.txt")
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

        // alphabet-count.txt で取得したalphabetごとの件数をmapとしてそのままここに定義
	var runeToOccurence = map[rune]uint16{
		[]rune("a")[0]: 11111,
		[]rune("b")[0]: 2222,
		[]rune("c")[0]: 12345,
		...
	}
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		word := scanner.Text()

                // 素朴に単語のruneでループすると blood のように o が2回カウントされてしまうので map に入れておく
		m := make(map[rune]uint16, len(word))
		for _, r := range word {
			m[r]++
		}
		score := 0
		for k := range m {
                        // alphabetごとの登場した回数をそのままスコアとして加算
			score += int(runeToOccurence[k])
		}
                // 単語とスコアをカンマ区切りで出力
		fmt.Printf("%s,%d\n", word, score)
	}

	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}
}

読めばわかると思いますが、出現回数を素朴にアルファベットごとのスコアということにして、単語ごとにその単語の点数を加算していって、最終的にCSV形式に出力しています。

これを例えばGoogleスプレッドシートに取り込んでソートしたら初手に最適な単語の候補がわかります。

2回目以降の単語

例えば1回目に ae を消化した場合、2回目はその ae を使っていない単語のリストで一番点数の高いものを選びたい。上記のスクリプトの中で a: 0点, e: 0点ということにして再度実行するとそれらを使わない単語が上位に入ってくるので、二つ目の単語の候補としてこういうのを使うと良いでしょう。

終わり

もともと同僚がWikipediaのLetter frequencyの記事を参考にこういう攻略方法を考えていたのをみていいなと思って自分でもちょっとやってみました。面白いですね。

ちなみにネタバレとかはしたくないので実際にどの文字や単語が点数高かったかはここでは書かないでおきます。

追記

もうちょっとコンピュータに色々がんばってもらいました

blog.stenyan.jp

*1:あとではてブのコメントで教えてもらったのですがWordleのJSの中に単語リストが直接書かれてました