Створіть рішення судоку CHECKER


21

Створіть рішення судоку CHECKER

Тут є одул Sudoku SOLVERS, але я хочу, щоб ви створили рішення CHECKER якомога меншим по-людськи (code-golf).

  • Дійсний запис зможе або взяти масив розміром 9x9 як аргумент (переданий за посиланням, серіалізований у командному рядку, або, якщо ви хочете взяти його), або прийняти вхідний файл, який становить дев'ять рядків з дев'яти чисел, для остаточної сітки . Дивіться приклади введення нижче.

  • Дійсне введення має бути базовим числом 10 (1-9)

  • Пропущені, порожні, зайві, нечислові позиції або позиції з цифрами поза 1-9 повинні бути відхилені як недійсні введення шляхом повернення ненульового результату, друку помилки або обох.

  • Вашій програмі потрібно перевірити, чи відображається кожне число один раз у стовпчику, один раз у рядку та один раз у підмережі 3х3. Якщо він пройде, поверніть "0", а якщо ні, поверніть ненульовий результат.

  • Використання зовнішніх ресурсів (веб-сайтів тощо) слід уникати.

  • Якщо ваше рішення - це автономна програма, вихід із статусом виходу або друк "0" або не нульовий для "Pass" або "Fail" відповідно, нормально.

Нехай виграє найменша відповідь!

Приклади введення:

c масив:

int input[9][9]={{1,2,3,4,5,6,7,8,9},
                 {4,5,6,7,8,9,1,2,3},
                 {7,8,9,1,2,3,4,5,6},
                 {2,3,1,5,6,4,8,9,7},
                 {5,6,4,8,9,7,2,3,1},
                 {8,9,7,2,3,1,5,6,4},
                 {3,1,2,6,4,5,9,7,8},
                 {6,4,5,9,7,8,3,1,2},
                 {9,7,8,3,1,2,6,4,5}
                };

файл:

123456789
456789123
789123456
231564897
564897231
897231564
312645978
645978312
978312645

9 підмереж:

+---+---+---+
|123|456|789|
|456|789|123|
|789|123|456|
+---+---+---+
|231|564|897|
|564|897|231|
|897|231|564|
+---+---+---+
|312|645|978|
|645|978|312|
|978|312|645|
+---+---+---+

Відповіді:


5

GolfScript, 39 символів

.zip.{3/}%zip{~}%3/{[]*}%++{$10,1>=!},,

Він приймає масив масивів в якості вхідних даних (див. Приклад в Інтернеті ) і виводить, 0якщо це дійсна сітка.

Коротке пояснення коду

.zip         # Copy the input array and transpose it
.{3/}%       # Split each line into 3 blocks
zip{~}%      # Transpose these blocks
3/{[]*}%     # Do the same for the lines themselves and join again
++           # Make one large list of 27 9-element arrays 
             # (9 for rows, 9 for columns, 9 for blocks)
{$10,1>=!},  # From those 27 select the ones which are not a permutation of [1 2 3 ... 9]
             #   $      -> sort
             #   10,1>  -> [1 2 3 ... 9]
             #   =!     -> not equal
,            # Count after filtering

Мені подобається , що ненульова вихід вашого коду є більш значущим , ніж просто 1або-1
Девід Уілкінс

Мені дуже сподобалась ваша відповідь, але врешті-решт я вирішив не брати рішення з голфскрипту. Я дуже сподіваюся, що ви зрозуміли
Девід Уілкінс

2
@DavidWilkins Насправді я не розумію - ви створили правила (!) І ніде не заявляли, що GolfScript заборонено.
Говард

Ваша думка цілком справедлива ... по правді кажучи, я нічого не можу виправдати, не вибравши вашу відповідь. Добре зіграний
Девід Уілкінс

10

Пітона, 103

Я ненавиджу судоку.

b = [[1,2,3,4,5,6,7,8,9],
     [4,5,6,7,8,9,1,2,3],
     [7,8,9,1,2,3,4,5,6],
     [2,3,1,5,6,4,8,9,7],
     [5,6,4,8,9,7,2,3,1],
     [8,9,7,2,3,1,5,6,4],
     [3,1,2,6,4,5,9,7,8],
     [6,4,5,9,7,8,3,1,2],
     [9,7,8,3,1,2,6,4,5]]

e=enumerate;print 243-len(set((a,t)for(i,r)in e(b)for(j,t)in e(r)for a in e([i,j,i/3*3+j/3]*(0<t<10))))

Як це працює: кожен рядок, стовпець і блок повинні мати кожне число від 1 до 9. Отже, для кожної 0 <= i, j < 9клітинки i,jзнаходиться в блоці 3*floor(i/3) + floor(j/3). Таким чином, необхідно задовольнити 243 вимоги. Я роблю кожну вимогу кортежем, ((item index,item type number),symbol)де item indexчисло між 0 і 8 (включно), item type numberдорівнює 0,1, або 2, щоб позначити рядок, стовпчик або блок відповідно, і symbolце запис b[i][j].

Редагувати: я помилково не перевірив правильність записів. Тепер я.


Ваша програма повинна виводити, 0якщо рішення пройде, а неTrue
Девід Уілкінс

@DavidWilkins яка дивна вимога. Виправлено.
стенди

Ви, сер, отримаєте мій голос саме за те, як ви почали свою відповідь: D
Teun Pronk

9

APL (46)

{∧/,↑∊∘Z¨(/∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9),(↓⍵),↓⍉⍵}

Для цього потрібна матриця 9 на 9. Приклад можна ввести в TryAPL так:

     sudoku ← ↑(1 2 3 4 5 6 7 8 9)(4 5 6 7 8 9 1 2 3)(7 8 9 1 2 3 4 5 6)(2 3 1 5 6 4 8 9 7)(5 6 4 8 9 7 2 3 1)(8 9 7 2 3 1 5 6 4)(3 1 2 6 4 5 9 7 8)(6 4 5 9 7 8 3 1 2)(9 7 8 3 1 2 6 4 5)
     {∧/,↑∊∘Z¨(/∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9),(↓⍵),↓⍉⍵} sudoku
1

Пояснення:

  • ↓⍉⍵: отримати стовпці ,
  • ↓⍵: отримати рядки ,
  • 3/3⌿3 3⍴Z←⍳9: Зробити матрицю 3 × 3 , що містить число , 1щоб 9, потім потрійний кожне число в обох напрямках, що дає матрицю 9-по-9 з номерами 1для 9індикації кожної групи,
  • Z∘.=: для кожного числа, 1щоб 9зробити біт-маску для даної групи,
  • /∘(,⍵)¨: і маскувати кожен, даючи групам .
  • ∊∘Z¨: Для кожного суб-масиву, чи містить він число 1до 9,
  • ∧/,↑: візьмемо логічно andвсі ці числа разом.

+1 Приємно! Але 3 × 3 групи можна пограти ще трохи. Наприклад, це ↓9 9⍴1 3 2⍉3 3 9⍴⍵рівнозначно, /∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9але досить коротше. Я впевнений, що є ще коротші формули.
Тобія

Крім того, ви можете об'єднати матриці за 1-м виміром і виконати один розкол в кінці:↓(9 9⍴1 3 2⍉3 3 9⍴⍵)⍪⍵⍪⍉⍵
Тобія

Існує помилка: цей код ∊∘Z¨перевіряє, чи кожний підмасив (рядок, стовпець або блок) складається лише з цифр від 1 до 9. Це не тестування, чи представлені всі числа. Вам потрібно зробити щось на кшталт Z∘.∊тестів, які кожне число Z міститься у кожному підмасиві.
Тобія

І це ∧/,↑можна скоротити ∧/∊. Я закінчив, я закінчив! ;-)
Тобія

Дуже компактний, але ви пропустили один критичний момент, який я можу побачити відразу:If it passes, return "0" and if not, return a non-zero result.
Девід Уілкінс

5

Java / C # - 183/180 181/178 173/170 байт

boolean s(int[][]a){int x=0,y,j;int[]u=new int[27];for(;x<(y=9);x++)while(y>0){j=1<<a[x][--y];u[x]|=j;u[y+9]|=j;u[x/3+y/3*3+18]|=j;}for(x=0;x<27;)y+=u[x++];return y==27603;}

(Зміна boolean на boolC #)

Відформатовано:

boolean s(int[][] a){
    int x=0, y, j;
    int[] u=new int[27];
    for(;x<(y=9);x++)
        while(y>0){
            j=1<<a[x][--y];
            u[x]|=j;
            u[y+9]|=j;
            u[x/3+y/3*3+18]|=j;
        }

    for(x=0;x<27;)
        y+=u[x++];

    return y==27603;
}

Метод створює масив u з 27 бітових масок, що представляють цифри, знайдені в дев'яти рядках, стовпцях і квадратах.

Потім він переходить на всі комірки, виконуючи операцію 1 << a[x][y] по створенню бітової маски, що представляє цифру, і АБО її стовпчик, рядок і квадратну біткову маску.

Потім він повторюється над усіма 27 бітовими масками, гарантуючи, що всі вони складають до 27594 (1022 * 9, 1022 - це бітова маска для всіх цифр 1-9, що присутні). (Зауважте, щоy закінчується як 27603 завдяки тому, що він вже містить 9 після подвійного циклу.)

Редагувати: Випадково залишено в а %3 тому, що більше не потрібно.

Редагування 2: Натхненний коментарем Брайса Вагнера, код був ще більше стислий.


Майже такий самий алгоритм у символах C # 149 (але лише якщо дозволено Linq): bool s (int [] a) {int x = 0, y, j; var u = new int [27]; while (x ++ <(y = 9)) в той час як (y> 0) {j = 1 << a [x + 9 * - y]; u [x] | = j; u [y + 9] | = j; u [x / 3 + y / 3 * 3 + 18] | = j;} повернути u.Sum () == 27594;}
Брайс Вагнер

@BryceWagner Linq справді був би корисним. Однак моє рішення полягає в тому, що Java з C # є задумливою (навіть не згадується в оригінальній публікації) і, таким чином, має нижчий пріоритет. Я також використовував одновимірні масиви для компактності на початку перед тим, як прийняти рішення проти нього (як приклади використовують двовимірні). Тим не менш, ваш код дав мені декілька ідей, як можна ще кілька байтів відтерти. :)
Smallhacker

3

пітон = 196

Не самий гольф, але ідея є. Набори досить корисні.

Рада:

b = [[1,2,3,4,5,6,7,8,9],
     [4,5,6,7,8,9,1,2,3],
     [7,8,9,1,2,3,4,5,6],
     [2,3,1,5,6,4,8,9,7],
     [5,6,4,8,9,7,2,3,1],
     [8,9,7,2,3,1,5,6,4],
     [3,1,2,6,4,5,9,7,8],
     [6,4,5,9,7,8,3,1,2],
     [9,7,8,3,1,2,6,4,5]]

Програма:

n={1,2,3,4,5,6,7,8,9};z=0
for r in b:
 if set(r)!=n:z=1
for i in zip(*b):
 if set(i)!=n:z=1
for i in (0,3,6):
 for j in (0,3,6):
  k=j+3
  if set(b[i][j:k]+b[i+1][j:k]+b[i+2][j:k])!=n:z=1
print(z)

s / {1,2,3,4,5,6,7,8,9} / set (діапазон (1,10)) / зберігає 3 символи.
MatrixFrog

У Python 3.5 ви можете використовувати n={*range(1,10)}, але це новіше, ніж виклик. Замість цього використовуйте, set(range(1,10))як сказав MatrixFrog.
mbomb007

3

Java - 385 306 328 260 символів

Редагувати: Я нерозумно перечитав інструкції, що відповідь мала бути повноцінною програмою. Оскільки це може бути просто допустима функція, я переписав і звів до мінімуму функцію, і переписав введення свого рішення, враховуючи це.

Отже, як виклик собі я подумав, що спробую зробити найменшу перевірку Java рішення.

Щоб досягти цього, я припускаю, що головоломка судоку буде передана у вигляді багатовимірного масиву Java, наприклад:

s(new int[][] {
    {1,2,3,4,5,6,7,8,9},
    {4,5,6,7,8,9,1,2,3},
    {7,8,9,1,2,3,4,5,6},
    {2,3,1,5,6,4,8,9,7},
    {5,6,4,8,9,7,2,3,1},
    {8,9,7,2,3,1,5,6,4},
    {3,1,2,6,4,5,9,7,8},
    {6,4,5,9,7,8,3,1,2},
    {9,7,8,3,1,2,6,4,5}});

Тоді ми маємо фактичний вирішувач, який повертає "0", якщо дійсне рішення, "1", якщо ні.

Повністю гольф:

int s(int[][] s){int i=0,j,k=1;long[] f=new long[9];long r=0L,c=r,g=r,z=45L,q=r;for(f[0]=1L;k<9;){f[k]=f[k-1]*49;z+=f[k++]*45;}for(;i<9;i++){for(j=0;j<9;){k=s[i][j];r+=k*f[i];c+=k*f[j];g+=k*f[j++/3+3*(i/3)];q+=5*f[k-1];}}return (r==z&&c==z&&g==z&&q==z)?0:1;}

Читає:

    int s(int[][] s) {
        int i=0,j,k=1;
        long[] f=new long[9]; 
        long r=0L,c=r,g=r,z=45L,q=r;
        for(f[0]=1L;k<9;){f[k]=f[k-1]*49;z+=f[k++]*45;}
        for(;i<9;i++) {
            for (j=0;j<9;) {
                k=s[i][j];
                r+=k*f[i];
                c+=k*f[j];
                g+=k*f[j++/3+3*(i/3)];
                q+=5*f[k-1];
            }
        }
        return (r==z&&c==z&&g==z&&q==z)?0:1;
    }

То як це працює? Я в основному просто створюю свою власну базу чисел з достатньою роздільною здатністю в кожній цифрі, що мені потрібно лише три порівняння після читання головоломки один раз, щоб знати, чи дійсно це. Я вибрав базу 49 для цієї проблеми, але будь-яка база, що перевищує 45, буде достатньою.

Який (сподіваємось) чіткий приклад: уявіть, що кожен "рядок" у головоломці судоку - це одна цифра в базовій кількості 49. Ми будемо представляти кожну цифру в номері бази-49 як число базової-10 у векторі для простоти. Отже, якщо всі рядки є "правильними", ми очікуємо наступне число бази-49 (як вектор базового 10):

(45,45,45,45,45,45,45,45,45)

або перетворене на єдине число-10: 1526637748041045

Дотримуйтесь аналогічної логіки для всіх стовпців, а також для "підмереж". Будь-яке значення, що зустрічається в остаточному аналізі, яке не відповідає цьому "ідеальному числу", означає, що рішення головоломки недійсне.

Редагуйте, щоб вирішити вразливість усіх 5-х та інші пов'язані з цим проблеми. Я додаю четверте число 49-бази, грунтуючись на ідеї, що в кожній головоломці має бути 9 номерів. Отже, я додаю 5 до кожної цифри в номері бази-49 за кожне виникнення числа базового-10, яке представляє індекс цифри. Наприклад, якщо є 10 9 та 9 8, 9 7, 8 6, і 9 всіх інших, ви отримаєте число 49-бази (як вектор-10 розміром 10 для боротьби з переповненням):

(1, 1, 45, 45, 40, 45, 45, 45, 45, 45)

Що не вдасться порівняти з нашим "ідеальним" номером-49.

Моє рішення використовує це математичне рішення, щоб максимально уникати циклічного циклу та порівняння. Я просто використовую longзначення, щоб зберігати кожне число бази-49 як число базового-10 і використовую масив пошуку, щоб отримати "коефіцієнти" для кожної цифри бази-49 під час обчислення значення стовпців / рядків / підрешітки.

Оскільки Java не розрахована на стислість, єдиний спосіб, коли я зрозумів, що зможу побудувати лаконічну перевірку, був обережним у математичній конструкції.

Дайте мені знати, що ви думаєте.


1
Власне, це страждає від тієї ж вразливості, про яку згадує @ steve-verrill - усі 5, або будь-який набір чисел, який дорівнює 45, "обмануть" вирішувач. Я збираюся переглянути. У мене є ідея, як це перемогти.
ПрограмістDan

Я вирішив цю вразливість у своєму останньому оновлення. Тепер ця справа розглянута, і всі інші її типи. В основному, це був серйозний нагляд не мати справу з "підрахунками" кожного типу базової 10 цифри. Зараз я виконую цю перевірку безпосередньо, але використовую той самий математичний підхід (число 49).
ПрограмістДат

Ден, дякую за визнання. Я побачив це і поцікавився, чому мені не повідомлено, але я бачу, що ти поставив тире на моє ім’я. Це, здається, заплутало систему. Просто опустіть пробіл. Я розглядаю можливість зміни способу відображення мого імені.
Річка рівня Св.

Аха, це пояснює це. Спасибі @steveverrill - я все ще звикаю до способу виконання ставок. Однак, ваше стисле використання принципу «сума-45» було яскраво заявлено. Зробив моє рішення довше, щоб його подолати, але це життя!
ПрограмістDan


3

Haskell (Lambdabot), 65 байт

k x=and$(all$([1..9]==).sort)<$>[x,transpose x,join$chunksOf 3 x]

2

Perl, 193 байт

for(@x=1..9){$i=$_-1;@y=();push@y,$a[$i][$_-1]for@x;@y=sort@y;$r+=@y~~@x;@y=();push@y,$a[3*int($i/3)+$_/3][3*($i%3)+$_%3]for 0..8;@y=sort@y;$r+=@y~~@x}for(@a){@y=sort@$_;$r+=@y~~@x}exit($r!=27)

Вхід очікується у вигляді масиву:

@a=(
    [1,2,3,4,5,6,7,8,9],
    [4,5,6,7,8,9,1,2,3],
    [7,8,9,1,2,3,4,5,6],
    [2,3,1,5,6,4,8,9,7],
    [5,6,4,8,9,7,2,3,1],
    [8,9,7,2,3,1,5,6,4],
    [3,1,2,6,4,5,9,7,8],
    [6,4,5,9,7,8,3,1,2],
    [9,7,8,3,1,2,6,4,5]
);

Вихідний код дорівнює 0, якщо @aце рішення, інакше 1повертається.

Негольована версія:

@x = (1..9);
for (@x) {
    $i = $_ - 1;
    # columns
    @y = ();
    for (@x) {
        push @y, $a[$i][$_-1];
    }
    @y = sort @y;
    $r += @y ~~ @x;
    # sub arrays
    @y = ();
    for (0..8) {
        push @y, $a[ 3 * int($i / 3) + $_ / 3 ][ 3 * ($i % 3) + $_ % 3 ];
    }
    @y = sort @y;
    $r += @y ~~ @x
}
# rows
for (@a) {
    @y = sort @$_;
    $r += @y ~~ @x
}
exit ($r != 27);

Кожен з 9 рядків, 9 стовпців та 9 підмасивів поміщається в відсортований масив і перевіряється, чи відповідає він масиву (1..9). Кількість $rзбільшується за кожен успішний матч, який повинен дорівнювати 27 для дійсного рішення.


2

J 52 54

-.*/,(9=#)@~.@,"2(0 3 16 A.i.4)&|:(4#3)($,)".;._2]0 :0

Вважає, що аргумент вставляється в командному рядку і закінчується а) як:

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

Повертає 1, якщо передано, 0 якщо ні.

Внутрішньо вона перетворює сітку 9x9 в сітку 3x3x3x3 і робить деякі перестановки на осях, щоб отримати потрібний блок (рядки, лінії та поля) в останніх 2 вимірах.

Після цього перевіряється наявність у кожного блоку 9 унікальних значень.

Напевно, далеко не ідеально, але вже б'є більшість ;-)


На перший погляд, вас спіймала та ж вимога, що і деякі інші .... Ваші повернення повинні бути відмінені ... 0 за пропуск, не нульовий для провалу
Девід Уілкінс

0 для пропуску - ідіотський. Є причина, що Бул вибрав 1 для істинного та 0 для хибного. Але ви праві. Додає 2 символи.
jpjacobs

Розгляньте це як статус виходу, а не булеве значення
Девід Уілкінс

Я обираю вашу відповідь, тому що вона працює. Ви дотримувались правил, і ваша програма дуже коротка. Спасибі!
Девід Уілкінс

Ну, я попростував ... Правду кажучи, я не можу виправдати, що не обрав відповідь Гольфскрипта, яка коротша за твою ... Але кудо за 2 місце
Девід Уілкінс

2

Математика, 84 79 символів

f=Tr[Norm[Sort@#-Range@9]&/@Join[#,Thread@#,Flatten/@Join@@#~Partition~{3,3}]]&

Приклади:

f[{{1,2,3,4,5,6,7,8,9},
   {4,5,6,7,8,9,1,2,3},
   {7,8,9,1,2,3,4,5,6},
   {2,3,1,5,6,4,8,9,7},
   {5,6,4,8,9,7,2,3,1},
   {8,9,7,2,3,1,5,6,4},
   {3,1,2,6,4,5,9,7,8},
   {6,4,5,9,7,8,3,1,2},
   {9,7,8,3,1,2,6,4,5}}]

0

f[{{2,1,3,4,5,6,7,8,9},
   {4,5,6,7,8,9,1,2,3},
   {7,8,9,1,2,3,4,5,6},
   {2,3,1,5,6,4,8,9,7},
   {5,6,4,8,9,7,2,3,1},
   {8,9,7,2,3,1,5,6,4},
   {3,1,2,6,4,5,9,7,8},
   {6,4,5,9,7,8,3,1,2},
   {9,7,8,3,1,2,6,4,5}}]

2

f[{{0,2,3,4,5,6,7,8,9},
   {4,5,6,7,8,9,1,2,3},
   {7,8,9,1,2,3,4,5,6},
   {2,3,1,5,6,4,8,9,7},
   {5,6,4,8,9,7,2,3,1},
   {8,9,7,2,3,1,5,6,4},
   {3,1,2,6,4,5,9,7,8},
   {6,4,5,9,7,8,3,1,2},
   {9,7,8,3,1,2,6,4,5}}]

3


Ваш третій приклад виводу: Чи 3завжди вказується на недійсний ввід чи це іноді відповідь на невдале рішення?
Девід Уілкінс

2

Javascript ES6, 150 символів

Вводиться як 81-знакова рядок без жодних деліметрів.

s=>s.match("^(?=(#.{0,8}#.{9})+$)(?=(#(.{9}){0,8}#.){9})((#.?.?(.{9}){0,2}#...){3}.{18})+$".replace(/#(.*?)#/g,"123456789".replace(/./g,"(?=$$1$&)")))

Функція повертається nullяк негативна відповідь, а масив з оригінальним рядком у першому елементі як позитивний. Можна змінити на bool, додавши !!до функції, що починається.

Тест (див. Пов'язаний виклик для деталей):

f=s=>s.match("^(?=(#.{0,8}#.{9})+$)(?=(#(.{9}){0,8}#.){9})((#.?.?(.{9}){0,2}#...){3}.{18})+$".replace(/#(.*?)#/g,"123456789".replace(/./g,"(?=$$1$&)")))
;`123456789456789123789123456231564897564897231897231564312645978645978312978312645
725893461841657392396142758473516829168429537952378146234761985687935214519284673
395412678824376591671589243156928437249735186738641925983164752412857369567293814
679543182158926473432817659567381294914265738283479561345792816896154327721638945
867539142324167859159482736275398614936241587481756923592873461743615298618924375
954217683861453729372968145516832497249675318783149256437581962695324871128796534
271459386435168927986273541518734269769821435342596178194387652657942813823615794
237541896186927345495386721743269158569178432812435679378652914924813567651794283
168279435459863271273415986821354769734692518596781342615947823387526194942138657
863459712415273869279168354526387941947615238138942576781596423354821697692734185
768593142423176859951428736184765923572389614639214587816942375295837461347651298`
.split`
`.every(f)
&&
`519284673725893461841657392396142758473516829168429537952378146234761985687935214
839541267182437659367158924715692843624973518573864192298316475941285736456729381
679543182158926473432817659567381294914256738283479561345792816896154327721638945
867539142324167859159482736275398684936241517481756923592873461743615298618924375
754219683861453729372968145516832497249675318983147256437581962695324871128796534
271459386435168927986273541518734269769828435342596178194387652657942813823615794
237541896186927345378652914743269158569178432812435679495386721924813567651794283
168759432459613278273165984821594763734982516596821347615437829387246195942378651
869887283619214453457338664548525781275424668379969727517385163319223917621449519
894158578962859187461322315913849812241742157275462973384219294849882291119423759
123456789456789123564897231231564897789123456897231564312645978645978312978312645
145278369256389147364197258478512693589623471697431582712845936823956714931764825`
.split`
`.every(s => !f(s))

Оце один смішний регекс ... Дивовижна робота.
ETHproductions

2

R, 63 50 байт

Припустимо, що вхід m- це матриця чисел 9x9.

all(apply(m,1,match,x=1:9),apply(m,2,match,x=1:9))

Я мав рацію, що подальший гольф можливий.

Пояснення:

    apply(m,1,match,x=1:9),

Візьміть mі для кожного ряду застосуйте matchфункцію. Ми вказуємо подальший аргумент, якому x=1:9слід передати match. xє першим аргументом позиції за замовчуванням, і тому кожен рядок розміщується у другому положенні аргументу, яке є table. Функція matchшукає екземпляри xв table. Тоді в цьому випадку вона шукає 1:9(цифри від 1 до 9) у кожному рядку. Для кожного з них 1:9він повернеться TRUE(або FALSE), якщо це число буде знайдено (чи ні).

Отже, це дає низку 81 булевих значень.

                           apply(m,2,match,x=1:9)

Повторіть вище для кожного стовпця вводу.

all(                                             )

Нарешті, allперевіряє, чи є кожен елемент списку булевих значень TRUE. Це буде в тому випадку, якщо і тільки якщо рішення є правильним (тобто кожне число 1:9присутнє лише один раз у кожному стовпчику та кожному рядку).

Старий підхід:

for(i in 1:2)F=F+apply(m,i,function(x)sort(x)==1:9);sum(F)==162

Він бере кожен ряд, сортує його, а потім порівнює [1, 2, ... 9]. Правильний рядок повинен точно відповідати. Тоді це робиться те саме для кожного стовпця. Загалом у нас повинно бути 162 точних відповідності, на що перевіряється фінальна частина. Тут, мабуть, є якась можливість для подальшого гольфу ...


Схоже, ви перевіряєте стовпці та рядки, але не для коробок ...
JayCe

1

Haskell - 175

import Data.List
c=concat
m=map
q=[1..9]
w=length.c.m (\x->(x\\q)++(q\\x))
b x=c.m(take 3.drop(3*mod x 3)).take 3.drop(3*div x 3)
v i=sum$m(w)[i,transpose i,[b x i|x<-[0..8]]]

Функція v- та, яку потрібно викликати. Він працює, отримуючи різницю між кожними рядками, стовпцями та блоками проти списку [1..9]та підсумовуючи довжину цих списків різниць.

Демонстрація на прикладі судоку:

*Main> :l so-22443.hs 
[1 of 1] Compiling Main             ( so-22443.hs, interpreted )
Ok, modules loaded: Main.
*Main> v [[1,2,3,4,5,6,7,8,9],[4,5,6,7,8,9,1,2,3],[7,8,9,1,2,3,4,5,6],[2,3,1,5,6,4,8,9,7],[5,6,4,8,9,7,2,3,1],[8,9,7,2,3,1,5,6,4],[3,1,2,6,4,5,9,7,8],[6,4,5,9,7,8,3,1,2],[9,7,8,3,1,2,6,4,5]]
0

1

Javascript - 149 символів

r=[];c=[];g=[];for(i=9;i;)r[o=--i]=c[i]=g[i]=36;for(x in a)for(y in z=a[x]){r[v=z[y]-1]-=y;c[v]-=x;g[v]-=3*(x/3|0)+y/3|0}for(i in r)o|=r[i]|c[i]|g[i]

Очікує існування масиву aі створює змінну oдля виводу, який є 0успішним і не нульовим в іншому випадку.

Працює, перевіряючи, що сума позиції, в якій відбувається кожне значення для кожного рядка, стовпця та сітки 3 * 3, дорівнює 36 (0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8).

Тестування

a=[
    [1,2,3, 4,5,6, 7,8,9],
    [4,5,6, 7,8,9, 1,2,3],
    [7,8,9, 1,2,3, 4,5,6],

    [2,3,1, 5,6,4, 8,9,7],
    [5,6,4, 8,9,7, 2,3,1],
    [8,9,7, 2,3,1, 5,6,4],

    [3,1,2, 6,4,5, 9,7,8],
    [6,4,5, 9,7,8, 3,1,2],
    [9,7,8, 3,1,2, 6,4,5]
  ];

Дає "o = 0"

a=[
    [1,2,3, 4,5,6, 7,8,9],
    [4,5,6, 7,8,9, 1,2,3],
    [7,8,9, 1,2,3, 4,5,6],

    [2,3,1, 5,6,4, 8,9,7],
    [5,6,4, 8,9,7, 2,3,1],
    [8,9,7, 2,3,1, 5,6,4],

    [3,1,2, 6,4,5, 9,7,8],
    [6,4,5, 9,7,8, 3,1,2],
    [9,7,8, 3,1,2, 6,5,4]
  ];

(Останні дві цифри помінялися)

Дає o=-1

a=[
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],

    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],

    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5]
  ];

Дає o=-284


1

Haskell, 121 130 127 байт (87 лямбдаботів)

import Data.List
import Data.List.Split
c=concat
t=transpose
k=chunksOf
p x=all(==[1..9])$(sort<$>)=<<[x,t x,k 9.c.c.t$k 3<$>x]

використовує:

-- k 9.c.c.t$k 3<$> x = chunksOf 9 $ concat $ concat $ transpose $ map chunksOf 3 x

let ts = k 9$[10*a+b|a<-[1..9],b<-[1..9]] --yep, this is ugly
in k 9.c.c.t$k 3<$>ts
-- prints:
--[[11,12,13,21,22,23,31,32,33],[41,42,43,51,52,53,61,62,63],[71,72,73,81,82,83,91,92,93],[14,15,16,24,25,26,34,35,36],[44,45,46,54,55,56,64,65,66],[74,75,76,84,85,86,94,95,96],[17,18,19,27,28,29,37,38,39],[47,48,49,57,58,59,67,68,69],[77,78,79,87,88,89,97,98,99]]

Lambdabot за замовчуванням завантажує Data.List і Data.List.Split (я не думаю, що рішення BlackCap перевіряє поля).

Ідеї ​​для вдосконалення вітаються

// Редагувати: Я заплутався :)
// Редагувати: 3 байти, збережені BlackCap


Ви маєте рацію, я не помітив, що перевірка рядків і стовпців недостатня ..
BlackCap

ну і я
заплутався

1
Ви можете замінити (map sort)на(sort<$>)
BlackCap

1
І .c$(sort<$>)<$>з$(sort<$>)=<<
BlackCap

о мій, мав би згадати ті 2
michi7x7


0

Clojure, 151 байт

Досить довго, але, схоже, і інші. Також дратує, що об'єднання множин вимагає аrequire , тому я замість цього використовував набір векторів.

Ітератується над кожним рядком і стовпцем, і якщо значення становить від 1 до 9, воно випромінює три вектори, один для рядка, col і 3x3 комірок. Повертає 0 із успіхом, nilінакше два додаткові символи можуть повернути 1 під час відмови. Обробляє числа за межами від 1 до 9, повертаючись, nilале вони збігаються за іншими аномаліями, такими як не цілі значення. Коефіцієнти 0 - 2, тому безпечно використовувати значення 8та 9диференціювати значення комірок від рядків та стовпців.

(fn[s](if(= 243(count(set(apply concat(for[i(range 9)j(range 9)](let[v(nth(nth s i)j)q #(quot % 3)](if(<= 1 v 9)[[8 v i][9 v j][(q i)(q j)v]])))))))0))

Вхід - це вкладений вектор векторів (так, що nthпрацює):

(def sudoku [[1 2 3 4 5 6 7 8 9]
             [4 5 6 7 8 9 1 2 3] 
             [7 8 9 1 2 3 4 5 6] 
             [2 3 1 5 6 4 8 9 7] 
             [5 6 4 8 9 7 2 3 1] 
             [8 9 7 2 3 1 5 6 4] 
             [3 1 2 6 4 5 9 7 8] 
             [6 4 5 9 7 8 3 1 2] 
             [9 7 8 3 1 2 6 4 5]])

Безголівки:

(defn f [s]
  (->> (for [i (range 9) j (range 9)]
         (let [v (-> s (nth i) (nth j)) q #(quot % 3)]
           (if (<= 1 v 9)
             [[:row v i] [:col v j] [:cell [(q i) (q j)] v]])))
    (apply concat)
    set
    count
    (#(if (= 243 %) :pass :fail))))

0

PHP, 196 190 байт

while($i<9){for($b=$c=$k=$y="";$y++<9;)$b.=($a=$argv)[$y][$i];for(;$k<3;)$c.=substr($a[++$k+$i-$i%3],$i%3*3,3);if(($u=count_chars)($a[++$i],3)<($d=123456789)|$u($b,3)<$d|$u($c,3)<$d)die(1);}

Програма бере 9 окремих аргументів командного рядка (по одному рядку цифр для кожного рядка сітки);
закінчується 1(помилка) для недійсного, 0(ок) для дійсного.

Бігайте з php -nr '<code>' <row1> <row2> ....

зламатися

while($i<9)
{
    for($b=$c=$k=$y="";$y++<9;)$b.=($a=$argv)[$y][$i];  // column to string
    for(;$k++<3;)$c.=substr($a[$i-$i%3+$k],$i%3*3,3);   // sub-grid to string
    if(($u=count_chars)($a[++$i],3)<($d=123456789)      // check row
        |$u($b,3)<$d                                    // check column
        |$u($c,3)<$d                                    // check sub-grid
    )die(1);                                            // test failed: exit with 1
}

пояснення

count_charsрахує символи в рядку і зазвичай створює масив з кодами ascii як ключі та число символів як значення; але з 3параметром mode, він створює відсортовану рядок із символів; і це легко порівняти число з шуканими цифрами.

Порівняння не лише перевіряє наявність дублікатів, але також включає перевірку на недійсні символи. І це потрібно лише <, ні !=, тому що це числове порівняння: PHP інтерпретує рядок як число, наскільки це можливо. 123e56789, 0x3456789Або подібне не може з'явитися, тому що символи упорядковано; і будь-яке чисте ціле число з відсутньою цифрою менше, ніж 123456789... і .23456789теж, звичайно.

$a=$argvзберігає один байт, $d=123456789заощаджує дев'ять і $u=count_charsзберігає 13.


-1

C # - 306 298 288 символів

Наступна програма консолі була використана для виклику функції перевірки;

static void Main(string[] args)
    {
        int[,] i={{1,2,3,4,5,6,7,8,9},
             {4,5,6,7,8,9,1,2,3},
             {7,8,9,1,2,3,4,5,6},
             {2,3,1,5,6,4,8,9,7},
             {5,6,4,8,9,7,2,3,1},
             {8,9,7,2,3,1,5,6,4},
             {3,1,2,6,4,5,9,7,8},
             {6,4,5,9,7,8,3,1,2},
             {9,7,8,3,1,2,6,4,5}
            };

            Console.Write(P(i).ToString());
    }

Все це робить ініціалізація масиву та передача його у перевірочну функцію P.

Функція перевірки наведена нижче (у формі Golfed);

private static int P(int[,]i){int[]r=new int[9],c=new int[9],g=new int[9];for(int p=0;p<9;p++){r[p]=45;c[p]=45;g[p]=45;}for(int y=0;y<9;y++){for(int x=0;x<9;x++){r[y]-=i[x,y];c[x]-=i[x,y];int k=(x/3)+((y/3)*3);g[k]-=i[x,y];}}for(int p=0;p<9;p++)if(r[p]>0|c[p]>0|g[p]>0)return 1;return 0;}

Або в повністю викладеному вигляді;

    private static int P(int[,] i)
    {
        int[] r = new int[9],c = new int[9],g = new int[9];
        for (int p = 0; p < 9; p++)
        {
            r[p] = 45;
            c[p] = 45;
            g[p] = 45;
        }

        for (int y = 0; y < 9; y++)
        {
            for (int x = 0; x < 9; x++)
            {
                r[y] -= i[x, y];

                c[x] -= i[x, y];

                int k = (x / 3) + ((y / 3) * 3);
                g[k] -= i[x, y];
            }
        }

        for (int p = 0; p < 9; p++)
            if (r[p] > 0 | c[p] > 0 | g[p] > 0) return 1;

        return 0;
    }

Тут використовується ідея, що всі стовпці, рядки та підмережі повинні містити до 45. Він працює через вхідний масив і віднімає значення кожної позиції з її рядків, стовпців та підмереж. Після завершення він перевіряє, що жоден із рядків, стовпців чи підмереж досі не має значення.

За запитом повертає 0, якщо масив є дійсним рішенням судоку та не нульовим (1), де його немає.


Я думаю, що ви можете зберегти деякі символи, скориставшись private static int P(int[,]i){int[]r=new int[9],c=new int[9],g=new int[9];замість цього. (Зверніть увагу на вилучення місця після закритого квадратного кронштейна ].) Також я не впевнений, але, думаю, ви можете позбутися цього private static.
користувач12205

Крім того, для останньої частини в C ми можемо видалити деякі дужки, тобто for(int p=0;p<9;p++)if(r[p]>0|c[p]>0|g[p]>0)return 1;return 0;}не впевнені, чи працює він у C #, хоча. (Я фактично не знаю C #)
користувач12205

@ace - Я зробив кілька вдосконалень на основі ваших пропозицій. Тепер до 298 символів.
Буде

Обрізано ще 10 символів на основі коментарів @ace.
Буде

1
Що відбувається з масивом, повним числа 5? Усі рядки, стовпці та квадрати складають до 45.
Рівень річки Св.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.