Refactoring

master
Inga 🏳‍🌈 7 years ago
parent 5ffaa1090a
commit 5a0026ff80
  1. 41
      dotnet/WhiteRabbit/Program.cs
  2. 20
      dotnet/WhiteRabbit/StringsProcessor.cs

@ -24,11 +24,10 @@
stopwatch.Start(); stopwatch.Start();
var sourcePhrase = ConfigurationManager.AppSettings["SourcePhrase"]; var sourcePhrase = ConfigurationManager.AppSettings["SourcePhrase"];
var sourceChars = ToOrderedChars(sourcePhrase);
var maxWordsInPhrase = int.Parse(ConfigurationManager.AppSettings["MaxWordsInPhrase"]); var maxWordsInPhrase = int.Parse(ConfigurationManager.AppSettings["MaxWordsInPhrase"]);
if (sourceChars.Length + maxWordsInPhrase > 28) if (sourcePhrase.Where(ch => ch != ' ').Count() + maxWordsInPhrase > 28)
{ {
Console.WriteLine("Only anagrams of up to 27 characters (including whitespace) are allowed"); Console.WriteLine("Only anagrams of up to 27 characters (including whitespace) are allowed");
return; return;
@ -78,27 +77,14 @@
stopwatch.Restart(); stopwatch.Restart();
processor.CheckPhrases(phraseSet => ProcessPhraseSet(phraseSet, expectedHashesFirstComponents, stopwatch)); processor.CheckPhrases(expectedHashesFirstComponents, (phraseBytes, hashFirstComponent) =>
Console.WriteLine($"Done; time from start: {stopwatch.Elapsed}");
}
private static void ProcessPhraseSet(PhraseSet phraseSet, Vector<uint> expectedHashesFirstComponents, Stopwatch stopwatch)
{
phraseSet.ComputeMD5();
for (var i = 0; i < Constants.PhrasesPerSet; i++)
{ {
/*Debug.Assert( var phrase = Encoding.ASCII.GetString(phraseBytes);
sourceChars == ToOrderedChars(ToString(phraseSet, i)), var hash = ComputeFullMD5(phraseBytes);
$"StringsProcessor produced incorrect anagram: {ToString(phraseSet, i)}");*/ Console.WriteLine($"Found phrase for {hash} ({hashFirstComponent:x8}): {phrase}; time from start is {stopwatch.Elapsed}");
});
if (Vector.EqualsAny(expectedHashesFirstComponents, new Vector<uint>(phraseSet.GetMD5(i)))) Console.WriteLine($"Done; time from start: {stopwatch.Elapsed}");
{
var phrase = ToString(phraseSet, i);
var hash = ComputeFullMD5(phrase);
Console.WriteLine($"Found phrase for {hash} ({phraseSet.GetMD5(i):x8}): {phrase}; time from start is {stopwatch.Elapsed}");
}
}
} }
// Code taken from http://stackoverflow.com/a/321404/831314 // Code taken from http://stackoverflow.com/a/321404/831314
@ -112,9 +98,8 @@
} }
// We can afford to spend some time here; this code will only run for matched phrases (and for one in several billion non-matched) // We can afford to spend some time here; this code will only run for matched phrases (and for one in several billion non-matched)
private static string ComputeFullMD5(string phrase) private static string ComputeFullMD5(byte[] phraseBytes)
{ {
var phraseBytes = Encoding.ASCII.GetBytes(phrase);
using (var hashAlgorithm = new MD5CryptoServiceProvider()) using (var hashAlgorithm = new MD5CryptoServiceProvider())
{ {
var resultBytes = hashAlgorithm.ComputeHash(phraseBytes); var resultBytes = hashAlgorithm.ComputeHash(phraseBytes);
@ -127,11 +112,6 @@
return hex.Substring(6, 2) + hex.Substring(4, 2) + hex.Substring(2, 2) + hex.Substring(0, 2); return hex.Substring(6, 2) + hex.Substring(4, 2) + hex.Substring(2, 2) + hex.Substring(0, 2);
} }
private static string ToString(PhraseSet phrase, int offset)
{
return Encoding.ASCII.GetString(phrase.GetBytes(offset));
}
private static IEnumerable<byte[]> ReadInput() private static IEnumerable<byte[]> ReadInput()
{ {
string line; string line;
@ -140,10 +120,5 @@
yield return Encoding.ASCII.GetBytes(line); yield return Encoding.ASCII.GetBytes(line);
} }
} }
private static string ToOrderedChars(string source)
{
return new string(source.Where(ch => ch != ' ').OrderBy(ch => ch).ToArray());
}
} }
} }

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics;
using System.Threading.Tasks; using System.Threading.Tasks;
internal sealed class StringsProcessor internal sealed class StringsProcessor
@ -60,13 +61,13 @@
private int NumberOfCharacters { get; } private int NumberOfCharacters { get; }
public void CheckPhrases(Action<PhraseSet> action) public void CheckPhrases(Vector<uint> expectedHashes, Action<byte[], uint> action)
{ {
// task of finding anagrams could be reduced to the task of finding sequences of dictionary vectors with the target sum // task of finding anagrams could be reduced to the task of finding sequences of dictionary vectors with the target sum
var sums = this.VectorsProcessor.GenerateSequences(); var sums = this.VectorsProcessor.GenerateSequences();
// converting sequences of vectors to the sequences of words... // converting sequences of vectors to the sequences of words...
Parallel.ForEach(sums, new ParallelOptions { MaxDegreeOfParallelism = Constants.NumberOfThreads }, sum => ProcessSum(sum, action)); Parallel.ForEach(sums, new ParallelOptions { MaxDegreeOfParallelism = Constants.NumberOfThreads }, sum => ProcessSum(sum, expectedHashes, action));
} }
public long GetPhrasesCount() public long GetPhrasesCount()
@ -118,24 +119,31 @@
return result; return result;
} }
private void ProcessSum(int[] sum, Action<PhraseSet> action) private void ProcessSum(int[] sum, Vector<uint> expectedHashes, Action<byte[], uint> action)
{ {
var initialPhraseSet = new PhraseSet(); var initialPhraseSet = new PhraseSet();
initialPhraseSet.Init(); initialPhraseSet.Init();
initialPhraseSet.FillLength(this.NumberOfCharacters, sum.Length); initialPhraseSet.FillLength(this.NumberOfCharacters, sum.Length);
var phraseSet = new PhraseSet(); var phraseSet = new PhraseSet();
phraseSet.Init(); phraseSet.Init();
var filter = ComputeFilter(sum); var permutationsFilter = ComputeFilter(sum);
var wordsVariants = this.ConvertVectorsToWordIndexes(sum); var wordsVariants = this.ConvertVectorsToWordIndexes(sum);
foreach (var wordsArray in Flattener.Flatten(wordsVariants)) foreach (var wordsArray in Flattener.Flatten(wordsVariants))
{ {
//Console.WriteLine(new string(wordsArray.SelectMany(wordIndex => this.AllWords[wordIndex].Original).Select(b => (char)b).ToArray())); //Console.WriteLine(new string(wordsArray.SelectMany(wordIndex => this.AllWords[wordIndex].Original).Select(b => (char)b).ToArray()));
var permutations = PrecomputedPermutationsGenerator.HamiltonianPermutations(wordsArray.Length, filter); var permutations = PrecomputedPermutationsGenerator.HamiltonianPermutations(wordsArray.Length, permutationsFilter);
for (var i = 0; i < permutations.Length; i += Constants.PhrasesPerSet) for (var i = 0; i < permutations.Length; i += Constants.PhrasesPerSet)
{ {
phraseSet.FillPhraseSet(initialPhraseSet, this.AllWords, wordsArray, permutations, i); phraseSet.FillPhraseSet(initialPhraseSet, this.AllWords, wordsArray, permutations, i);
action(phraseSet); phraseSet.ComputeMD5();
for (var j = 0; j < Constants.PhrasesPerSet; j++)
{
if (Vector.EqualsAny(expectedHashes, new Vector<uint>(phraseSet.GetMD5(j))))
{
action(phraseSet.GetBytes(j), phraseSet.GetMD5(j));
}
}
} }
} }
} }

Loading…
Cancel
Save