If I understand the question: are you looking for all sequences of integers of length P, where each integer in the set is between 0 and T, and the sequence is monotonically non-decreasing. It is right?
Writing such a program using iterator blocks is simple:
using System; using System.Collections.Generic; using System.Linq; static class Program { static IEnumerable<T> Prepend<T>(T first, IEnumerable<T> rest) { yield return first; foreach (var item in rest) yield return item; } static IEnumerable<IEnumerable<int>> M(int p, int t1, int t2) { if (p == 0) yield return Enumerable.Empty<int>(); else for (int first = t1; first <= t2; ++first) foreach (var rest in M(p - 1, first, t2)) yield return Prepend(first, rest); } public static void Main() { foreach (var sequence in M(4, 0, 2)) Console.WriteLine(string.Join(", ", sequence)); } }
Which gives the desired result: non-decreasing sequences of length 4, taken from 0 to 2.
0, 0, 0, 0 0, 0, 0, 1 0, 0, 0, 2 0, 0, 1, 1 0, 0, 1, 2 0, 0, 2, 2 0, 1, 1, 1 0, 1, 1, 2 0, 1, 2, 2 0, 2, 2, 2 1, 1, 1, 1 1, 1, 1, 2 1, 1, 2, 2 1, 2, 2, 2 2, 2, 2, 2
Please note that using multi-threaded iterators for concatenation is not very efficient , but who cares? You already generate the number of exponential sequences, so the fact of the absence of a polynomial in the generator does not matter.
Method M generates all monotone non-decreasing sequences of integers p, where integers are between t1 and t2. It does this recursively using direct recursion. The main case is that there is exactly one sequence of zero length, namely an empty sequence. The recursive case is that to calculate, say, P = 3, t1 = 0, t2 = 2, you calculate:
- all sequences starting with 0 followed by sequences of length 2 drawn from 0 to 2. - all sequences starting with 1 followed by sequences of length 2 drawn from 1 to 2. - all sequences starting with 2 followed by sequences of length 2 drawn from 2 to 2.
And what a result.
Alternatively, you can use query understanding instead of iterator blocks in the main recursive method:
static IEnumerable<T> Singleton<T>(T first) { yield return first; } static IEnumerable<IEnumerable<int>> M(int p, int t1, int t2) { return p == 0 ? Singleton(Enumerable.Empty<int>()) : from first in Enumerable.Range(t1, t2 - t1 + 1) from rest in M(p - 1, first, t2) select Prepend(first, rest); }
It is basically the same; it just moves the loops into the SelectMany method.