Skip to content

Commit 5a93af1

Browse files
committed
added cartesian product
1 parent 9c3e605 commit 5a93af1

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed

BinaryRelations/Matrix/MatrixExtensions.cs

+41
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34
using System.Linq.Expressions;
45
using System.Runtime.CompilerServices;
56

@@ -548,5 +549,45 @@ private static void ThrowIfSizeNotEqual<T>(this T[,] array1, in T[,] array2)
548549
}
549550

550551
#endregion
552+
553+
#region Combinatorics
554+
555+
public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
556+
{
557+
IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
558+
return sequences.Aggregate(
559+
emptyProduct,
560+
(accumulator, sequence) =>
561+
from acc in accumulator
562+
from item in sequence
563+
select acc.Concat(new[] { item }));
564+
}
565+
566+
public static IEnumerable<IEnumerable<IEnumerable<int>>> CartesianProductDistinctPairs(int size, int start = 1)
567+
{
568+
var range = Enumerable.Range(start, size).ToArray();
569+
for (var i = 1; i <= size; i++)
570+
yield return Permutations(range, i);
571+
}
572+
573+
public static IEnumerable<IEnumerable<T>> Permutations<T>(IEnumerable<T> array, int elementsInArray)
574+
{
575+
var range = array as T[] ?? array.ToArray();
576+
var i = 1;
577+
foreach (var item in range)
578+
{
579+
if (elementsInArray == 1)
580+
{
581+
yield return new[] { item };
582+
}
583+
else
584+
{
585+
foreach (var result in Permutations(range.Skip(i++), elementsInArray - 1))
586+
yield return new[] { item }.Concat(result);
587+
}
588+
}
589+
}
590+
591+
#endregion
551592
}
552593
}

BinaryRelationsTests/MatrixOperationsTests.cs

+76
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
13
using BinaryRelationsTests.Helpers;
24
using MaxRev.Extensions.Binary;
35
using MaxRev.Extensions.Matrix;
@@ -83,5 +85,79 @@ public void SubtractMatrices()
8385
};
8486
Assert.Equal(expected, m1.Subtract(m2));
8587
}
88+
89+
[Fact]
90+
public void Permutations()
91+
{
92+
var expected = new[]
93+
{
94+
new[] {1, 2, 3},
95+
new[] {1, 2, 4},
96+
new[] {1, 2, 5},
97+
new[] {1, 3, 4},
98+
new[] {1, 3, 5},
99+
new[] {1, 4, 5},
100+
new[] {2, 3, 4},
101+
new[] {2, 3, 5},
102+
new[] {2, 4, 5},
103+
new[] {3, 4, 5},
104+
};
105+
Assert.Equal(expected, MatrixExtensions.Permutations(Enumerable.Range(1, 5), 3));
106+
}
107+
108+
[Fact]
109+
public void CartesianProductDistinctPairs()
110+
{
111+
var expected = new[] {
112+
new[]
113+
{
114+
new[] {1},
115+
new[] {2},
116+
new[] {3},
117+
new[] {4},
118+
new[] {5},
119+
},
120+
new[]
121+
{
122+
new[] {1, 2},
123+
new[] {1, 3},
124+
new[] {1, 4},
125+
new[] {1, 5},
126+
new[] {2, 3},
127+
new[] {2, 4},
128+
new[] {2, 5},
129+
new[] {3, 4},
130+
new[] {3, 5},
131+
new[] {4, 5},
132+
},
133+
new[]
134+
{
135+
new[] {1, 2, 3},
136+
new[] {1, 2, 4},
137+
new[] {1, 2, 5},
138+
new[] {1, 3, 4},
139+
new[] {1, 3, 5},
140+
new[] {1, 4, 5},
141+
new[] {2, 3, 4},
142+
new[] {2, 3, 5},
143+
new[] {2, 4, 5},
144+
new[] {3, 4, 5},
145+
},
146+
new[]
147+
{
148+
new[] {1, 2, 3, 4},
149+
new[] {1, 2, 3, 5},
150+
new[] {1, 2, 4, 5},
151+
new[] {1, 3, 4, 5},
152+
new[] {2, 3, 4, 5},
153+
},
154+
new []
155+
{
156+
new[] {1, 2, 3, 4, 5}
157+
}
158+
};
159+
160+
Assert.Equal(expected, MatrixExtensions.CartesianProductDistinctPairs(5));
161+
}
86162
}
87163
}

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,5 @@ Provides a bunch of extension methods for binary matrices including:
6060
- Randomize
6161
- AllocateRandomSquareMatrix
6262
- AllocateRandomVector
63+
- CartesianProduct
64+
- CartesianProductDistinctPairs

0 commit comments

Comments
 (0)