146 lines
5.0 KiB
C#
146 lines
5.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using C5;
|
|
|
|
namespace Core
|
|
{
|
|
public class DictionarySearcher
|
|
{
|
|
static HashBag<char> GetLettersBag(string letters)
|
|
{
|
|
var hashBag = new HashBag<char>();
|
|
hashBag.AddAll(letters.Canonicalize().ToCharArray());
|
|
return hashBag;
|
|
}
|
|
|
|
readonly struct DictWord
|
|
{
|
|
public readonly string Word;
|
|
public readonly HashBag<char> CharBag;
|
|
|
|
public DictWord(string word) : this()
|
|
{
|
|
Word = word;
|
|
CharBag = GetLettersBag(word);
|
|
}
|
|
|
|
public static implicit operator DictWord(string s) => new DictWord(s);
|
|
public static implicit operator string(DictWord dw) => dw.Word;
|
|
|
|
public char[] ToCharArray() => Word.ToCharArray();
|
|
public bool Contains(char c) => Word.Contains(c);
|
|
|
|
public int Length => Word.Length;
|
|
public bool StartsWith(string s) => Word.StartsWith(s);
|
|
|
|
public string Substring(int startIndex) => Word.Substring(startIndex);
|
|
}
|
|
|
|
private class DictWordComprer : IComparer<DictWord>
|
|
{
|
|
private readonly IComparer<string> _comparer;
|
|
public DictWordComprer(IComparer<string> comparer)
|
|
{
|
|
_comparer = comparer;
|
|
}
|
|
public int Compare(DictWord x, DictWord y)
|
|
{
|
|
return _comparer.Compare(x, y);
|
|
}
|
|
}
|
|
|
|
private readonly List<DictWord> _dictionary;
|
|
|
|
public DictionarySearcher(int? characterCount = null)
|
|
: this(@"TWL06.txt", characterCount)
|
|
{
|
|
}
|
|
|
|
public DictionarySearcher(string filename, int? characterCount = null)
|
|
: this(filename.GetFileLines(), characterCount)
|
|
{
|
|
}
|
|
|
|
public DictionarySearcher(IEnumerable<string> words, int? characterCount = null)
|
|
{
|
|
_dictionary = new List<DictWord>();
|
|
foreach (var word in words)
|
|
{
|
|
if (characterCount != null && word.Length != characterCount)
|
|
continue;
|
|
var w = word.Canonicalize();
|
|
_dictionary.Add(w);
|
|
}
|
|
}
|
|
|
|
public System.Collections.Generic.IList<string> GetWords()
|
|
{
|
|
return _dictionary.Select(d => d.Word).ToList();
|
|
}
|
|
|
|
public void SortDictionary(IComparer<string> comparer)
|
|
{
|
|
_dictionary.Sort(new DictWordComprer(comparer));
|
|
}
|
|
|
|
public IEnumerable<string> FindWords(string letters)
|
|
{
|
|
var hashBag = new HashBag<char>();
|
|
hashBag.AddAll(letters.Canonicalize().ToCharArray());
|
|
return from w in _dictionary
|
|
where hashBag.ContainsAll(w.ToCharArray())
|
|
select w.Word;
|
|
}
|
|
|
|
public IEnumerable<string> FindWords(string includeLetters, string excludeLetters)
|
|
{
|
|
var excludeBag = GetLettersBag(excludeLetters);
|
|
|
|
return from w in _dictionary
|
|
where w.CharBag.ContainsAll(includeLetters.Canonicalize())
|
|
&& excludeBag.All(c => !w.Contains(c))
|
|
select w.Word;
|
|
}
|
|
|
|
public IEnumerable<string> FindWords(string includeLetters, string excludeLetters, int? len)
|
|
{
|
|
return
|
|
from w in FindWords(includeLetters, excludeLetters)
|
|
where !len.HasValue || w.Length == len.Value
|
|
select w;
|
|
}
|
|
|
|
public IEnumerable<Tuple<string, string>> MatchingWords(string firstSelector, string secondSelector)
|
|
{
|
|
var firstSet = _dictionary.Where(w => w.StartsWith(firstSelector.Canonicalize())).GroupBy(w => w.Length)
|
|
.ToList();
|
|
var secondSet = _dictionary.Where(w => w.StartsWith(secondSelector.Canonicalize())).GroupBy(w => w.Length)
|
|
.ToList();
|
|
|
|
return from len in firstSet.Select(g => g.Key)
|
|
from w1 in firstSet.Where(g => g.Key == len)
|
|
from w2 in secondSet.Where(g => g.Key == len)
|
|
from ww1 in w1
|
|
from ww2 in w2
|
|
where ww1.Substring(1).Equals(ww2.Substring(1))
|
|
select Tuple.Create(ww1.Word, ww2.Word);
|
|
}
|
|
/*public Dictionary<char, int>[] GetLetterPositionFreq(int wordLen)
|
|
{
|
|
var ws = _dictionary.Where(w => w.Length == wordLen).ToList();
|
|
|
|
var freqList = new Dictionary<char, int>[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.Word[i] == c)
|
|
);
|
|
}
|
|
|
|
return freqList;
|
|
}*/
|
|
}
|
|
} |