2012-02-01 35 views
5

Olası Çoğalt:
Generating all Possible CombinationsN-enumerable?

emin değilim nasıl ifade sorusunu için; ama bir LINQ ifadesi kullanarak çözebildiğim aptal bir mantık bulmacası üzerinde çalışıyordum. İlgili kod aşağıdaki gibi görünüyordu:

(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}) 

Yani temelde nerede fıkrada kriterlere uygun A, B, C, D tüm kombinasyonları üretiyor.

Şimdi ne yapmaya çalışıyorum bu yüzden N değerlerinin yerine sadece dört ile aynı şeyi yapabileceği bu genelleme olduğunu. Örneğin, 3 değerlerle - eşdeğer kod şöyle olacaktır: Doğal

(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}) 

, kodu değiştirmedim istemiyorum - Ben arayıp bir tamsayı sağlamak ve doğru dönmek var bir işlev istiyorum nesne.

Birkaç yanlış girişimleri yaptık; ama gerçekten böyle bir şeyi nasıl yapacağımı göremiyorum. Birisi bana doğru yönde işaret edebilir mi?

+4

Eric Lippert'ın http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian- ([Bu kendi blog sitesinde] birçok dizinin bilgisayar ürünleri ile ilgili ürün-ile-linq.aspx). O yardımcı olabilir. –

+0

@AnthonyPegram - Bu mükemmel. Tam olarak aradığım şey. Bunu bir cevap olarak göndermek isterseniz kabul ediyorum. –

+0

Bu benim * yanıtım değil. ; Kredi nedeniyle nerede kredi vermek isterseniz), [burada denemek] (http://stackoverflow.com/a/3098381/414076) –

cevap

0

bağlantıları okumadınız mı ve bu bile doğru yaklaşımdır emin değilim, ama (örnekte olduğu gibi veya 20) neden her düğüm 40 sahip derinlik n bir ağaç yürüyorlar hayal bile çocuklar? Daha sonra, bu gibi görünecektir:

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())); 
    } 
}