From 5a93af1b6a5083c236fa7328a44962a8fe983606 Mon Sep 17 00:00:00 2001 From: MaxRev-Dev Date: Tue, 29 Oct 2019 19:49:22 +0200 Subject: [PATCH] added cartesian product --- BinaryRelations/Matrix/MatrixExtensions.cs | 41 ++++++++++ BinaryRelationsTests/MatrixOperationsTests.cs | 76 +++++++++++++++++++ README.md | 2 + 3 files changed, 119 insertions(+) diff --git a/BinaryRelations/Matrix/MatrixExtensions.cs b/BinaryRelations/Matrix/MatrixExtensions.cs index 67ce190..01bf6a7 100644 --- a/BinaryRelations/Matrix/MatrixExtensions.cs +++ b/BinaryRelations/Matrix/MatrixExtensions.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; using System.Runtime.CompilerServices; @@ -548,5 +549,45 @@ private static void ThrowIfSizeNotEqual(this T[,] array1, in T[,] array2) } #endregion + + #region Combinatorics + + public static IEnumerable> CartesianProduct(this IEnumerable> sequences) + { + IEnumerable> emptyProduct = new[] { Enumerable.Empty() }; + return sequences.Aggregate( + emptyProduct, + (accumulator, sequence) => + from acc in accumulator + from item in sequence + select acc.Concat(new[] { item })); + } + + public static IEnumerable>> CartesianProductDistinctPairs(int size, int start = 1) + { + var range = Enumerable.Range(start, size).ToArray(); + for (var i = 1; i <= size; i++) + yield return Permutations(range, i); + } + + public static IEnumerable> Permutations(IEnumerable array, int elementsInArray) + { + var range = array as T[] ?? array.ToArray(); + var i = 1; + foreach (var item in range) + { + if (elementsInArray == 1) + { + yield return new[] { item }; + } + else + { + foreach (var result in Permutations(range.Skip(i++), elementsInArray - 1)) + yield return new[] { item }.Concat(result); + } + } + } + + #endregion } } \ No newline at end of file diff --git a/BinaryRelationsTests/MatrixOperationsTests.cs b/BinaryRelationsTests/MatrixOperationsTests.cs index 7a7ba8c..0575287 100644 --- a/BinaryRelationsTests/MatrixOperationsTests.cs +++ b/BinaryRelationsTests/MatrixOperationsTests.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; +using System.Linq; using BinaryRelationsTests.Helpers; using MaxRev.Extensions.Binary; using MaxRev.Extensions.Matrix; @@ -83,5 +85,79 @@ public void SubtractMatrices() }; Assert.Equal(expected, m1.Subtract(m2)); } + + [Fact] + public void Permutations() + { + var expected = new[] + { + new[] {1, 2, 3}, + new[] {1, 2, 4}, + new[] {1, 2, 5}, + new[] {1, 3, 4}, + new[] {1, 3, 5}, + new[] {1, 4, 5}, + new[] {2, 3, 4}, + new[] {2, 3, 5}, + new[] {2, 4, 5}, + new[] {3, 4, 5}, + }; + Assert.Equal(expected, MatrixExtensions.Permutations(Enumerable.Range(1, 5), 3)); + } + + [Fact] + public void CartesianProductDistinctPairs() + { + var expected = new[] { + new[] + { + new[] {1}, + new[] {2}, + new[] {3}, + new[] {4}, + new[] {5}, + }, + new[] + { + new[] {1, 2}, + new[] {1, 3}, + new[] {1, 4}, + new[] {1, 5}, + new[] {2, 3}, + new[] {2, 4}, + new[] {2, 5}, + new[] {3, 4}, + new[] {3, 5}, + new[] {4, 5}, + }, + new[] + { + new[] {1, 2, 3}, + new[] {1, 2, 4}, + new[] {1, 2, 5}, + new[] {1, 3, 4}, + new[] {1, 3, 5}, + new[] {1, 4, 5}, + new[] {2, 3, 4}, + new[] {2, 3, 5}, + new[] {2, 4, 5}, + new[] {3, 4, 5}, + }, + new[] + { + new[] {1, 2, 3, 4}, + new[] {1, 2, 3, 5}, + new[] {1, 2, 4, 5}, + new[] {1, 3, 4, 5}, + new[] {2, 3, 4, 5}, + }, + new [] + { + new[] {1, 2, 3, 4, 5} + } + }; + + Assert.Equal(expected, MatrixExtensions.CartesianProductDistinctPairs(5)); + } } } \ No newline at end of file diff --git a/README.md b/README.md index 78ea4d8..c03f4d0 100644 --- a/README.md +++ b/README.md @@ -60,3 +60,5 @@ Provides a bunch of extension methods for binary matrices including: - Randomize - AllocateRandomSquareMatrix - AllocateRandomVector + - CartesianProduct + - CartesianProductDistinctPairs