We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
This is a little piece of work I did on the Wordle. I was having an issue with the feedback on the words not being correct. I wanted to make sure that a letter only gets a yellow if it’s in the word, not already in the right position, and not already counted for.
Initial setup:
letter_count =
letter_count(word)
|> IO.inspect(label: "Letter Count")
Enum.map(index_guess, fn {letter, index} ->
cond do
{letter, index} in index_word ->
letter_count = Map.update!(letter_count, letter, fn count -> count - 1 end)
|> IO.inspect(label: "green")
[letter, "bg-green-400"]
letter in String.split(word, "", trim: true) and letter_count[letter] > 0 ->
letter_count = Map.update!(letter_count, letter, fn count -> count - 1 end)
|> IO.inspect(label: "yellow")
[letter, "bg-yellow-300"]
true ->
[letter, "bg-gray-300"]
end
end)
This approach didn’t work for words like "Tolls" when entering "Torts" — it would output 1 green t and 1 yellow t.
Solution: Two Passes
First pass – set greens:
{green_results, letter_count_after_greens} =
Enum.map_reduce(index_guess, letter_count, fn {letter, index}, letter_count ->
if {letter, index} in index_word do
letter_count = Map.update!(letter_count, letter, fn count -> count - 1 end)
IO.inspect(letter_count, label: "green update")
{[letter, "bg-green-400"], letter_count}
else
{[{letter, index}], letter_count}
end
end)
Second pass – set yellows and grays:
{final_results, _final_letter_count} =
Enum.map_reduce(green_results, letter_count_after_greens, fn
[{letter, index}], letter_count ->
if letter in String.split(word, "", trim: true) and letter_count[letter] > 0 do
letter_count = Map.update!(letter_count, letter, fn count -> count - 1 end)
IO.inspect(letter_count, label: "yellow update")
{[letter, "bg-yellow-300"], letter_count}
else
{[letter, "bg-gray-300"], letter_count}
end
# Already green
[letter, color], letter_count ->
{[letter, color], letter_count}
end)
Explanation
-
First pass: We use
Enum.map_reduceinstead ofEnum.mapsoletter_countcan be updated. Any letter in the correct position (green) is handled here. Non-green letters are kept as{letter, index}for the next pass. -
Second pass:
green_resultscontains two types:-
[letter, color]→ already green -
{letter, index}→ not yet colored
We use pattern matching on the function inputs to handle each case.
-
[letter, color]→ keep the same output, maintainletter_count -
{letter, index}→ check if it should be yellow or gray
-
The tricky part was keeping letter_count updated while still passing the correct information to the next Enum. This two-pass approach solves that elegantly while reusing most of the original code.