diff --git a/Algorithms/Algorithms.Tests/FactorizationTests/FactorizationTest.cs b/Algorithms/Algorithms.Tests/FactorizationTests/FactorizationTest.cs new file mode 100644 index 0000000..a6878de --- /dev/null +++ b/Algorithms/Algorithms.Tests/FactorizationTests/FactorizationTest.cs @@ -0,0 +1,45 @@ +using System.Collections.Generic; +using FluentAssertions; +using Xunit; + +namespace Algorithms.Tests.FactorizationTests +{ + public class FactorizationTest + { + [Fact] + public void GetFactors_FactorizationOf825_ReturnCollection() + { + var expected = new List{3, 5, 5, 11}; + + var result = Factorization.GetFactorsOf(825); + + result.Should().BeEquivalentTo(expected); + } + + [Fact] + public void GetFactors_FactorizationOf1386_ReturnCollection() + { + var expected = new List { 2, 3, 3, 7, 11 }; + + var result = Factorization.GetFactorsOf(1386); + + result.Should().BeEquivalentTo(expected); + } + + [Fact] + public void GetFactors_FactorizationOf0_ReturnCollectionWith0() + { + var result = Factorization.GetFactorsOf(0); + + result.Should().BeEquivalentTo(0); + } + + [Fact] + public void GetFactors_FactorizationOfNegative_ReturnCollectionWith0() + { + var result = Factorization.GetFactorsOf(-1); + + result.Should().BeEquivalentTo(0); + } + } +} diff --git a/Algorithms/Algorithms/Factorization/Factorization.cs b/Algorithms/Algorithms/Factorization/Factorization.cs new file mode 100644 index 0000000..cfd7c65 --- /dev/null +++ b/Algorithms/Algorithms/Factorization/Factorization.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Algorithms +{ + public static class Factorization + { + public static IEnumerable GetFactorsOf(int input) + { + if (input < 0) + return new [] {0}; + + var first = GetPrimes() + .TakeWhile(x => x <= Math.Sqrt(input)) + .FirstOrDefault(x => input % x == 0); + + var result = first == 0 + ? new[] { input } + : new[] { first }.Concat(GetFactorsOf(input / first)); + + return result; + } + + private static IEnumerable GetSequence() + { + yield return 2; + yield return 3; + + var k = 1; + while (k > 0) + { + yield return 6 * k - 1; + yield return 6 * k + 1; + k++; + } + } + + private static IEnumerable GetPrimes() + { + var memoized = new List(); + var sqrt = 1; + var primes = GetSequence().Where(x => + { + sqrt = GetSqrtCeiling(x, sqrt); + return memoized + .TakeWhile(y => y <= sqrt) + .All(y => x % y != 0); + }); + + foreach (var prime in primes) + { + yield return prime; + memoized.Add(prime); + } + } + + private static int GetSqrtCeiling(int value, int start) + { + while (start * start < value) + { + start++; + } + return start; + } + } +}