Compare commits

...

2 Commits

  1. 1
      WhiteRabbit/App.config
  2. 11
      WhiteRabbit/Program.cs
  3. 3
      WhiteRabbit/StringsProcessor.cs
  4. 38
      WhiteRabbit/VectorsProcessor.cs

@ -6,6 +6,7 @@
<appSettings>
<add key="SourcePhrase" value="poultry outwits ants" />
<add key="MaxWordsInPhrase" value="5" />
<add key="AllowWordsReuse" value="false" />
<add key="ExpectedHashes" value="e4820b45d2277f3844eac66c903e84be,23170acc097c24edb98fc5488ab033fe,665e5bcb0c20062fe8abaaf4628bb154"/>
</appSettings>
</configuration>

@ -27,6 +27,7 @@
var sourceChars = ToOrderedChars(sourcePhrase);
var maxWordsInPhrase = int.Parse(ConfigurationManager.AppSettings["MaxWordsInPhrase"]);
var allowWordsReuse = bool.Parse(ConfigurationManager.AppSettings["AllowWordsReuse"]);
var expectedHashesAsVectors = ConfigurationManager.AppSettings["ExpectedHashes"]
.Split(',')
@ -40,6 +41,7 @@
var processor = new StringsProcessor(
Encoding.ASCII.GetBytes(sourcePhrase),
maxWordsInPhrase,
allowWordsReuse,
ReadInput());
Console.WriteLine($"Initialization complete; time from start: {stopwatch.Elapsed}");
@ -51,13 +53,14 @@
sourceChars == ToOrderedChars(Encoding.ASCII.GetString(phraseBytes)),
$"StringsProcessor produced incorrect anagram: {Encoding.ASCII.GetString(phraseBytes)}");
var hashVector = ComputeHashVector(phraseBytes);
Console.WriteLine(Encoding.ASCII.GetString(phraseBytes));
/*var hashVector = ComputeHashVector(phraseBytes);
if (Array.IndexOf(expectedHashesAsVectors, hashVector) >= 0)
{
var phrase = Encoding.ASCII.GetString(phraseBytes);
var hash = VectorToHexadecimalString(hashVector);
Console.WriteLine($"Found phrase for {hash}: {phrase}; time from start is {stopwatch.Elapsed}");
}
}*/
#if DEBUG
anagramsBag.Add(Encoding.ASCII.GetString(phraseBytes));
@ -113,6 +116,10 @@
string line;
while ((line = Console.ReadLine()) != null)
{
if (line.Length == 1 && line != "a" && line != "i")
{
continue;
}
yield return Encoding.ASCII.GetBytes(line);
}
}

@ -8,7 +8,7 @@
{
private const byte SPACE = 32;
public StringsProcessor(byte[] sourceString, int maxWordsCount, IEnumerable<byte[]> words)
public StringsProcessor(byte[] sourceString, int maxWordsCount, bool allowWordsReuse, IEnumerable<byte[]> words)
{
var filteredSource = sourceString.Where(ch => ch != SPACE).ToArray();
this.NumberOfCharacters = filteredSource.Length;
@ -29,6 +29,7 @@
this.VectorsProcessor = new VectorsProcessor(
this.VectorsConverter.GetVector(filteredSource).Value,
maxWordsCount,
allowWordsReuse,
vectorsToWords.Select(tuple => tuple.vector).ToArray());
}

@ -17,7 +17,7 @@
PrecomputedPermutationsGenerator.HamiltonianPermutations(0);
}
public VectorsProcessor(Vector<byte> target, int maxVectorsCount, Vector<byte>[] dictionary)
public VectorsProcessor(Vector<byte> target, int maxVectorsCount, bool allowWordsReuse, Vector<byte>[] dictionary)
{
if (Enumerable.Range(0, Vector<byte>.Count).Any(i => target[i] > MaxComponentValue))
{
@ -27,6 +27,7 @@
this.Target = target;
this.MaxVectorsCount = maxVectorsCount;
this.AllowWordsReuseAddendum = allowWordsReuse ? 0 : 1;
this.Dictionary = ImmutableArray.Create(FilterVectors(dictionary, target).ToArray());
}
@ -34,6 +35,8 @@
private int MaxVectorsCount { get; }
private int AllowWordsReuseAddendum { get; }
private ImmutableArray<VectorInfo> Dictionary { get; }
// Produces all sequences of vectors with the target sum
@ -43,7 +46,14 @@
public ParallelQuery<int[]> GenerateSequences()
#endif
{
return GenerateUnorderedSequences(this.Target, GetVectorNorm(this.Target, this.Target), this.MaxVectorsCount, this.Dictionary, 0)
var unorderedSequences = GenerateUnorderedSequences(
this.Target,
GetVectorNorm(this.Target, this.Target),
this.MaxVectorsCount,
this.Dictionary,
0,
this.AllowWordsReuseAddendum);
return unorderedSequences
#if !SINGLE_THREADED
.AsParallel()
#endif
@ -81,7 +91,7 @@
// In every sequence, next vector always goes after the previous one from dictionary.
// E.g. if dictionary is [x, y, z], then only [x, y] sequence could be generated, and [y, x] will never be generated.
// That way, the complexity of search goes down by a factor of MaxVectorsCount! (as if [x, y] does not add up to a required target, there is no point in checking [y, x])
private static IEnumerable<ImmutableStack<int>> GenerateUnorderedSequences(Vector<byte> remainder, int remainderNorm, int allowedRemainingWords, ImmutableArray<VectorInfo> dictionary, int currentDictionaryPosition)
private static IEnumerable<ImmutableStack<int>> GenerateUnorderedSequences(Vector<byte> remainder, int remainderNorm, int allowedRemainingWords, ImmutableArray<VectorInfo> dictionary, int currentDictionaryPosition, int dictionaryPositionAddendum)
{
if (allowedRemainingWords > 1)
{
@ -96,7 +106,7 @@
var currentVectorInfo = dictionary[i];
if (currentVectorInfo.Vector == remainder)
{
yield return ImmutableStack.Create(currentVectorInfo.Index);
//yield return ImmutableStack.Create(currentVectorInfo.Index);
}
else if (currentVectorInfo.Norm < requiredRemainderPerWord)
{
@ -106,7 +116,15 @@
{
var newRemainder = remainder - currentVectorInfo.Vector;
var newRemainderNorm = remainderNorm - currentVectorInfo.Norm;
foreach (var result in GenerateUnorderedSequences(newRemainder, newRemainderNorm, newAllowedRemainingWords, dictionary, i))
var newSequences = GenerateUnorderedSequences(
newRemainder,
newRemainderNorm,
newAllowedRemainingWords,
dictionary,
i + dictionaryPositionAddendum,
dictionaryPositionAddendum);
foreach (var result in newSequences)
{
yield return result.Push(currentVectorInfo.Index);
}
@ -133,6 +151,11 @@
// BCL BinarySearch would find any vector with required norm, not the first one; or would find nothing if there is no such vector
private static int FindFirstWithNormLessOrEqual(int expectedNorm, ImmutableArray<VectorInfo> dictionary, int offset)
{
if (offset >= dictionary.Length)
{
return dictionary.Length;
}
var start = offset;
var end = dictionary.Length - 1;
@ -167,6 +190,9 @@
private static IEnumerable<T[]> GeneratePermutations<T>(T[] original)
{
yield return original;
yield break;
/*
var length = original.Length;
foreach (var permutation in PrecomputedPermutationsGenerator.HamiltonianPermutations(length))
{
@ -177,7 +203,7 @@
}
yield return result;
}
}*/
}
private struct VectorInfo

Loading…
Cancel
Save