|
|
@ -1,14 +1,15 @@ |
|
|
|
namespace WhiteRabbit |
|
|
|
namespace WhiteRabbit |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.Immutable; |
|
|
|
using System.Collections.Immutable; |
|
|
|
using System.Linq; |
|
|
|
using System.Linq; |
|
|
|
|
|
|
|
|
|
|
|
internal class StringsProcessor |
|
|
|
internal class StringsProcessor |
|
|
|
{ |
|
|
|
{ |
|
|
|
public StringsProcessor(string sourceString, int maxWordsCount) |
|
|
|
public StringsProcessor(byte[] sourceString, int maxWordsCount) |
|
|
|
{ |
|
|
|
{ |
|
|
|
var filteredSource = new string(sourceString.Where(ch => ch != ' ').ToArray()); |
|
|
|
var filteredSource = sourceString.Where(ch => ch != 32).ToArray(); |
|
|
|
this.VectorsConverter = new VectorsConverter(filteredSource); |
|
|
|
this.VectorsConverter = new VectorsConverter(filteredSource); |
|
|
|
this.VectorsProcessor = new VectorsProcessor( |
|
|
|
this.VectorsProcessor = new VectorsProcessor( |
|
|
|
this.VectorsConverter.GetVector(filteredSource).Value, |
|
|
|
this.VectorsConverter.GetVector(filteredSource).Value, |
|
|
@ -20,11 +21,11 @@ |
|
|
|
|
|
|
|
|
|
|
|
private VectorsProcessor VectorsProcessor { get; } |
|
|
|
private VectorsProcessor VectorsProcessor { get; } |
|
|
|
|
|
|
|
|
|
|
|
public IEnumerable<string> GeneratePhrases(IEnumerable<string> words) |
|
|
|
public IEnumerable<byte[]> GeneratePhrases(IEnumerable<byte[]> words) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Dictionary of vectors to array of words represented by this vector |
|
|
|
// Dictionary of vectors to array of words represented by this vector |
|
|
|
var formattedWords = words |
|
|
|
var formattedWords = words |
|
|
|
.Distinct() |
|
|
|
.Distinct(new ByteArrayEqualityComparer()) |
|
|
|
.Select(word => new { word, vector = this.VectorsConverter.GetVector(word) }) |
|
|
|
.Select(word => new { word, vector = this.VectorsConverter.GetVector(word) }) |
|
|
|
.Where(tuple => tuple.vector != null) |
|
|
|
.Where(tuple => tuple.vector != null) |
|
|
|
.Select(tuple => new { tuple.word, vector = tuple.vector.Value }) |
|
|
|
.Select(tuple => new { tuple.word, vector = tuple.vector.Value }) |
|
|
@ -40,7 +41,7 @@ |
|
|
|
.SelectMany(this.Flatten) |
|
|
|
.SelectMany(this.Flatten) |
|
|
|
.Select(stack => stack.ToArray()); |
|
|
|
.Select(stack => stack.ToArray()); |
|
|
|
|
|
|
|
|
|
|
|
return anagramsWords.Select(list => string.Join(" ", list)); |
|
|
|
return anagramsWords.Select(WordsToPhrase); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Converts e.g. pair of variants [[a, b, c], [d, e]] into all possible pairs: [[a, d], [a, e], [b, d], [b, e], [c, d], [c, e]] |
|
|
|
// Converts e.g. pair of variants [[a, b, c], [d, e]] into all possible pairs: [[a, d], [a, e], [b, d], [b, e], [c, d], [c, e]] |
|
|
@ -55,5 +56,23 @@ |
|
|
|
var newStack = phrase.Pop(out wordVariants); |
|
|
|
var newStack = phrase.Pop(out wordVariants); |
|
|
|
return this.Flatten(newStack).SelectMany(remainder => wordVariants.Select(word => remainder.Push(word))); |
|
|
|
return this.Flatten(newStack).SelectMany(remainder => wordVariants.Select(word => remainder.Push(word))); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private byte[] WordsToPhrase(byte[][] words) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
var result = new byte[words.Length + words.Sum(word => word.Length) - 1]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Buffer.BlockCopy(words[0], 0, result, 0, words[0].Length); |
|
|
|
|
|
|
|
var position = words[0].Length; |
|
|
|
|
|
|
|
for (var i = 1; i < words.Length; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
result[position] = 32; |
|
|
|
|
|
|
|
position++; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Buffer.BlockCopy(words[i], 0, result, position, words[i].Length); |
|
|
|
|
|
|
|
position += words[i].Length; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|