Алгоритм судоку в C#

[^<]/ будет соответствовать e/, а t/

использовать взамен просмотра, у него будет желаемое поведение, чтобы рассматривать / только как разделитель, если это не закрывающий тег

[ 119] На regex101.com

(?

Целое регулярное выражение

(;|:|(?

5
задан Community 23 May 2017 в 11:44
поделиться

7 ответов

Удачный для Вас я создал решатель судоку сам не слишком долго назад :) Все это было приблизительно 200 строками C#, и он решит самые жесткие загадки, я мог найти строку через 4 секунды или меньше.

Производительность, вероятно, не является настолько большой из-за использования.Count, но это должно работать:

!a.Any(i => i != 0 && a.Where(j => j != 0 && i == j).Count >  1)

Кроме того, j != 0 часть не действительно необходима, но она должна помочь вещам, выполненным немного быстрее.

[редактирование:] ответ kvb дал мне другую идею:

!a.Where(i => i != 0).GroupBy(i => i).Any(gp => gp.Count() > 1)

Отфильтруйте 0 перед группировкой. Хотя на основе того, как IEnumerable работает, он не может иметь значения никто.

Так или иначе, Для лучшей замены производительности .Count > 1 в любом из тех с новым дополнительным методом IEnumerable, который похож на это:

bool MoreThanOne(this IEnumerable<T> enumerable, Predictate<T> pred)
{
    bool flag = false;
    foreach (T item in enumerable)
    {
       if (pred(item))
       {
          if (flag)
             return true;
          flag = true;
       }
    }
    return false;
}

Это, вероятно, не будет иметь значения слишком много, так как массивы ограничены 9 объектами, но если Вы называете его много, это могло бы сложить.

10
ответ дан 18 December 2019 в 05:25
поделиться

Это приблизительно в 50-250 раз быстрее, чем решение LINQ (в зависимости от того, как рано дубликат найден):

public static bool IsValid(int[] values) {
    int flag = 0;
    foreach (int value in values) {
        if (value != 0) {
            int bit = 1 << value;
            if ((flag & bit) != 0) return false;
            flag |= bit;
        }
    }
    return true;
}
17
ответ дан 18 December 2019 в 05:25
поделиться

!a.GroupBy(i => i).Any(gp => gp.Key != 0 && gp.Count() > 1)

3
ответ дан 18 December 2019 в 05:25
поделиться

Я обычно осуждаю решения, которые включают полученные переменные, но у меня было желание записать это:

bool hasRepeating = false;
int previous = 0;

int firstDuplicateValue = a
  .Where(i => i != 0)
  .OrderBy(i => i)
  .FirstOrDefault(i => 
  {
    hasRepeating = (i == previous);
    previous = i;
    return hasRepeating;
  });

if (hasRepeating)
{
  Console.WriteLine(firstDuplicateValue);
}
1
ответ дан 18 December 2019 в 05:25
поделиться

Как насчет:

var itIsOk = a.Where(x => x > 0).Distinct().Count() == a.Where(x => x > 0).Count();

Обоснование: Сначала создайте перечисление без 0s. Из остающихся чисел, если его отличный список является той же длиной как фактический список, то нет никаких повторений.

или: Если список уникальных чисел меньше, чем фактический список, то у Вас должно быть повторное число.

Это - версия остроты. A. Где (x => x> 0) список мог быть факторизован.

var nonZeroList = a.Where(x => x > 0).ToList();
var itIsOk = nonZeroList.Distinct().Count() == nonZeroList.Count();
1
ответ дан 18 December 2019 в 05:25
поделиться

Почему Вы хотите замысловатую строку кода Linq, вместо того, чтобы обернуть эффективное внедрение теста в дополнительном методе и назвать это?

var a = new int[9] {1,2,3,4,5,6,7,8,9};
var itIsOk = a.HasNoNonZeroRepeats();

Одна реализация NoNonZeroRepeats могла быть должна использовать 9 самых низких битов короткого для указания на присутствие значения в массиве, дав O (длина (a)) тест без использования динамической памяти. Linq является милым, но если Вы только не используете его по эстетическим причинам (Вы конкретно не говорите запись решателя судоку с помощью только Linq в качестве осуществления), это, кажется, просто добавляет сложность здесь.

2
ответ дан 18 December 2019 в 05:25
поделиться

Это старый вопрос, но недавно мне было указано на однострочное решение с использованием пользовательского SQL Oracle для делать древовидные структуры. Я подумал, что было бы неплохо преобразовать это в Linq.

Вы можете прочитать больше в моем блоге о том, как решать судоку в одной строке Linq

Вот код:

public static string SolveStrings(string Board)
{
    string[] leafNodesOfMoves = new string[] { Board };
    while ((leafNodesOfMoves.Length > 0) && (leafNodesOfMoves[0].IndexOf(' ') != -1))
    {
        leafNodesOfMoves = (
            from partialSolution in leafNodesOfMoves
            let index = partialSolution.IndexOf(' ')
            let column = index % 9
            let groupOf3 = index - (index % 27) + column - (index % 3)
            from searchLetter in "123456789"
            let InvalidPositions =
            from spaceToCheck in Enumerable.Range(0, 9)
            let IsInRow = partialSolution[index - column + spaceToCheck] == searchLetter
            let IsInColumn = partialSolution[column + (spaceToCheck * 9)] == searchLetter
            let IsInGroupBoxOf3x3 = partialSolution[groupOf3 + (spaceToCheck % 3) +
                (int)Math.Floor(spaceToCheck / 3f) * 9] == searchLetter
            where IsInRow || IsInColumn || IsInGroupBoxOf3x3
            select spaceToCheck
            where InvalidPositions.Count() == 0
            select partialSolution.Substring(0, index) + searchLetter + partialSolution.Substring(index + 1)
                ).ToArray();
    }
    return (leafNodesOfMoves.Length == 0)
        ? "No solution"
        : leafNodesOfMoves[0];
}
2
ответ дан 18 December 2019 в 05:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: