using System; using System.Collections.Generic; using System.Linq; namespace Core { public class LetterPositionFrequency : IComparer { private readonly Dictionary[] _letterFrequencies; private LetterPositionFrequency(Dictionary[] letterFrequencies) { _letterFrequencies = letterFrequencies; } public LetterPositionFrequency(DictionarySearcher dictionarySearcher, int wordLen) : this(GetLetterPositionFreq(dictionarySearcher.GetWords(), wordLen)) { } public LetterPositionFrequency(WordleUtil wordleUtil, int wordLen) : this(GetLetterPositionFreq(wordleUtil.Words, wordLen)) { } public LetterPositionFrequency(IList words, int wordLen) : this(GetLetterPositionFreq(words, wordLen)) { } public static Dictionary[] GetLetterPositionFreq(IList words, int wordLen) { var ws = words.Where(w => w.Length == wordLen).ToList(); var freqList = new Dictionary[wordLen]; for (var i = 0; i < wordLen; i++) { var letters = Enumerable.Range(0, 26).Select(r => Convert.ToChar('A' + r)); freqList[i] = letters.ToDictionary(c => c, c => ws.Count(w => w[i] == c) ); } return freqList; } public IEnumerable> ScoreWords(IEnumerable words, WordleUtil wordleUtil = null) { return from word in words let score = word.Select((c, i) => _letterFrequencies[i][c]).Sum() select wordleUtil != null ? Tuple.Create(word, Convert.ToInt32(wordleUtil.FactorRepeatedLetters(word, score))) : Tuple.Create(word, score) ; } public List SortWords(IEnumerable words, WordleUtil wordleUtil = null) { return ScoreWords(words, wordleUtil) .OrderByDescending(w => w.Item2) .Select(w => w.Item1) .ToList(); } private int ScoreWord(string word) { return word.Select((c, i) => _letterFrequencies[i][c]).Sum(); } public int Compare(string x, string y) { return ScoreWord(y).CompareTo(ScoreWord(x)); } } }