WordleHelp.jar helps ordinary mortals, such as myself, to solve Wordle puzzles. The original Wordle by Josh Wardle is located here, although I tested my code against Wordle Unlimited.
WordleHelp uses Java's regexs to apply a series of grep-like filters to a text file containing all the lowercase 5-letter words in en-US-large.txt, available from http://wordlist.sourceforge.net.
The compiled WordleHelp, its source code, and the dictionary, are packaged in the JAR file. Execute it from the command line, supplying two string patterns. Usage details are available by calling the JAR with no arguments:
inPos supplies information about the position of a letter (i.e. a Wordle green box) You can also use [^ letter(s)] to exclude letter(s) from a position, but still have them appear elsewhere in the word (i.e. a Wordle yellow box).
notInWord lists the letters that do not appear in the word (i.e. Wordle gray boxes).
WordleHelp's output is a sequence of words that satisfy the two strings supplied by the user, sorted into descending order by the number of vowels in each word. Also the most commonly occurring letter in each position of the words is reported.
The easiest way to understand how to use WordleHelp is to examine the progress of the two Wordle games shown below.
Row 1. The starting word "arose" produces a Wordle green and four gray boxes. This let me set WordleHelp's inPos string to "...s." and the notInWord string to "aroe". Calling WordleHelp with these patterns produced 29 possiblities (the full dictionary holds over 16,000 words).
Row 2. I chose "blush" for my second guess because it's a common word, uses a different vowel than 'u', and sports a different mix of consonants. In retrospect, I should have paid more attention to the list of common letters supplied by WordleHelp, which suggested using 'i' in the third position. Wordle reports one green and four grays, but the grays are new letters. This allowed me to extend notInWord to eight characters, which let WordleHelp generate a list of eight words.
Row 3. I chose poorly from the WordleHelp words, and received one green and four grays from Wordle. However, three of those gray letters were new, so I could extend notInWord to "aroebluhgyp". Supplying this to WordleHelp reduced the possibilities to three words.
Row 1. The starting word "arose" produces two Wordle yellows, which were added to inPos as ".[^r]..[^e]", denoting that 'r' and 'e' are in the word but not at positions 2 and 5. The three gray boxes were added to notInWord as "aos". WordleHelp then produced over 200 matches. You may note that the words are not in alphabetical order. The list is sorted so words with the most vowels are placed first. This is useful for choosing the next word, which is likely to contain another vowel along with 'e'. In addition, the list of common words strongly suggests that the last two letters of the word are 'e' and 'r'.
Row 2."biker" was a good choice, producing two greens, a yellow, and two gray boxes. inPos becomes ".[^ri].er", reflecting that 'e' and 'r' are in their correct positions. Also note that the excluded letters in position 2 include the letter from this row's yellow box and the one in row 1. notInWord also grows to include the two new gray letters from this row along with the three gray letters of row 1. Calling WordleHelp with these strings produces eight possibilities, and a suggestion that the letter in position 1 should be 'i'.
Row 3. Rather stupidly, instead of choosing a word beginning with 'i', I went for "flier". It generated two new gray letters, and a yellow box for 'i', which meant that 'i' had to be in position 1. This realization let me change inPos to "i[^ri][^i]er", and notInWord was extended to "aosbkfl". WordleHelp suggested three words, with "inner" the most common one.
The source code is in WordleHelp.jar, and essentially uses Java's regular expression functionality (from the java.util.regex package) to implement a series of grep-like calls.
For example, the WordleHelp "...s." "aroe" strings from the first row of Game 1 correspond to the grep calls:
The WordleHelp ".[^ri].er." "aosbk" strings from the second row of Game 2 correspond to the grep calls:
The translation to grep calls falls into three parts. inPos becomes the first grep call and a series of greps for each of the alphabetical characters used in inPos. notInWord becomes a series of 'negative' greps (i.e. using the "-v" option), with one call for each letter in notInWord.
The Java version has two slightly tricky features. The first is that inPos (e.g. ".[^ri].er") is used in two ways which mirror the approach above. It's employed to execute a pattern match akin to "^.[^ri].er$" which includes and excludes letters from specified positions. In addition, the alphabetical characters from inPos are used to filter the matching words so that those letters appear somewhere in every word. This is equivalent to the sequence of simple 'positive' greps in the two examples above.
Another aspect of Java regexs is that they don't support the equivalent of grep's "-v" for negating the matching lines. However, this functionality can be replicated by using negative lookaheads in the patterns. This means that each "-v" grep in the examples above can be implemented by a Java regex equivalent to "^((?!x).)*$" where x is the letter to be excluded. For example, "grep -v 'a'" is rephrased as "grep '^((?!a).)*$'. As a longer example, consider:
This pipe excludes all words containing 'a', 'e', 'i', 'o', and 'u' by utilizing five negative lookahead grep calls.