开发者

Solving brain teaser using linq

At the very outset let me express my sincere thanks to Marc Gravel,Dahlbyk and the rest for helping me to apply linq practically.

The following are few questions which I have faced in an interview to solve applying Linq. As I am not familiar with Linq I solved it without using Linq.

I appreciate the answers which helps me to solve them using Linq

Thanks in advance.


Question 1: The Problem is to find different digits such that,in whatever order they are used to make a three-digit number,that number will not be divisible by:

3,5,7,11,13 or 17.

To ensure that there is no ambuigity,suppose the three digits are a,b,and c.Then,none of the combination of the numbers:

say abc,acb,bac,bca,cab and cba will divide by 3,5,7,11,13 or 17.

Example :

When I take 248 none of its combination(284,428,482,842,824) will exactly divisible by 3,5,7,11,13 or 17.

public void FindingRareNumbers()
{
   for (int i = 1; i <= 9; i++)
   {
    for (int j = 1; j <= 9; j++)
    {
      for (int k = 1; k <= 9; k++)
      {
   //to form the three digit
    string digit = i.ToString() + j.ToString() + k.ToString();
   //converting to  integer
    int StrToDigit = Convert.ToInt32(digit);
    char[] digitcombination = digit.ToCharArray();
    string PossibleCombination = "";

    bool testpassed = false;
    int dcount = 0;
     #region different possible combinations 

       for (int p = 0; p <= 2; p++)
        {
         for (int q = 0; q <= 2; q++)
          {
            for (int r = 0; r <= 2; r++)
            {
             // The following condition avoid the repeatance 
              // of digit like 111,111,111
               if (p != q && p != r && r != q)
               {
                  PossibleCombination =  

                  digitcombination[p].ToString() +                               
                  digitcombination[q].ToString() +
                  digitcombination[r].ToString();

                  int num =  Convert.ToInt32(PossibleCombination);

                  if (num % 3 != 0 && num % 5 != 0 && num % 7 != 0 
                      && num % 11 != 0 && num % 11 != 0
                      && num % 13 != 0 && num % 17 != 0)
                    {
                       //count is increment for 6 times
                       // it satisfies the condition    
                         dcount++;
                         testpassed = true;
                   }

             }

          }
      }
  }

   #endregion combination
  if (testp开发者_开发问答assed && dcount==6)

  {

    Console.WriteLine(StrToDigit);

  }

 }
}
}               
}

(coding is working)

Question 2:

The task is to arrange the element in matrix so that all rows,columns,and diagonals add up to the same total.(Bit problem in coding ,I am trying to solve it).

------------------
1     2        3  
-----------------
4     5        6
-----------------
7     8        9
-----------------

example :

The one of solutions is as follows:

-----------
2   9   4
-----------
7   5   3
----------
6   1   8
----------


I agree that Marc's solution to your first problem is a reasonable approach. But I think there's a larger question here, which is "how do I solve problems like this in a LINQ-ish manner?"

Notice how your solution is completely "procedural" and "imperative". Your code specifies a series of steps that you would execute, one after the other, with deep loops. Each step along the way is meaningless unless you understand its place in the larger whole.

There are two ideas I like to use when solving problems with LINQ:

  • Describe what the program is doing logically, rather than listing a series of commands
  • Characterize the problem as a query against a data set rather than as a procedure to follow.

So, what's our data set? We wish to filter out some elements from the set of all combinations of three digits.

How do we filter them? Permute the digits and then perform a divisibility check on each permutation.

OK, so now we have a structure for our program:

var query = from c in ThreeDigitCombinations() 
            where DivisibilityCheckPasses(c) 
            select c;
foreach(Combination result in query) Console.WriteLine(result);

And now you can continue breaking down each of those further, solving each sub-problem using LINQ in turn.

Same goes for your "magic square" problem; you're looking for a permutation that has a certain property, so write a generator of permutations, write a filter, and execute it.


For the first:

static IEnumerable<int> Permute(int x, int y, int z)
{
    yield return x * 100 + y * 10 + z;
    yield return x * 100 + z * 10 + y;
    yield return y * 100 + x * 10 + z;
    yield return y * 100 + z * 10 + x;
    yield return z * 100 + x * 10 + y;
    yield return z * 100 + y * 10 + x;
}
static void Main()
{
    var divs = new[] {3,5,7,11,13,17};
    // combinations of 1-9
    var combinations =
              from x in Enumerable.Range(1, 7)
              from y in Enumerable.Range(x + 1, 8 - x)
              from z in Enumerable.Range(y + 1, 9 - y)
              select new { x, y, z };

    // permute
    var qry = from comb in combinations
              where !Permute(comb.x, comb.y, comb.z).Any(
                i => divs.Any(d => i % d == 0))
              select comb;

    foreach (var answer in qry)
    {
        Console.WriteLine("{0}, {1}, {2}", answer.x, answer.y, answer.z);
    }
}

For the second - not elegant, but it works (returns the 8 permutations of the sample):

static void Main() {
    var data = Enumerable.Range(1, 9);
    var magicSquares =
        // generate 1st row and deduce the target
        from a in data let arrA = new[] { a }
        from b in data.Except(arrA) let arrB = new[] { a,b }
        from c in data.Except(arrB) let arrC = new[] { a,b,c }
        let target = a + b + c
        // generate 2nd row and filter to target matches
        from d in data.Except(arrC) let arrD = new[] { a,b,c,d }
        from e in data.Except(arrD) let arrE = new[] { a,b,c,d,e }
        from f in data.Except(arrE) let arrF = new[] { a,b,c,d,e,f }
        where d + e + f == target 
        // generate 3rd row and filter to target matches
        from g in data.Except(arrF) let arrG = new[] { a,b,c,d,e,f,g }
        from h in data.Except(arrG) let arrH = new[] { a,b,c,d,e,f,g,h }
        from i in data.Except(arrH)
        where g + h + i == target
        // filter columns
           && a + d + g == target
           && b + e + h == target
           && c + f + i == target
        // filter diagonals
           && a + e + i == target
           && c + e + g == target 
       select new {a,b,c,d,e,f,g,h,i};

    foreach (var row in magicSquares)
    {
        Console.WriteLine("{0} {1} {2}", row.a, row.b, row.c);
        Console.WriteLine("{0} {1} {2}", row.d, row.e, row.f);
        Console.WriteLine("{0} {1} {2}", row.g, row.h, row.i);
        Console.WriteLine();
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜