2009-10-17 1 views
1

В самом начале позвольте выразить искреннюю благодарность Marc Gravel, Dahlbyk, а остальное для оказания мне помощи в применении linq практически.Решающий мозговой тизер с использованием linq

Следующие несколько вопросов, с которыми я столкнулся в интервью, чтобы решить применение Linq. Поскольку я не знаком с Linq, я решил его без использования Linq.

Я ценю ответы, которые помогают мне решить их с помощью LinQ

Спасибо заранее.


Вопрос 1: Проблема заключается в том, чтобы найти различные цифры, так что в любом порядке, они используются, чтобы сделать три-значное число, это число не делится на:

3 , 5,7,11,13 или 17

Чтобы убедиться, что нет ambuigity, предположим, что три цифры являются а, б, и c.Then, ни одна из комбинации цифр:

говорят ABC, ACB, BAC, BCA, такси и сЬа будет разделить на 3,5,7,11,13 или 17.

Пример:

Когда я беру 248 ни один из его комбинации (284,428,482,842,824) будет точно делится на 3,5,7,11,13 или 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 (testpassed && dcount==6) 

    { 

    Console.WriteLine(StrToDigit); 

    } 

} 
} 
}    
} 

(кодирование работает)

Вопрос 2:

Задача состоит в том, чтобы упорядочить элемент в матрице так, чтобы все строки, столбцы и диагонали добавлялись к одной и той же сумме. (Бит-проблема в кодировании, я пытаюсь ее решить).

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

пример:

Одно из решений состоит в следующем:

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

ответ

4

Для первого:

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

Для второго - не элегантно, но он работает (возвращает 8 перестановок образца):

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

Как насчет перестановок с двумя номерами одинаковыми? Почему вы не тестируете 113, 131, 311? –

+0

(ответили на ваш ответ) –

+0

Ах, вы правы, проблема вызывает «разные цифры». –

5

Я согласен с тем, что решение Марка для вашей первой проблемы - разумный подход. Но я думаю, что здесь есть более большой вопрос: «Как я могу решить такие проблемы, как LINQ-ish?»

Обратите внимание, что ваше решение полностью «процедурное» и «императивное». Ваш код определяет последовательность шагов, которые вы выполняете один за другим, с глубокими циклами. Каждый шаг по пути не имеет смысла, если вы не поймете его место в большом целом.

Есть две идеи, которые я хотел бы использовать при решении задач с помощью LINQ:

  • Опишите, что программа делает логически, а не перечисляя ряд команд
  • Охарактеризуйте проблему a запрос к набору данных, а не как процедура для последующего использования.

Итак, что же это наш набор данных? Мы хотим отфильтровать некоторые элементы из множества всех комбинаций из трех цифр.

Как их фильтровать? Перенесите цифры, а затем выполните проверку делимости на каждую перестановку.

ОК, так что теперь мы имеем структуру для нашей программы:

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

И теперь вы можете продолжить разрушение каждого из них дальше, решая каждый суб-проблемы с помощью LINQ, в свою очередь.

То же самое касается проблемы с «магическим квадратом»; вы ищете перестановку с определенным свойством, поэтому напишите генератор перестановок, напишите фильтр и выполните его.

+0

Re comment; см. комментарий «Обеспечить, чтобы в задаче не было никакой ошибки»; это связано с неповторяющимися перестановками. –

+0

В частности «скажем, abc, acb, bac, bca, cab и cba разделится на 3,5,7,11,13 или 17.» –