Create a LINQ Killer Sudoku Cage Solver When playing Killer Sudoku I find myself repeatedly writing stuff like this:

12/3
921
831
741
732
651
642
543


and then crossing out the combinations that include say 9, 7, and 6  

IE I need a list of any 3 digits between 1 and 9 that add up to 12, excluding 9, 7, and 6 because they are already in the house.

So I wrote a Linq query to run in LinqPad that does this. However its pretty specific. Here is the implementation for 3 numbers:

var num=3;
var target=12;
var exceptions=new List&lt;int&gt;{9,7,6};

var List1 = new List&lt;int&gt;{1,2,3,4,5,6,7,8,9};
var List2 = new List&lt;int&gt;{1,2,3,4,5,6,7,8,9};
var List3 = new List&lt;int&gt;{1,2,3,4,5,6,7,8,9};

// Make a Cartesian join of the three lists
// Filter out the stuff that we want
// Sort the result from highest to lowest
var combo = (from l1 in List1
        from l2 in List2
        from l3 in List3        // Cartesian product    
        where l1 &gt; l2 &amp;&amp; l2 &gt; l3    // exclude duplicates
        &amp;&amp; l1 + l2 + l3 == target   // add up to the target 
        &amp;&amp; !exceptions.Contains(l1) // exclude exceptions
        &amp;&amp; !exceptions.Contains(l2)
        &amp;&amp; !exceptions.Contains(l3)
        select new List&lt;int&gt;{l1, l2, l3})                       
        .OrderByDescending (c =&gt;c[0] ) 
        .ThenByDescending (d =&gt; d[1])
        .ThenByDescending (e =&gt; e[2]);

Console.WriteLine(string.Format("{0}/{1}", target, num));
foreach(var item in combo){ 
for (var i=0; i&lt; num;i++){
    Console.Write(item[i]);
}       
Console.WriteLine();
}
Console.Write("excluding");
foreach(var i in exceptions){
    Console.Write(string.Format(" {0} ",i));
}


I have found it pretty useful but is there a better and more general way of implementing this?
Naming

Use camelCase for local variable names. And, use a meaningful name if possible.

//var List1 = new List&lt;int&gt;{1,2,3,4,5,6,7,8,9};
var validNumbers = new List&lt;int&gt;{1,2,3,4,5,6,7,8,9};


Use pluralized noun for variable of collection type.

//var combo = ... /*combo contains all possible combinations, not just one*/
var combos


Code


You don't need to enumerate the numbers 1 to 9. A Enumerable.Range will do the job.
The chain of !exceptions.Contains(x) is rather inefficient and redundant. You can avoid them by removing the exceptions from the start with IEnumerable.Except.
You can reuse the same list in your LINQ.
You can reuse the same name for your lambdas given they are not within the same parentheses.  (Not really a big problem)



Result : 

var validNumbers = Enumerable.Range(1, 9).Except(exceptions);
var combos = (from a in validNumbers
              from b in validNumbers
              from b in validNumbers       // Cartesian product    
              where a &gt; b &amp;&amp; b &gt; c &amp;&amp;      // exclude duplicates
                    a + b + c == target    // add up to the target 
              select new List&lt;int&gt;{ a, b , c})
             .OrderByDescending(x =&gt; x[0]) 
             .ThenByDescending(x =&gt; x[1])
             .ThenByDescending(x =&gt; x[2]);




In the last 2 blocks of the code, Console.Write was repeatedly called within the for loop. You can join them together with String.Join before printing it to the console.

Results :

foreach(var item in combos)
    Console.WriteLine(string.Join("", item));

Console.Write("excluding " + string.Join(" ", exceptions));




Final Code

This can be directly copied to LinqPad and ran.

void Main()
{
    string buffer;
    int target, elementCount;

    //get target
    Console.WriteLine("&gt;&gt; Target is ..?");

    while(!int.TryParse(buffer = Console.ReadLine(), out target))
        Console.WriteLine("\tInvalid input : {0}", buffer);
    Console.WriteLine(target);

    //get elementCount
    Console.WriteLine("&gt;&gt; Number of elements is ..?");

    while(!int.TryParse(buffer = Console.ReadLine(), out elementCount) ||
          1 &gt; elementCount || elementCount &gt; 6)
        Console.WriteLine("\tInvalid input : {0}", buffer);
    Console.WriteLine(elementCount);
    Console.WriteLine(/*Empty Line*/);

    //get exceptions
    var validNumbers = Enumerable.Range(1, 9);
    IEnumerable&lt;int?&gt; exceptions;
    Console.WriteLine("&gt;&gt; Exceptions are ..? (separated with comma like : 1,2,3)");

    while(!TryParseExceptions(buffer = Console.ReadLine(), out exceptions))
        Console.WriteLine("\tInvalid input : {0}", buffer);
    Console.WriteLine(string.Join(" ", exceptions.OrderBy(x =&gt; x)));

    Console.WriteLine(/*Empty Line*/);
    CalculateCombinations(target, elementCount, exceptions.Select(e =&gt; e.Value).Distinct());
}

int? ToNullableInt(string value)
{
    int number;
    return int.TryParse(value.Trim(), out number) ? (int?)number : null;
}
bool TryParseExceptions(string value, out IEnumerable&lt;int?&gt; exceptions)
{
    //const int MinValue = 1, MaxValue = 9;
    exceptions = value == ""
        ? Enumerable.Empty&lt;int?&gt;()
        : value.Split(',').Select(ToNullableInt);

    return exceptions.All(e =&gt; e.HasValue &amp;&amp; (1 &lt;= e.Value &amp;&amp; e.Value &lt;= 9)); //less verbose but magical...
    //return exceptions.All(e =&gt; e.HasValue &amp;&amp; (MinValue &lt;= e.Value &amp;&amp; e.Value &lt;= MaxValue));
}

// Define other methods and classes here
void CalculateCombinations(int target, int elementCount, IEnumerable&lt;int&gt; exceptions)
{
    var validNumbers = Enumerable.Range(1, 9).Except(exceptions);

    // Make a Cartesian join of the three lists
    // Filter out the stuff that we want
    // Sort the result from highest to lowest
    var combos = validNumbers.CartesianProduct(elementCount)     // Cartesian product 
                            .Where(x =&gt; x.GreaterThanNext() &amp;&amp;   // exclude duplicates
                                        x.Sum(y =&gt; y) == target) // add up to the target 
                            .OrderByDescending(x =&gt; x.First());  // sort from the 1st number to...

    for(int i = 1; i &lt; elementCount; i++)
    {
                    ///i would be incremented when the ienumerable unfolds
        var index = i;
        combos = combos.ThenByDescending(x =&gt; x.ElementAt(index));   // ... the [n]th
    }

    Console.WriteLine(string.Format("{0}/{1}", target, elementCount));

    foreach(var item in combos)
        Console.WriteLine(string.Join("", item));

    Console.Write("excluding : " + string.Join(" ", exceptions.OrderBy(x =&gt; x)));
}

//credit : http://ericlippert.com/2010/06/28/computing-a-cartesian-product-with-linq/
//slightly altered to reuse the same sequence

public static class Extensions
{
    public static IEnumerable&lt;IEnumerable&lt;T&gt;&gt; CartesianProduct&lt;T&gt;(this IEnumerable&lt;T&gt; sequence, int repeat) 
    {
        IEnumerable&lt;IEnumerable&lt;T&gt;&gt; result =  new[] { Enumerable.Empty&lt;T&gt;() };

        for(int i = 0; i &lt; repeat; i++)
        { 
            // don't close over the loop variable (fixed in C# 5 BTW)
            var s = sequence; 
            // recursive case: use SelectMany to build 
            // the new product out of the old one 
            result = from seq in result 
                    from item in s 
                    select seq.Concat(new[] {item}); 
        }

        return result; 
    }

    public static bool GreaterThanNext(this IEnumerable&lt;int&gt; sequence)
    {
        if (sequence.Count() &lt; 2) return true;

        var previous = int.MaxValue;
        foreach(var item in sequence)
            if(previous &lt;= item)
                return false;
            else previous = item;

        return true;
    }
}


Example of result : 

&gt;&gt; Target is ..?
25
&gt;&gt; Number of elements is ..?
4

&gt;&gt; Exceptions are ..? (separated with comma like : 1,2,3)
1

25/4
9862
9853
9763
9754
8764
excluding : 1