Как сделать судоку в python

Добавил пользователь Владимир З.
Обновлено: 04.10.2024

привет, ребята, я новичок в программеminG, и у меня есть этот проект для моей школы. Я должен сделать Sudoku в python, и это то, что я сделал, но он не закончен, и он имеет некоторые ошибки, например, если он добавляет один столбец, а затем он понимает, что это число уже в рове. Я не знаю, как чтобы удалить его из столбца. ПОЖАЛУЙСТА ПОМОГИ

поэтому, если переменная error равна True вы не вызываете функцию unos .

и весь код будет:

код все еще не очень хорош, но эта проблема в вашем программировании вы должны использовать для циклов (ваши переменные, в которых вы храните информацию о строках, столбцах и блоках, должны быть в списке, а затем вы должны проверить, существует ли введенное число в строке, используя цикл и один, если, а не используя девять ifs: например, вместо использования:

вы должны использовать:

а затем, когда вы проверяете, находится ли введенный номер в столбце вместо использования:

вы должны использовать:

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

Также ваша программа судоку имеет другие проблемы, такие как: вы можете вводить номер на месте, где номер уже существует, вы не можете удалить введенный номер.

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

Я играл с моим собственным решателем Sudoku и искал некоторые указатели на хороший и быстрый дизайн, когда я наткнулся на это:

Моя собственная реализация решает Sudokus так же, как я решаю их в своей голове, но как работает этот критический алгоритм?

ОТВЕТЫ

Ответ 1

Ну, вы можете сделать немного проще, установив синтаксис:

Хорошо, поэтому этот script ожидает аргумент командной строки и вызывает на нем функцию r. Если в этой строке нет нулей, r завершает и распечатывает свой аргумент.

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

Интересен цикл: for m in'%d'%5**18

Почему 5 ** 18? Оказывается, что '%d'%5**18 оценивается как '3814697265625' . Это строка с каждой цифрой 1-9 хотя бы один раз, поэтому, возможно, она пытается разместить каждую из них. На самом деле, похоже, это то, что делает r(a[:i]+m+a[i+1:]) : рекурсивный вызов r, причем первый пробел заполняется цифрой из этой строки. Но это происходит только в том случае, если предыдущее выражение ложно. Давайте посмотрим на это:

m in [(i-j)%9*(i/9^j/9)*(i/27^j/27|i%9/3^j%9/3) or a[j] for j in range(81)]

Таким образом, размещение выполняется только в том случае, если m не находится в списке монстров. Каждый элемент является либо числом (если первое выражение отличным от нуля), либо символом (если первое выражение равно нулю). m исключается как возможная подстановка, если она появляется как символ, что может произойти только в том случае, если первое выражение равно нулю. Когда выражение 0?

Он состоит из трех частей, которые умножаются:

  • (i-j)%9 , который равен нулю, если я и j кратно 9, т.е. один и тот же столбец.
  • (i/9^j/9) , который равен нулю, если i/9 == j/9, т.е. одна и та же строка.
  • (i/27^j/27|i%9/3^j%9/3) , который равен нулю, если оба они равны нулю:
    • i/27^j^27 , который равен нулю, если i/27 == j/27, т.е. тот же блок из трех строк
    • i%9/3^j%9/3 , который равен нулю, если i% 9/3 == j% 9/3, т.е. тот же блок из трех столбцов

    Если любая из этих трех частей равна нулю, все выражение равно нулю. Другими словами, если я и j делят строку, столбец или блок 3x3, то значение j не может использоваться в качестве кандидата для пробела в i. Aha!

    Обратите внимание, что если ни одно из мест размещения не будет работать, r вернется и вернется к точке, где может быть выбрано что-то еще, поэтому это базовый алгоритм первой глубины.

    Добавление: как я буду переписывать его в качестве программиста по обслуживанию (эта версия имеет примерно 93-кратное ускорение:)

    Ответ 2

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

    Ответ 3

    r(a) - это рекурсивная функция, которая пытается заполнить a 0 на доске на каждом шаге.

    i=a.find('0');~i or exit(a) - это завершение на успех. Если на доске больше значений 0 , мы закончили.

    m - это текущее значение, которое мы попытаемся заполнить 0 .

    m in[(i-j)%9*(i/9^j/9)*(i/27^j/27|i%9/3^j%9/3)or a[j]for j in range(81)] оценивается правдоподобно, если неправильно ввести m в текущий 0 . Пусть псевдоним "is_bad". Это самый сложный бит.:)

    is_bad or r(a[:i]+m+a[i+1:] - условно-рекурсивный шаг. Он рекурсивно попытается оценить следующий 0 на доске, если текущий кандидат на решение окажется разумным.

    for m in '%d'%5**18 перечисляет все числа от 1 до 9 (неэффективно).

    Ответ 4

    Многие из коротких решателей судоку просто рекурсивно пробовали все возможные юридические номера до тех пор, пока они не заполнили ячейки. Я не разделял это, но просто просматривая его, похоже, что он делает.

    Ответ 5

    Код фактически не работает. Вы можете проверить это самостоятельно. Вот пример неразрешенной головоломки судоку:

    что не соответствует решению. На самом деле вы уже видите противоречие, два 1s в первой строке.

    Ответ 6

    Как я могу создать код, который может решить игру Sudoku, используя связанный список без использования массива с использованием С++?

    Итак, я пытаюсь создать функцию, которая будет принимать список списков, каждый из которых состоит из 9 целых чисел, пронумерованных от 1 до 9, и возвращать логическое значение, если это допустимое решение для судоку. Прямо сейчас мне удалось решить часть проблемы с проверкой строк и столбцов, но я застрял на реализации проверки трех на три поля. Вот мой код.

    По сути, My должен был проверить все три фактора, необходимые для его истинности, затем вернуть True, если все три истинны, иначе вернуть false. Любая помощь?

    Предложение по улучшению вашего кода: используйте более удачные имена переменных. Я не могу точно узнать, что означают ваши a сквозные f переменные, не копаясь в кучке кода. Если бы у них были значащие имена, я мог бы сразу увидеть проблемы. Однобуквенные имена переменных часто бывают плохими, за исключением очень ограниченных ситуаций ( i и j часто являются традиционными индексными переменными в циклах x , y и z имеют давнюю математическую традицию в качестве имен координат и т. Д.).

    Каждый раз, когда вы устанавливаете переменную False , вы можете просто вернуться False . Вам также может быть интересно взглянуть на этот set класс.

    @emodendroket Если этот вопрос был решен в другом месте на Stack Overflow, то он может быть отмечен как повторяющийся. Однако нет ничего плохого в том, чтобы задать вопрос, на который был дан ответ извне.

    Не уверен, что это ваша проблема, но с этим кодом есть довольно очевидная проблема:

    Похоже, вы думаете, что это создает 3 копии сетки, но это не так. Он создает три разных ссылки на один и тот же объект. Это означает, что ваше i.sort() включение a повлияет на логику b позже.

    Что вам нужно сделать, так это скопировать объект. То, что это вложенный список, делает это немного сложнее, но простой способ сделать это - использовать библиотечную функцию deepcopy:


    Более простым решением может быть создание копии при сортировке подсписка с помощью sorted функции. Тогда нет необходимости иметь несколько копий сетки!

    Одна из основных проблем с тем, как работает ваш код, заключается в том, что вы его используете list.sort , а это означает, что сама сетка изменяется . Рассмотрите возможность использования sorted , который работает со всеми итерациями и вместо этого возвращает копию:

    Это также означает, что вам не нужно пытаться дублировать вручную grid . Если вам нужна помощь в дублировании list (особенно многомерного list ), ознакомьтесь с этим вопросом .

    Все комментарии приветствуются.

    2. exactcover.py

    3. sudoku.py

    4. Примеры

    2 ответа

    Это не совсем правильно:

    Он обещает отменить произвольный выбор i , но на самом деле выдает последний из self.solution . Поскольку вы используете только, если для отмены последнего выбора, я предлагаю отказаться от параметра:

    На самом деле выбор-unchoose-образец немного неудобен для меня. Вместо этого я предпочел бы функциональное программирование. Другая идея, которая заставила бы меня чувствовать себя более комфортно, заключалась бы в создании менеджера контекста:

    У меня есть только незначительный комментарий:

    В ExactCover.__init__ , я бы использовал iteritems , а не итерировал по клавишам constraints :

    Вы написали хороший код, учтенный в приятные, мелкие функции с ясной целью. Молодцы!

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

    Популярные теги

    Читайте также: