diff --git a/Blink3.Core/Extensions/WordleExtensions.cs b/Blink3.Core/Extensions/WordleExtensions.cs
index 316178d..12d0a88 100644
--- a/Blink3.Core/Extensions/WordleExtensions.cs
+++ b/Blink3.Core/Extensions/WordleExtensions.cs
@@ -14,8 +14,8 @@ public static class WordleExtensions
/// The word guess entered by a player.
public static void ProcessGuess(this Wordle wordle, WordleGuess guess)
{
- List correctIndices = [];
- List misplacedIndices = [];
+ ICollection correctIndices = [];
+ ICollection misplacedIndices = [];
guess.MarkCorrectLetters(wordle, correctIndices);
guess.MarkMisplacedLetters(wordle, correctIndices, misplacedIndices);
diff --git a/Blink3.Core/Extensions/WordleGuessExtensions.cs b/Blink3.Core/Extensions/WordleGuessExtensions.cs
index bb610d4..6e450ef 100644
--- a/Blink3.Core/Extensions/WordleGuessExtensions.cs
+++ b/Blink3.Core/Extensions/WordleGuessExtensions.cs
@@ -1,6 +1,8 @@
using Blink3.Core.Entities;
using Blink3.Core.Enums;
+// ReSharper disable SuggestBaseTypeForParameter
+
namespace Blink3.Core.Extensions;
///
@@ -39,27 +41,67 @@ public static void MarkMisplacedLetters(this WordleGuess guess, Wordle wordle,
{
string word = guess.Word;
string wordToGuess = wordle.WordToGuess;
- Dictionary checkedLettersCount = new(); // number of times a letter has been processed
- for (int i = 0; i < word.Length; i++)
- {
- char letter = word[i];
- if (guess.Letters[i].State == WordleLetterStateEnum.Correct) continue;
+ Dictionary checkedLettersCount = new();
+ Dictionary> charIndicesMap = GenerateCharIndicesMap(wordToGuess);
- checkedLettersCount.TryAdd(letter, 0);
- int letterOccurrences = wordToGuess.AllIndexesOf(letter).Count;
+ for (int i = 0; i < word.Length; i++)
+ MarkSpecificLetter(guess, word, correctIndices, misplacedIndices, checkedLettersCount, charIndicesMap, i);
+ }
- if (checkedLettersCount[letter] >= letterOccurrences) continue;
- checkedLettersCount[letter]++;
+ ///
+ /// Generates a character indices map for a given word.
+ ///
+ /// The word to generate the character indices map for.
+ /// A dictionary with characters as keys and lists of indices as values.
+ private static Dictionary> GenerateCharIndicesMap(string wordToGuess)
+ {
+ Dictionary> charIndicesMap = new(wordToGuess.Length);
- List indices = wordToGuess.AllIndexesOf(letter);
- foreach (int index in indices.Where(index =>
- !(correctIndices.Contains(index) || misplacedIndices.Contains(index))))
+ for (int i = 0; i < wordToGuess.Length; i++)
+ {
+ if (!charIndicesMap.TryGetValue(wordToGuess[i], out List? value))
{
- guess.Letters[i].State = WordleLetterStateEnum.Misplaced;
- misplacedIndices.Add(index);
- break;
+ value = new List();
+ charIndicesMap[wordToGuess[i]] = value;
}
+
+ value.Add(i);
}
+
+ return charIndicesMap;
+ }
+
+ ///
+ /// Marks a specific letter in the WordleGuess object based on given parameters.
+ ///
+ /// The WordleGuess object
+ /// The word from the guess
+ /// The collection of correct indices
+ /// The collection of misplaced indices
+ /// The dictionary of checked letters count
+ /// The dictionary mapping characters to indices
+ /// The index of the letter to mark
+ private static void MarkSpecificLetter(WordleGuess guess, string word, ICollection correctIndices,
+ ICollection misplacedIndices, Dictionary checkedLettersCount,
+ Dictionary> charIndicesMap, int i)
+ {
+ char letter = word[i];
+ if (guess.Letters[i].State == WordleLetterStateEnum.Correct) return;
+
+ checkedLettersCount.TryAdd(letter, 0);
+ checkedLettersCount[letter]++;
+
+ if (!charIndicesMap.TryGetValue(letter, out List? value)) return;
+
+ foreach (int index in value.Where(index =>
+ !correctIndices.Contains(index) && !misplacedIndices.Contains(index)))
+ {
+ guess.Letters[i].State = WordleLetterStateEnum.Misplaced;
+ misplacedIndices.Add(index);
+ break;
+ }
+
+ if (checkedLettersCount[letter] >= value.Count) charIndicesMap.Remove(letter);
}
}
\ No newline at end of file