5

Possible Duplicate:
Generating all Possible Combinations

I'm not sure how to phrase the question; but I was working on a silly logic puzzle that I was able to solve using a LINQ statement. The relevant code looked like this:

(from myA in Enumerable.Range(1, 40)
 from myB in Enumerable.Range(1, 40)
 from myC in Enumerable.Range(1, 40)
 from myD in Enumerable.Range(1, 40)
 where myA + myB + myC + myD == 40
    && myA <= myB
    && myB <= myC
    && myC <= myD
 select new[] {myA, myB, myC, myD})

So it's basically generating all the combinations of A,B,C D that meet the criteria in the Where clause.

What I'm trying to do now is generalize this so I can do the exact same thing with N values instead of just four. For example, with 3 values - the equivalent code would be:

(from myA in Enumerable.Range(1, 40)
 from myB in Enumerable.Range(1, 40)
 from myC in Enumerable.Range(1, 40)
 where myA + myB + myC == 40
    && myA <= myB
    && myB <= myC
 select new[] {myA, myB, myC})

Naturally, I don't want to modify the code - I want a function that I can call and provide an integer and have it return the correct object.

I've made a few misguided attempts; but I really can't see how to do something like that. Can someone point me in the right direction?

Community
  • 1
  • 1
Rob P.
  • 14,921
  • 14
  • 73
  • 109
  • 4
    Eric Lippert [blogged on this](http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx) in regards to computing products of many sequences. It might help. – Anthony Pegram Feb 01 '12 at 20:52
  • @AnthonyPegram - That is perfect. Exactly what I'm looking for. If you want to post that as an answer, I'd accept it. – Rob P. Feb 01 '12 at 20:55
  • It's not *my* answer. ;) If you'd like to give credit where credit is due, [try here](http://stackoverflow.com/a/3098381/414076) – Anthony Pegram Feb 01 '12 at 20:56

1 Answers1

0

Haven't read the links, and I'm not sure this is even the correct approach, but why not imagine we are walking a tree of depth n with every node having 40 (or 20 as is in the example) children? It will look like this, then:

class Program {
    static void Main(string[] args) {
        Walk(3).Where(l => l.Sum() == 20 &&
            l.Skip(1).Where((num, i) => num < l[i]).Count() == 0)
        .ToList().ForEach(l => Console.WriteLine(string.Join(" ", l)));
        Console.ReadLine();
    }

    static IEnumerable<List<int>> Walk(int depth) {
        return depth == 0 ? 
            new[] { new List<int>()} :
            Enumerable.Range(1,20).SelectMany(i =>
                Walk(depth - 1).Select(l => l.Concat(new[] {i}).ToList()));
    }
}
user1096188
  • 1,809
  • 12
  • 11