From 5fb43799af774983ea491e39c2b092bfca85e450 Mon Sep 17 00:00:00 2001
From: inga-lovinde <52715130+inga-lovinde@users.noreply.github.com>
Date: Thu, 9 Mar 2017 11:56:45 +0300
Subject: [PATCH] Refactored to use RX
---
WhiteRabbit/App.config | 10 +++++++++-
WhiteRabbit/Program.cs | 31 +++++++++++++++++++------------
WhiteRabbit/StringsProcessor.cs | 13 +++++++++----
WhiteRabbit/VectorsProcessor.cs | 16 ++++++++++++----
WhiteRabbit/WhiteRabbit.csproj | 22 ++++++++++++++++++++++
WhiteRabbit/packages.config | 6 ++++++
6 files changed, 77 insertions(+), 21 deletions(-)
diff --git a/WhiteRabbit/App.config b/WhiteRabbit/App.config
index 8324aa6..f2af62f 100644
--- a/WhiteRabbit/App.config
+++ b/WhiteRabbit/App.config
@@ -1,6 +1,14 @@
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/WhiteRabbit/Program.cs b/WhiteRabbit/Program.cs
index e6faae4..3c354f1 100644
--- a/WhiteRabbit/Program.cs
+++ b/WhiteRabbit/Program.cs
@@ -5,6 +5,8 @@
using System.Diagnostics;
using System.Linq;
using System.Numerics;
+ using System.Reactive.Concurrency;
+ using System.Reactive.Linq;
using System.Security.Cryptography;
using System.Text;
@@ -31,11 +33,18 @@
var expectedHashesAsVectors = new HashSet>(expectedHashes.Select(hash => new Vector(StringToByteArray(hash))));
- foreach (var result in AddHashes(processor.GeneratePhrases(ReadInput())))
+ var phrases = processor.GeneratePhrases(ReadInput());
+ using (var hasher = MD5.Create())
{
- if (expectedHashesAsVectors.Contains(result.Item2))
+ var phrasesWithHashes = phrases
+ .Select(phrase => new { phrase, hash = ComputeHash(hasher, phrase) })
+ .SubscribeOn(NewThreadScheduler.Default);
+
+ var filteredPhrases = phrasesWithHashes.Where(tuple => expectedHashesAsVectors.Contains(tuple.hash));
+
+ foreach (var result in filteredPhrases.ToEnumerable())
{
- Console.WriteLine($"Found phrase: {result.Item1} (spent {stopwatch.Elapsed})");
+ Console.WriteLine($"Found phrase with hash {HashToString(result.hash)}: {result.phrase} (spent {stopwatch.Elapsed})");
}
}
@@ -52,16 +61,14 @@
.ToArray();
}
- private static IEnumerable>> AddHashes(IEnumerable input)
+ private static Vector ComputeHash(HashAlgorithm hasher, string phrase)
{
- 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));
- }
- }
+ return new Vector(hasher.ComputeHash(Encoding.ASCII.GetBytes(phrase)));
+ }
+
+ private static string HashToString(Vector hash)
+ {
+ return string.Concat(Enumerable.Range(0, 16).Select(i => hash[i].ToString("x2")));
}
private static IEnumerable ReadInput()
diff --git a/WhiteRabbit/StringsProcessor.cs b/WhiteRabbit/StringsProcessor.cs
index 3cbe422..d8a2f50 100644
--- a/WhiteRabbit/StringsProcessor.cs
+++ b/WhiteRabbit/StringsProcessor.cs
@@ -1,8 +1,11 @@
namespace WhiteRabbit
{
+ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
+ using System.Reactive.Concurrency;
+ using System.Reactive.Linq;
internal class StringsProcessor
{
@@ -20,7 +23,7 @@
private VectorsProcessor VectorsProcessor { get; }
- public IEnumerable GeneratePhrases(IEnumerable words)
+ public IObservable GeneratePhrases(IEnumerable words)
{
// Dictionary of vectors to array of words represented by this vector
var formattedWords = words
@@ -32,15 +35,17 @@
.ToDictionary(group => group.Key, group => group.Select(tuple => tuple.word).ToArray());
// 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(formattedWords.Keys);
+ var sums = this.VectorsProcessor.GenerateSequences(formattedWords.Keys).ObserveOn(Scheduler.Default);
// converting sequences of vectors to the sequences of words...
var anagramsWords = sums
.Select(sum => ImmutableStack.Create(sum.Select(vector => formattedWords[vector]).ToArray()))
.SelectMany(this.Flatten)
- .Select(stack => stack.ToArray());
+ .Select(stack => stack.ToArray())
+ .SubscribeOn(NewThreadScheduler.Default);
- return anagramsWords.Select(list => string.Join(" ", list));
+ return anagramsWords.Select(list => string.Join(" ", list))
+ .SubscribeOn(NewThreadScheduler.Default);
}
// 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]]
diff --git a/WhiteRabbit/VectorsProcessor.cs b/WhiteRabbit/VectorsProcessor.cs
index 28be0c6..4dedc7f 100644
--- a/WhiteRabbit/VectorsProcessor.cs
+++ b/WhiteRabbit/VectorsProcessor.cs
@@ -6,6 +6,8 @@
using System.Diagnostics;
using System.Linq;
using System.Numerics;
+ using System.Reactive.Concurrency;
+ using System.Reactive.Linq;
internal class VectorsProcessor
{
@@ -33,12 +35,18 @@
private long Iterations { get; set; } = 0;
// Produces all sequences of vectors with the target sum
- public IEnumerable[]> GenerateSequences(IEnumerable> vectors)
+ public IObservable[]> GenerateSequences(IReadOnlyCollection> vectors)
{
var filteredVectors = this.FilterVectors(vectors);
var dictionary = ImmutableStack.Create(filteredVectors.ToArray());
- var unorderedSequences = this.GenerateUnorderedSequences(this.Target, ImmutableStack.Create>(), dictionary);
- var allSequences = unorderedSequences.SelectMany(this.GeneratePermutations);
+
+ var unorderedSequences = this.GenerateUnorderedSequences(this.Target, ImmutableStack.Create>(), dictionary)
+ .ToObservable()
+ .SubscribeOn(NewThreadScheduler.Default);
+
+ var allSequences = unorderedSequences
+ .SelectMany(this.GeneratePermutations)
+ .SubscribeOn(NewThreadScheduler.Default);
return allSequences;
}
@@ -59,7 +67,7 @@
return weight;
}
- private IEnumerable> FilterVectors(IEnumerable> vectors)
+ private IEnumerable> FilterVectors(IReadOnlyCollection> vectors)
{
return vectors
.Where(vector => ((this.Target - vector) & Negative) == Vector.Zero)
diff --git a/WhiteRabbit/WhiteRabbit.csproj b/WhiteRabbit/WhiteRabbit.csproj
index 1af7ec9..f2662e5 100644
--- a/WhiteRabbit/WhiteRabbit.csproj
+++ b/WhiteRabbit/WhiteRabbit.csproj
@@ -45,12 +45,34 @@
..\packages\System.Numerics.Vectors.4.3.0\lib\net46\System.Numerics.Vectors.dll
True
+
+ ..\packages\System.Reactive.Core.3.1.1\lib\net46\System.Reactive.Core.dll
+ True
+
+
+ ..\packages\System.Reactive.Interfaces.3.1.1\lib\net45\System.Reactive.Interfaces.dll
+ True
+
+
+ ..\packages\System.Reactive.Linq.3.1.1\lib\net46\System.Reactive.Linq.dll
+ True
+
+
+ ..\packages\System.Reactive.PlatformServices.3.1.1\lib\net46\System.Reactive.PlatformServices.dll
+ True
+
+
+ ..\packages\System.Reactive.Windows.Threading.3.1.1\lib\net45\System.Reactive.Windows.Threading.dll
+ True
+
+
+
diff --git a/WhiteRabbit/packages.config b/WhiteRabbit/packages.config
index d38493d..05c58a2 100644
--- a/WhiteRabbit/packages.config
+++ b/WhiteRabbit/packages.config
@@ -2,4 +2,10 @@
+
+
+
+
+
+
\ No newline at end of file