SharpC
SharpC

Reputation: 43

Generating Numbers in sequence

How can i generate numbers using LinQ in this sequence given the startIndex,count of numbers and the maximum number.For example:

Sample Numbers = 1,2,3,4

StartIndex = 1 (i.e it should start from 1)
Sequence number count = 3 
Maximum number = 4 (i.e till 4)

Expected result given the above details :
 1,2,3
 1,3,4
 1,2,4

Is there a way to do it using linQ?

Upvotes: 1

Views: 2439

Answers (3)

jason
jason

Reputation: 241641

Okay, first let's state the problem clearly. I'll assume your numbers are int but that's a mostly irrelevant detail but the concreteness makes thinking go more smo

You have a sequence a_0, a_1, a_2, ..., a_N of int.

You have an integer k satisfying 1 <= k <= N + 1.

You have a starting index start >=0 and an ending index end <= N.

You want all subsequences a_i0, a_i1, a_i2, ..., a_ik of length k such that i0 = start and ik = end.

Then your algorithm is simple. You want to produce all combinations of size k - 2 of { start + 1, ..., end - 1 }. Given such a combination j1, j2, ..., j(k-1), order it, call the resulting ordered sequence i1, i2, ..., i(k-1) and return the sequence a_start, a_i1, a_i2, ..., a_i(k-1), a_end.

Now that you know a formal statement of the problem, and what you need to solve it, resources abound for generating said combinations. cf. Google search : Generating combinations C# or Knuth Volume 4A.

Upvotes: 0

mbeckish
mbeckish

Reputation: 10579

If you didn't need the length of you sequences to be dynamic, then you could use:

var startindex=1;
var maxindex=4;

var data = Enumerable.Range(startindex,maxindex);
var qry = from x in data
          where x == startindex
          from y in data
          where x < y
          from z in data
          where y < z
          select new { x, y, z };
foreach (var tuple in qry) {
    Console.WriteLine("{0} {1} {2}", tuple.x, tuple.y, tuple.z);
}

The sequence length is hardcoded to 3, because there are 3 enumerables being joined: x, y, z.

If you want to dynamically join an arbitrary number of enumerables, then you can use Eric Lippert's Cartesian Product Linq example.

You pass a set of k sequences of N items, and it will return a set of all combinations of length k.

Now, you don't want repeated elements in your results. So, I added the following to Eric's example:

where accseq.All(accitem => accitem < item)

Here's the final solution (edited for clarity):

var startindex=1;
var maxindex=7;
var count = 3;

// Make a set of count-1 sequences, whose values range from startindex+1 to maxindex
List<List<int>> sequences = new List<List<int>>();

// We only want permutations starting with startindex.  So, the first input sequence to be joined should only have the value startindex.
List<int> list1 = new List<int>();
list1.Add(startindex);
sequences.Add(list1);

// The rest of the input sequences to be joined should contain the range startindex+1 .. maxindex
for (int i=1; i< count; i++)
{
 sequences.Add(Enumerable.Range(startindex+1,maxindex-startindex).ToList());
}

// Generate the permutations of the input sequences
IEnumerable<IEnumerable<int>> emptyProduct = new[] { Enumerable.Empty<int>() };
var result = sequences.Aggregate( 
    emptyProduct, 
    (accumulator, sequence) =>  
      from accseq in accumulator  
      from item in sequence
      where accseq.All(accitem => accitem < item)
      select accseq.Concat(new[] {item}));                

// Show the result
foreach (var x in result)
{
    Console.WriteLine(x);
}

Upvotes: 2

Priyank
Priyank

Reputation: 10623

Try this function.

public static IEnumerable<IEnumerable<T>> Permute<T>(IEnumerable<T> list)
        {
            if (list.Count() == 1)
                return new List<IEnumerable<T>> { list };

            return list.Select((a, i1) => Permute(list.Where((b, i2) => i2 != i1)).Select(b => (new List<T> { a }).Union(b)))
                       .SelectMany(c => c);
        }

//Here Range(startindex, count)

List<int> list1 = Enumerable.Range(1, 3).ToList();

//generates all permutations

var permutationlist = Permute(list1);

enter image description here

Upvotes: 0

Related Questions