state should have the length of repeat
Input range primitives
Forward range primitive. Allocates using GC.
import mir.ndslice.fuse; import mir.ndslice.topology: iota; import std.string: representation; assert(iota(2).combinationsRepeat.fuse == [[0], [1]]); assert(iota(2).combinationsRepeat(2).fuse == [[0, 0], [0, 1], [1, 1]]); assert(iota(3).combinationsRepeat(2).fuse == [[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]]); assert("AB"d.representation.combinationsRepeat(2).fuse == ["AA"d, "AB"d, "BB"d]);
import mir.algorithm.iteration: equal; import mir.ndslice.slice: sliced; import mir.ndslice.topology: iota; import std.experimental.allocator.mallocator; auto alloc = Mallocator.instance; static immutable expected3r1 = [ 0, 1, 2]; auto r = iota(3); auto rc = alloc.makeCombinationsRepeat(r.length, 1); assert(expected3r1.sliced(3, 1).equal(rc.indexedRoR(r))); alloc.dispose(rc);
Lazy Forward range of combinations with repeats. It always generates combinations with repeats from 0 to n - 1, use indexedRoR to map it to your range.
Generating a new combination with repeats is in O(k), the number of combinations with repeats is binomial(n, k).