Wordle単語を辞書から正規表現一発で検索する
Wordleとは
説明は不要だと思いますが今世界中で流行っている単語当てゲームです。
辞書から単語検索
自動で解くソルバーは作らずに、辞書から候補の単語を検索するものを考えようと思います。
以下の辞書を利用させてもらいました。
正規表現
上記の辞書を加工して単語が単純に列挙されているものを作ります。そこから検索していくことを考えます。
文字列を検索するならやはり正規表現を使うだろうということで正規表現1発で候補の単語を絞っていきます。
肯定先読み
(?=pattern)
の表現を肯定先読みと呼びます。これはパターンが一致した場合にそのパターンの部分文字列とマッチするのではなく、部分文字列の先頭位置にマッチします。以下にわかりやすい説明が書かれていました。
例えば
^(?=.*a)(?=.*b).*$
という正規表現に一致する文字列を考えると以下のような解釈になります。
- 先頭から末尾までで(何か0文字以上)aというパターンが存在し、かつ部分文字列の先頭にマッチするので、今の場合^の行の先頭にマッチ
- 行の先頭にマッチしているので同じく行の先頭から末尾までで(何か0文字以上)bというパターンが存在しかつ行の先頭にマッチ
- 何か0文字以上
わかりづらいですが、つまりaが含まれるかつbが含まれる0文字以上の行ということになります。
これを用いると検索したいパターンのANDが取れるのでこれを使いまくります。同様のもので否定先読みも存在します。
必要な正規表現のパターン
以下例としてappleが正解とします。
緑文字
緑の場合は位置と文字が正しいので以下のような条件となります。
(?=a..l.)
黄文字
黃の場合は2つの情報が得られるので条件も2つ出来ます。
- その文字は含まれている
- その文字はその位置ではない
(?=.*p) // pが含まれる
(?!p....) // pは先頭ではない
黒文字
黒は含まれないので以下の条件です。
(?!.*b)
合成
各文字の条件が出揃ったら以下のように条件を列挙すれば得られた情報で文字列を絞ることが出来ます。
^(?=a..l.)(?=.*p)(?!p....)(?!.*b)[a-z]{5}$
ちなみに上記の正規表現で辞書データを開いたvscodeで検索してみるとappleを含む5件に絞られました。
まとめ
正規表現一発といっても条件を列挙しただけなのでエレガントさはありませんw
ただシンプルに条件を列挙するだけで目的の文字がほとんど一瞬で検索出来るのは改めて正規表現の強力さを感じます。
試しにコマンドラインで検索出来るプログラムを書いてみたので攻略のお供に使ってみてください。
Discussion