| @safe unittest |
| { |
| import std.algorithm.setops; |
| |
| import std.algorithm.searching : canFind; |
| import std.range; |
| import std.typecons : tuple; |
| |
| auto N = sequence!"n"(0); // the range of natural numbers |
| auto N2 = cartesianProduct(N, N); // the range of all pairs of natural numbers |
| |
| // Various arbitrary number pairs can be found in the range in finite time. |
| assert(canFind(N2, tuple(0, 0))); |
| assert(canFind(N2, tuple(123, 321))); |
| assert(canFind(N2, tuple(11, 35))); |
| assert(canFind(N2, tuple(279, 172))); |
| } |
| |
| @safe unittest |
| { |
| import std.algorithm.setops; |
| |
| import std.algorithm.searching : canFind; |
| import std.typecons : tuple; |
| |
| auto B = [ 1, 2, 3 ]; |
| auto C = [ 4, 5, 6 ]; |
| auto BC = cartesianProduct(B, C); |
| |
| foreach (n; [[1, 4], [2, 4], [3, 4], [1, 5], [2, 5], [3, 5], [1, 6], |
| [2, 6], [3, 6]]) |
| { |
| assert(canFind(BC, tuple(n[0], n[1]))); |
| } |
| } |
| |
| @safe unittest |
| { |
| import std.algorithm.setops; |
| |
| import std.algorithm.comparison : equal; |
| import std.typecons : tuple; |
| |
| auto A = [ 1, 2, 3 ]; |
| auto B = [ 'a', 'b', 'c' ]; |
| auto C = [ "x", "y", "z" ]; |
| auto ABC = cartesianProduct(A, B, C); |
| |
| assert(ABC.equal([ |
| tuple(1, 'a', "x"), tuple(1, 'a', "y"), tuple(1, 'a', "z"), |
| tuple(1, 'b', "x"), tuple(1, 'b', "y"), tuple(1, 'b', "z"), |
| tuple(1, 'c', "x"), tuple(1, 'c', "y"), tuple(1, 'c', "z"), |
| tuple(2, 'a', "x"), tuple(2, 'a', "y"), tuple(2, 'a', "z"), |
| tuple(2, 'b', "x"), tuple(2, 'b', "y"), tuple(2, 'b', "z"), |
| tuple(2, 'c', "x"), tuple(2, 'c', "y"), tuple(2, 'c', "z"), |
| tuple(3, 'a', "x"), tuple(3, 'a', "y"), tuple(3, 'a', "z"), |
| tuple(3, 'b', "x"), tuple(3, 'b', "y"), tuple(3, 'b', "z"), |
| tuple(3, 'c', "x"), tuple(3, 'c', "y"), tuple(3, 'c', "z") |
| ])); |
| } |
| |
| @system unittest |
| { |
| import std.algorithm.setops; |
| |
| import std.typecons : tuple, Tuple; |
| |
| // Figure which number can be found in most arrays of the set of |
| // arrays below. |
| double[][] a = |
| [ |
| [ 1, 4, 7, 8 ], |
| [ 1, 7 ], |
| [ 1, 7, 8], |
| [ 4 ], |
| [ 7 ], |
| ]; |
| auto b = new Tuple!(double, uint)[1]; |
| // it will modify the input range, hence we need to create a duplicate |
| largestPartialIntersection(a.dup, b); |
| // First member is the item, second is the occurrence count |
| assert(b[0] == tuple(7.0, 4u)); |
| // 7.0 occurs in 4 out of 5 inputs, more than any other number |
| |
| // If more of the top-frequent numbers are needed, just create a larger |
| // tgt range |
| auto c = new Tuple!(double, uint)[2]; |
| largestPartialIntersection(a, c); |
| assert(c[0] == tuple(1.0, 3u)); |
| // 1.0 occurs in 3 inputs |
| |
| // multiset |
| double[][] x = |
| [ |
| [1, 1, 1, 1, 4, 7, 8], |
| [1, 7], |
| [1, 7, 8], |
| [4, 7], |
| [7] |
| ]; |
| auto y = new Tuple!(double, uint)[2]; |
| largestPartialIntersection(x.dup, y); |
| // 7.0 occurs 5 times |
| assert(y[0] == tuple(7.0, 5u)); |
| // 1.0 occurs 6 times |
| assert(y[1] == tuple(1.0, 6u)); |
| } |
| |
| @system unittest |
| { |
| import std.algorithm.setops; |
| |
| import std.typecons : tuple, Tuple; |
| |
| // Figure which number can be found in most arrays of the set of |
| // arrays below, with specific per-element weights |
| double[][] a = |
| [ |
| [ 1, 4, 7, 8 ], |
| [ 1, 7 ], |
| [ 1, 7, 8], |
| [ 4 ], |
| [ 7 ], |
| ]; |
| auto b = new Tuple!(double, uint)[1]; |
| double[double] weights = [ 1:1.2, 4:2.3, 7:1.1, 8:1.1 ]; |
| largestPartialIntersectionWeighted(a, b, weights); |
| // First member is the item, second is the occurrence count |
| assert(b[0] == tuple(4.0, 2u)); |
| // 4.0 occurs 2 times -> 4.6 (2 * 2.3) |
| // 7.0 occurs 3 times -> 4.4 (3 * 1.1) |
| |
| // multiset |
| double[][] x = |
| [ |
| [ 1, 1, 1, 4, 7, 8 ], |
| [ 1, 7 ], |
| [ 1, 7, 8], |
| [ 4 ], |
| [ 7 ], |
| ]; |
| auto y = new Tuple!(double, uint)[1]; |
| largestPartialIntersectionWeighted(x, y, weights); |
| assert(y[0] == tuple(1.0, 5u)); |
| // 1.0 occurs 5 times -> 1.2 * 5 = 6 |
| } |
| |
| @system unittest |
| { |
| import std.algorithm.setops; |
| |
| import std.algorithm.comparison : equal; |
| |
| double[][] a = |
| [ |
| [ 1, 4, 7, 8 ], |
| [ 1, 7 ], |
| [ 1, 7, 8], |
| [ 4 ], |
| [ 7 ], |
| ]; |
| auto witness = [ |
| 1, 1, 1, 4, 4, 7, 7, 7, 7, 8, 8 |
| ]; |
| assert(equal(multiwayMerge(a), witness)); |
| |
| double[][] b = |
| [ |
| // range with duplicates |
| [ 1, 1, 4, 7, 8 ], |
| [ 7 ], |
| [ 1, 7, 8], |
| [ 4 ], |
| [ 7 ], |
| ]; |
| // duplicates are propagated to the resulting range |
| assert(equal(multiwayMerge(b), witness)); |
| } |
| |
| @system unittest |
| { |
| import std.algorithm.setops; |
| |
| import std.algorithm.comparison : equal; |
| |
| // sets |
| double[][] a = |
| [ |
| [ 1, 4, 7, 8 ], |
| [ 1, 7 ], |
| [ 1, 7, 8], |
| [ 4 ], |
| [ 7 ], |
| ]; |
| |
| auto witness = [1, 4, 7, 8]; |
| assert(equal(multiwayUnion(a), witness)); |
| |
| // multisets |
| double[][] b = |
| [ |
| [ 1, 1, 1, 4, 7, 8 ], |
| [ 1, 7 ], |
| [ 1, 7, 7, 8], |
| [ 4 ], |
| [ 7 ], |
| ]; |
| assert(equal(multiwayUnion(b), witness)); |
| |
| double[][] c = |
| [ |
| [9, 8, 8, 8, 7, 6], |
| [9, 8, 6], |
| [9, 8, 5] |
| ]; |
| auto witness2 = [9, 8, 7, 6, 5]; |
| assert(equal(multiwayUnion!"a > b"(c), witness2)); |
| } |
| |
| @safe unittest |
| { |
| import std.algorithm.setops; |
| |
| import std.algorithm.comparison : equal; |
| import std.range.primitives : isForwardRange; |
| |
| //sets |
| int[] a = [ 1, 2, 4, 5, 7, 9 ]; |
| int[] b = [ 0, 1, 2, 4, 7, 8 ]; |
| assert(equal(setDifference(a, b), [5, 9])); |
| static assert(isForwardRange!(typeof(setDifference(a, b)))); |
| |
| // multisets |
| int[] x = [1, 1, 1, 2, 3]; |
| int[] y = [1, 1, 2, 4, 5]; |
| auto r = setDifference(x, y); |
| assert(equal(r, [1, 3])); |
| assert(setDifference(r, x).empty); |
| } |
| |
| @safe unittest |
| { |
| import std.algorithm.setops; |
| |
| import std.algorithm.comparison : equal; |
| |
| // sets |
| int[] a = [ 1, 2, 4, 5, 7, 9 ]; |
| int[] b = [ 0, 1, 2, 4, 7, 8 ]; |
| int[] c = [ 0, 1, 4, 5, 7, 8 ]; |
| assert(equal(setIntersection(a, a), a)); |
| assert(equal(setIntersection(a, b), [1, 2, 4, 7])); |
| assert(equal(setIntersection(a, b, c), [1, 4, 7])); |
| |
| // multisets |
| int[] d = [ 1, 1, 2, 2, 7, 7 ]; |
| int[] e = [ 1, 1, 1, 7]; |
| assert(equal(setIntersection(a, d), [1, 2, 7])); |
| assert(equal(setIntersection(d, e), [1, 1, 7])); |
| } |
| |
| @safe unittest |
| { |
| import std.algorithm.setops; |
| |
| import std.algorithm.comparison : equal; |
| import std.range.primitives : isForwardRange; |
| |
| // sets |
| int[] a = [ 1, 2, 4, 5, 7, 9 ]; |
| int[] b = [ 0, 1, 2, 4, 7, 8 ]; |
| assert(equal(setSymmetricDifference(a, b), [0, 5, 8, 9][])); |
| static assert(isForwardRange!(typeof(setSymmetricDifference(a, b)))); |
| |
| //mutisets |
| int[] c = [1, 1, 1, 1, 2, 2, 2, 4, 5, 6]; |
| int[] d = [1, 1, 2, 2, 2, 2, 4, 7, 9]; |
| assert(equal(setSymmetricDifference(c, d), setSymmetricDifference(d, c))); |
| assert(equal(setSymmetricDifference(c, d), [1, 1, 2, 5, 6, 7, 9])); |
| } |
| |