Реализуйте самый короткий решатель судоку, используя догадки. Поскольку я получил несколько запросов, я добавил этот вопрос в качестве альтернативного вопроса для тех, кто желает внедрить решение для грубой силы судоку.
Головоломка Судоку:
| 1 2 3 | 4 5 6 | 7 8 9
-+-----------------------
A| 3 | 1 |
B| 6 | | 5
C| 5 | | 9 8 3
-+-----------------------
D| 8 | 6 | 3 2
E| | 5 |
F| 9 3 | 8 | 6
-+-----------------------
G| 7 1 4 | | 9
H| 2 | | 8
I| | 4 | 3
Ответ:
| 1 2 3 | 4 5 6 | 7 8 9
-+-----------------------
A| 8 3 2 | 5 9 1 | 6 7 4
B| 4 9 6 | 3 8 7 | 2 5 1
C| 5 7 1 | 2 6 4 | 9 8 3
-+-----------------------
D| 1 8 5 | 7 4 6 | 3 9 2
E| 2 6 7 | 9 5 3 | 4 1 8
F| 9 4 3 | 8 1 2 | 7 6 5
-+-----------------------
G| 7 1 4 | 6 3 8 | 5 2 9
H| 3 2 9 | 1 7 5 | 8 4 6
I| 6 5 8 | 4 2 9 | 1 3 7
Правила:
- Предположим, что все лабиринты разрешимы только логикой.
- Весь ввод будет длиной 81 символ. Недостающие символы будут 0.
- Выведите решение в виде одной строки.
- «Сетка» может храниться внутри, как вы пожелаете.
- Решение должно быть с использованием метода угадывания грубой силы.
- Решения должны быть решены в разумные сроки.
Пример ввода / вывода:
>sudoku.py "030001000006000050500000983080006302000050000903800060714000009020000800000400030"
832591674496387251571264983185746392267953418943812765714638529329175846658429137
code-golf
game
puzzle-solver
sudoku
snmcdonald
источник
источник
Ответы:
к (72 байта)
Кредит на это идет Артуру Уитни, создателю языка K.
источник
Python, 188 байт
Это еще одна сокращенная версия моего выигравшего представления для CodeSprint Sudoku , модифицированного для ввода в командной строке вместо стандартного ввода (согласно ОП):
Если вы используете Python 2,
'%d'%5**18
можно заменить на,`5**18`
чтобы сохранить 3 байта.Чтобы он работал быстрее, вы можете заменить его
'%d'%5**18
любой перестановкой'123456789'
со стоимостью 1 байт.Если вы хотите , чтобы принять ввод на стандартный ввод вместо этого, вы можете заменить
import sys;f(sys.argv[1])
сf(raw_input())
, доведя его до 177 байт .РЕДАКТИРОВАТЬ: Вот ссылка на более подробное руководство.
источник
Питон, 197 символов
источник
Ответ в D:
При вводе сэмпла на моем Phenom II X6 1090T требуется 0,03 с при компиляции
dmd -w
(т.е. без оптимизации), и 0,011 с при компиляцииdmd -w -O -inline -release
(с оптимизацией).источник
J, 103
ожидаемое время выполнения: O (млрд миллиардов лет)
источник
Perl, 120 байт
О, я помню игру в гольф еще в 2008 году ... И она фактически перестала работать в Perl 5.12, так как тогда неявная установка @_ через split была удалена. Так что попробуйте только на достаточно старом Perl.
Запустите с помощью ввода на STDIN:
sudoku.pl
:источник
Perl, 235 символов
Это версия игры в гольф, которую я опубликовал много лет назад в списке рассылки Fun With Perl : регулярное выражение для решения судоку.
По сути, он разбивает входные данные на 81 строку, каждая из которых содержит все числа, которые могут встречаться в соответствующем квадрате. Затем он создает регулярное выражение для соответствия одному числу из каждой строки, используя обратные ссылки и отрицательные косвенные утверждения, чтобы отклонить решения, которые нарушают ограничения строки, столбца или области. Затем он сопоставляет строку с регулярным выражением, позволяя механизму регулярного выражения Perl выполнять тяжелую работу проб и возврата.
Удивительно, но можно создать одно регулярное выражение, которое работает для любого ввода, как моя оригинальная программа. К сожалению, он довольно медленный, поэтому я основал здесь гольф-код на версии hardcoded-givens ( найденной позже в потоке FWP ), которая настраивает регулярное выражение для раннего отклонения любых решений, которые, как ему известно, позже нарушат ограничение. Это делает его достаточно быстрым для легкого и умеренного уровня судоку, хотя особенно тяжелые могут по-прежнему занимать довольно много времени.
Запустите код,
perl -M5.010
чтобы включить функцию Perl 5.10+say
. Ввод должен быть дан на стандартном вводе, и решение будет напечатано на стандартный вывод; пример:источник
1-лайнер кофе-скрипт
solve = (s, c = 0) -> if c is 81 then s else if s[x = c/9|0][y = c%9] isnt 0 then solve s, c+1 else (([1..9].filter (g) -> ![0...9].some (i) -> g in [s[x][i], s[i][y], s[3*(x/3|0) + i/3|0][3*(y/3|0) + i%3]]).some (g) -> s[x][y] = g; solve s, c+1) or s[x][y] = 0
Вот увеличенная версия с примером использования :
источник
solve
, удалив много пробелов (я знаю, что это важно, но во многих местах его можно удалить), используя символы вместо слов (например,!=
вместоisnt
), используя отступ вместоthen
ключевого слова, заменяя[0...9]
на[0..8]
.Clojure - 480 байт
Размер взорвался, но, по крайней мере, это довольно много. Я думаю, что это можно улучшить, используя только 1D-вектор. В любом случае, тестовый пример занимает чуть меньше четырех секунд на моем ноутбуке. Я думал, что было бы уместно определить функцию, так как в конце концов это функциональный язык.
Примеры:
Слегка разглаженная (и более симпатичная) версия:
источник
PowerShell ,
244242218215 байтПопробуйте онлайн!
Скрипт находит все решения для судоку.
раскатали:
Тестовые случаи:
источник
D (322 символа)
Для каждого нерешенного квадрата он строит массив доступных опций, а затем перебирает его.
с пробелами:
источник
Perl (195 символов)
Вся заслуга принадлежит создателю здесь , и объяснение можно найти там же.
источник
J, 94 байта
Работает точно так же, как версия K, а именно с BFS (поэтому он должен выводить все решения). Он печатает пробелы между выходными цифрами, но также и программа K. Я не считаю «s =:», так как это просто название функции (точно так же, как я не буду считать имя файла на другом языке).
источник