namespace WhiteRabbit { using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Numerics; using System.Security.Cryptography; using System.Text; /// /// Main class /// public static class Program { /// /// Main entry point /// public static void Main() { var expectedHashes = new[] { "e4820b45d2277f3844eac66c903e84be", "23170acc097c24edb98fc5488ab033fe", "665e5bcb0c20062fe8abaaf4628bb154", }; var expectedHashesAsVectors = new HashSet>(expectedHashes.Select(hash => new Vector(StringToByteArray(hash)))); var stopwatch = new Stopwatch(); stopwatch.Start(); using (var hasher = MD5.Create()) { var processor = new StringsProcessor("poultry outwits ants", 4, ReadInput()); var startBlock = DataflowBlockHelpers.Id[]>(); var task = startBlock .Pipe(processor.CreateUnorderedSequencesToPhrasesTransform()) .Pipe(phrase => { //Console.WriteLine("Found phrase: " + phrase); var hash = new Vector(hasher.ComputeHash(Encoding.ASCII.GetBytes(phrase))); return new PhraseWithHash(phrase, hash); }) .PipeMany(phraseWithHash => { //Console.WriteLine($"Found phrase with hash: " + phraseWithHash.Phrase); if (!expectedHashesAsVectors.Contains(phraseWithHash.Hash)) { return Enumerable.Empty(); } return new PhraseWithHash[] { phraseWithHash, }; }) .LinkForever(phraseWithHash => { Console.WriteLine($"Found phrase for hash {phraseWithHash.Hash}: {phraseWithHash.Phrase} (spent {stopwatch.Elapsed})"); }); Console.WriteLine($"Initialization complete: time spent: {stopwatch.Elapsed}"); processor.PostUnorderedSequences(startBlock); task.Wait(); Console.WriteLine($"Total time spent: {stopwatch.Elapsed}"); } } // Code taken from http://stackoverflow.com/a/321404/831314 private static byte[] StringToByteArray(string hex) { return Enumerable.Range(0, hex.Length) .Where(x => x % 2 == 0) .Select(x => Convert.ToByte(hex.Substring(x, 2), 16)) .ToArray(); } private static IEnumerable>> AddHashes(IEnumerable input) { using (MD5 hasher = MD5.Create()) { foreach (var line in input) { var data = hasher.ComputeHash(Encoding.ASCII.GetBytes(line)); yield return Tuple.Create(line, new Vector(data)); } } } private static IEnumerable ReadInput() { string line; while ((line = Console.ReadLine()) != null) { yield return line; } } private class PhraseWithHash { public PhraseWithHash(string phrase, Vector hash) { this.Phrase = phrase; this.Hash = hash; } public string Phrase { get; } public Vector Hash { get; } } } }