Exercise A3
Wordle is a popular online word game Wordle. There are instructions given at the official site for Wordle but in essence it is a word guessing game in which each guess is marked by indicating which letters of your guess match a secret answer. A Green mark indicates that you have found a correct letter in the correct position in the secret word. A Yellow mark indicates that you have found a correct letter but in an incorrect position relative to the secret word. A Grey mark indicates that the given letter does not appear in the secret word at all. Be careful of duplicate letters: a letter that is guessed twice may be marked once as Green or Yellow and once as Grey if there is only a single occurrence of that letter in the secret word. In particular, Green markings take priority over Yellow markings and Yellow markings have a priority in the guess reading from Left to Right.
Given the datatypes
data Check = Green | Yellow | Grey deriving (Eq,Show,Read)
type Marking = [(Char,Check)]
write a function markGuess :: String -> String -> Marking that takes the secret word to be guessed and a guess of the same length. The function should return a marking according to the Wordle rules. The order of the returned marking matters and should satisfy
map fst (markGuess secret guess) == guess
An example marking showing the marking priorities is
markGuess “aaabb” “bbxxb”
should return
[(‘b’,Yellow),(‘b’,Grey),(‘x’,Grey),(‘x’,Grey),(‘b’,Green)]
The final ‘b’ in the guess is marked Green because it is correctly placed in the secret word. The first ‘b’ in the guess is marked Yellow because there is a second occurrence of ‘b’ in the secret word in a different position. The second ‘b’ in the guess is marked Grey because there is no third occurrence of ‘b’ in the secret word.
Note that your solution should work with strings of any length but should report an error where the two given strings are of different length.
Hint: A reasonable strategy is to write a helper function that finds the characters marked Green first. Then feed the result of that helper function in to another helper function that finds the Yellow markings.
Exercise A4
In this question we return to Wordle as in Exercise A3 above. In the Wordle game, players are allowed a sequence of guesses and use the markings from each of these guesses collectively to gather information about the hidden word. In this exercise we will write a function that collates the information presented in the markings to obtain a State value that represents knowledge so far. A State comprises a 4-tuple representing:
Letters known to be contained in the secret (multiplicity matters, order ignored)
Letters known to be not contained in the secret (multiplicity and order ignored)
Known exact placements contained in the secret
Known exclusions at placements in the secret (multiplicity and order ignored)
The first two of these components should be clear, for the third, we use a hyphen to represent an unknown character and letters to represent the known character placements. For example, “s-e-e” represents that the answer begins with character ‘s’ and there are two occurences of character ‘e’ in position 3 and 5. These correspond to the Green markings.
The fourth component of a state, the known exclusions, is represented as a list of String. The list has the same length as the secret word (and markings) and, for each index in the exclusions list, represents the characters that appear in the answer word but cannot appear at that same index in the secret word. These correspond to the Yellow and possibly Grey markings.
Using the data types
data Check = Green | Yellow | Grey deriving (Eq,Show,Read)
type Marking = [(Char,Check)]
type State = (String,String,String,[String])
Write a function
collateMarking :: [Marking] -> State
that, given a list of marked wordle guesses, returns the corresponding state information.
For example, given the markings
[[(‘r’,Grey),(‘o’,Grey),(‘b’,Grey),(‘i’,Yellow),(‘n’,Yellow)],
[(‘r’,Grey),(‘a’,Grey),(‘v’,Grey),(‘e’,Yellow),(‘n’,Yellow)],
[(‘s’,Green),(‘t’,Grey),(‘o’,Grey),(‘r’,Grey),(‘k’,Grey)],
[(‘s’,Green),(‘w’,Grey),(‘i’,Green),(‘f’,Grey),(‘t’,Grey)]]
then the collateMarking function should return e.g.
(“ines”,”robavtkwf”,”s-i–“,[“”,””,””,”ie”,”n”])
Note that you are not expected to infer knowledge over the state beyond what is represented in the markings directly. For example if we have a marking
[[(‘c’,Yellow),(‘c’,Grey),(‘x’,Grey),(‘c’,Grey),(‘c’,Grey)]]
we could possibly infer that ‘c’ must be in the third positition. Your function is not expected to make this sort of inference and should simply return the state
(“c”,”x”,”—–“,[“c”,”c”,””,”c”,”c”])
Hint: Write four functions that return each component separately. For the third and fourth components regarding placement of the letters you may find it useful to work with the transpose of the Markings list. See Data.List.transpose for details.