Перевірка матриці знаків, що чергуються


16

Матриця змінного знака являє собою з nдопомогою nматриці , що складається з чисел -1, 0, 1, таким чином, що:

  • Сума кожного рядка та стовпця дорівнює 1
  • Незначні записи у кожному рядку та стовпці чергуються у знаку

Ці матриці узагальнюють матриці перестановки, і кількість таких матриць протягом даного nчасу цікавила деякий час. Вони виникають природним шляхом під час конденсації Доджсона методом обчислення детермінант матриці (названий на честь Чарльза Доджсона, більш відомий як Льюїс Керролл).

Ось кілька прикладів 4 на 4 змінних знакових матриць:

 0  1  0  0          1  0  0  0          0  0  1  0          0  0  1  0    
 0  0  1  0          0  0  1  0          0  1 -1  1          1  0 -1  1
 1  0  0  0          0  1 -1  1          1 -1  1  0          0  1  0  0
 0  0  0  1          0  0  1  0          0  1  0  0          0  0  1  0

Ось кілька прикладів матриць 4 на 4, які не чергуються знакових матриць:

 0  1  0  0
 0  0  0  1
 1  0  0  0
 0  0  1 -1    (last row and last column don't add to 1)

 0  0  0  1
 1  0  0  0
-1  1  1  0
 1  0  0  0    (third row does not alternate correctly)

Ваша програма або функція буде дано nпо nматриці ( n >= 1) з -1S, 0 і 1 - виводити значення truthy , якщо дана матриця є матрицею знакозмінного, інакше виведіть на falsy значення.

Це , тому мета - мінімізувати кількість використаних байтів.

Тестові справи

Наступні тестові випадки наведені у форматі 2D-списку, подібного Python.

Truthy:

[[1]]
[[1,0],[0,1]]
[[0,1],[1,0]]
[[0,1,0],[0,0,1],[1,0,0]]
[[0,1,0],[1,-1,1],[0,1,0]]
[[0,1,0,0],[0,0,1,0],[1,0,0,0],[0,0,0,1]]
[[1,0,0,0],[0,0,1,0],[0,1,-1,1],[0,0,1,0]]
[[0,0,1,0],[0,1,-1,1],[1,-1,1,0],[0,1,0,0]]
[[0,0,1,0],[1,0,-1,1],[0,1,0,0],[0,0,1,0]]
[[0,0,1,0,0],[0,1,-1,1,0],[1,-1,1,0,0],[0,1,0,-1,1],[0,0,0,1,0]]
[[0,0,1,0,0,0,0,0],[1,0,-1,0,1,0,0,0],[0,0,0,1,-1,0,0,1],[0,0,1,-1,1,0,0,0],[0,0,0,0,0,0,1,0],[0,0,0,0,0,1,0,0],[0,1,-1,1,0,0,0,0],[0,0,1,0,0,0,0,0]]
[[0,0,0,0,1,0,0,0],[0,0,1,0,-1,1,0,0],[0,0,0,1,0,0,0,0],[1,0,0,-1,1,-1,1,0],[0,1,-1,1,-1,1,0,0],[0,0,0,0,1,0,0,0],[0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1]]

Фальсі:

[[0]]
[[-1]]
[[1,0],[0,0]]
[[0,0],[0,1]]
[[-1,1],[1,0]]
[[0,1],[1,-1]]
[[0,0,0],[0,0,0],[0,0,0]]
[[0,1,0],[1,0,1],[0,1,0]]
[[-1,1,1],[1,-1,1],[1,1,-1]]
[[0,0,1],[1,0,0],[0,1,-1]]
[[0,1,0,0],[0,0,0,1],[1,0,0,0],[0,0,1,-1]]
[[0,0,1,0],[0,0,1,0],[1,0,-1,1],[0,1,0,0]]
[[0,0,0,1],[1,0,0,0],[-1,1,1,0],[1,0,0,0]]
[[1,0,1,0,-1],[0,1,0,0,0],[0,0,0,0,1],[0,0,0,1,0],[0,0,0,0,1]]
[[0,0,1,0,0],[0,1,-1,1,0],[1,-1,1,0,0],[0,1,1,-1,0],[0,0,-1,1,1]]
[[0,-1,0,1,1],[1,-1,1,-1,1],[0,1,1,0,-1],[1,1,-1,1,-1],[-1,1,0,0,1]]
[[0,0,1,0,0,0,0,0],[1,0,1,0,1,0,0,0],[0,0,0,1,-1,0,0,1],[0,0,1,-1,1,0,0,0],[0,0,0,0,0,0,1,0],[0,0,0,0,0,1,0,0],[0,1,-1,1,0,0,0,0],[0,0,1,0,0,0,0,0]]

Відповіді:


3

Сітківка , 62 58 56 53 байт

Кількість байтів передбачає кодування ISO 8859-1, і його \tслід замінити фактичними вкладками (0x09, які в іншому випадку перетворюються на пробіли SE).

$
\t$`¶
O$#`...(?<=^[^\t]*(.+))
$.1
T` 0
^(1(-11)*\s)+$

Формат введення - це матриця, де кожен стовпець використовує три символи, вирівняні вправо, наприклад:

  0  0  1  0
  1  0 -1  1
  0  1  0  0
  0  0  1  0

Вихід є або 0(фальшивим), або 1(truthy).

Тестовий набір. (Перші кілька рядків трансформують вхідний формат і дозволяють Retina запускати кілька тестових випадків одночасно.)

Пояснення

На щастя, вхід є квадратною матрицею: транспонування квадратів майже неможливо виконати в сітківці, тоді як переміщення прямокутників - це масова біль.

$
\t$`¶

Почнемо, додавши вкладку, весь вхід ще раз (використовуючи префікс $`), а потім в кінці рядка (використовуючи псевдонім Retina ). Ми використовуємо вкладку, щоб розділити дві копії, щоб ми могли їх розрізняти, коли переносимо одну з них, і, використовуючи символ пробілу, ми можемо зберегти пару байтів згодом.

O$#`...(?<=^[^\t]*(.+))
$.1

Це найскладніший біт: переміщення першої копії матриці. Ідея полягає в тому, щоб спочатку зіставити клітини, а потім сортувати їх (стабільно) за горизонтальним положенням. Ми порівнюємо клітинки з ...(оскільки вони завжди в ширину три символи), а потім вимірюємо горизонтальне положення (.+)зсередини зовні. Потім, щоб переконатися, що ми лише переносимо першу копію, ми перевіряємо, чи зможемо ми дійти до початку рядка, не проходячи повз вкладку.

Ви можете помітити, що це також буде відповідати деяким трибайтовим рядкам (які навіть не вирівнюються з комірками) у першому рядку другої копії, оскільки .+може проходити через вкладку. Однак це не проблема, оскільки горизонтальне положення цих сірників суворо більше, ніж будь-яке всередині першої копії, тому ці сірники залишаються у своєму положенні.

Решта досить проста:

T` 0

Видаляємо пробіли та нулі з вхідних даних.

^(1(-11)*\s)+$

І , нарешті , ми перевіряємо , що весь вхід складається з пробільних завершальних рядків форми 1(-11)*, тобто контрастною послідовності 1і -1яка починається і закінчується 1(так як в іншому випадку він не підсумовується з 1).


3

Желе, 15 байт

;Zḟ€0;€-;@€-IFP

Спробуйте в Інтернеті!

;Zḟ€0;€-;@€-IFP   Main monadic chain. Argument: z

;Z                Concatenate with its transpose.
  ḟ€0             Remove zeros from each sub-list. At this point,
                  one expects lists of the form [1, -1, 1, -1, ..., 1] for truthy,
                  and any other arrays containing purely 1 and -1 for falsey.
     ;€-          Append -1 to each sub-list.
        ;€@-      Prepend -1 to each sub-list.
            I     Compute the difference between each term. At this point,
                  for truthy, one expects arrays filled with 2, and arrays
                  containing 0 otherwise.
             FP   Product of every item. This checks if any item is equal to zero.

3

Pyth, 16 байт

!sm-sM._+d_1U2+C

Спробуйте в Інтернеті: Демонстрація або Тестовий набір

Пояснення:

!sm-sM._+d_1U2+CQQ   two implicit Qs (=input matrix) at the end
              +CQQ   zip Q and connect it with Q (=list of columns and rows)
  m                  map each column/row d to:
        +d_1            append -1 to d
      ._                compute all prefixes of ^
    sM                  compute the sums of the prefixes
   -        U2          remove zeros and ones
                        a column/row is correct, if this gives an empty list 
 s                   connect up all resulting lists
!                    check, if this result is empty

3

Желе , 11 байт

;Zj-+\ṚQḄ=2

Повертає 1 для змінних матриць знаків, 0 в іншому випадку. Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Фон

Не зважаючи на нулі, кожен рядок і стовпець повинен складатися з шаблону (1, -1) * 1 , тобто чергування випадків 1 і -1 , починаючи і закінчуючи рівнем 1 (тому сума дорівнює 1 ).

Щоб переконатися, що це так, ми беремо масив усіх рядків і стовпців і з'єднуємо їх, використовуючи -1 як роздільник. Оскільки всі кінцеві точки дорівнюють 1 ', отриманий плоский масив задовольняє шаблону (1, -1) * 1, якщо і лише в тому випадку, якщо це рядки та стовпці.

Для фактичного тесту обчислюємо сукупну суму масиву. Для змінної матриці знаків результатом буде масив 0 's та 1 ' s, який закінчується на 1 .

Ми перевертаємо сукупну суму і дедублюємо її, дотримуючись порядку початкових зустрічей усіх унікальних елементів. Для правдоподібного введення результатом буде список [1, 0] .

Для виведення відповідного булевого значення перетворюємо дублювані сукупні суми з двійкових у цілі числа та перевіряємо, чи результат 2 .

Як це працює

;Zj-+\ṚQḄ=2  Main link. Argument: M (matrix / 2D array)

 Z           Zip; transpose M's rows and columns.
;            Concatenate M and zipped M.
  j-         Join, separating by -1.
    +\       Take the cumulative sum of the result.
      Ṛ      Reverse the array of partial sums.
       Q     Unique; deduplicate the partial sums.
        Ḅ    Unbinary; convert from base 2 to integer.
         =2  Test for equality with 2.

2

MATL, 18 16 15 13 байт

3 байти збережено завдяки @Luis

t!h"@s1=@Xzdv

Це рішення приймає 2D-масив як вхідний і виводить масив truthy або falsey . Важливо зауважити, що в MATL тривистий масив складається з усіх ненульових елементів, тоді як результат фальси має принаймні один нульовий елемент. Ось ще одна демонстрація масивів truthy / falsey .

Спробуйте в Інтернеті

Модифікована версія для показу всіх тестових випадків

Пояснення

        % Implicitly grab input matrix
t!      % Duplicate and transpose input
h       % Horizontally concatenate input with transpose. This allows us to 
        % process only columns since now the columns *also* contain the rows.
"       % For each column (of our column/row combined matrix)
  @s1=  % Compute the sum and ensure it is equal to 1
  @Xz   % Get the non-zeros
  d     % Compute the element-to-element difference. The 1 and -1 alternate only if
        % all these differences are non-zero
  v     % Vertically concatenate everything on the stack
        % Implicit end of loop and implicitly display truthy/falsey value


1

JavaScript (ES6), 112 100 байт

a=>!/(^|,)(?!0*10*(-10*10*)*(,|$))/.test(a.map(b=>b.join``)+','+a.map((_,i)=>a.map(b=>b[i]).join``))

Вирівнювання масиву та його перенесення в рядки, потім (ігнорування 0s) перевіряє на зразок 1-11...1-11у кожній рядку.

Редагувати: Збережено 12 байт завдяки @PeterTaylor.


1
Вам не потрібно перевіряти шаблон, -11-1...-11-1оскільки оскільки записи чергуються і мають позитивну суму, їх має бути більше 1одного -1, тому шаблон повинен бути 1-11...1-11.
Пітер Тейлор

@PeterTaylor Фу, це вже другий раз, коли я неправильно прочитав питання. (Коментарі, що стосуються першого разу, з тих пір були видалені.)
Ніл,

Заголовок говорить про 110 байт, але це лише 100
Пітер Тейлор

1
@PeterTaylor Принаймні "збережений 12 байт завдяки @PeterTaylor" був правильним.
Ніл

1

Python 2, 63 60 байт

s=0;x=input()
for r in x+zip(*x):
 for n in(-1,)+r:s+=[n][s]

Введення - це список кортежів.

Це закінчується кодом виходу 0 для змінних матриць знаків та кодом виходу 1 в іншому випадку. Це те, що робиться правдою і помилкою , і - як показано в розділі перевірки - це дійсно може бути використане як умова, наприклад, у сценарії Bash.

Перевірка

тестові випадки.txt

[(1,)]
[(1, 0), (0, 1)]
[(0, 1), (1, 0)]
[(0, 1, 0), (0, 0, 1), (1, 0, 0)]
[(0, 1, 0), (1, -1, 1), (0, 1, 0)]
[(0, 1, 0, 0), (0, 0, 1, 0), (1, 0, 0, 0), (0, 0, 0, 1)]
[(1, 0, 0, 0), (0, 0, 1, 0), (0, 1, -1, 1), (0, 0, 1, 0)]
[(0, 0, 1, 0), (0, 1, -1, 1), (1, -1, 1, 0), (0, 1, 0, 0)]
[(0, 0, 1, 0), (1, 0, -1, 1), (0, 1, 0, 0), (0, 0, 1, 0)]
[(0, 0, 1, 0, 0), (0, 1, -1, 1, 0), (1, -1, 1, 0, 0), (0, 1, 0, -1, 1), (0, 0, 0, 1, 0)]
[(0, 0, 1, 0, 0, 0, 0, 0), (1, 0, -1, 0, 1, 0, 0, 0), (0, 0, 0, 1, -1, 0, 0, 1), (0, 0, 1, -1, 1, 0, 0, 0), (0, 0, 0, 0, 0, 0, 1, 0), (0, 0, 0, 0, 0, 1, 0, 0), (0, 1, -1, 1, 0, 0, 0, 0), (0, 0, 1, 0, 0, 0, 0, 0)]
[(0, 0, 0, 0, 1, 0, 0, 0), (0, 0, 1, 0, -1, 1, 0, 0), (0, 0, 0, 1, 0, 0, 0, 0), (1, 0, 0, -1, 1, -1, 1, 0), (0, 1, -1, 1, -1, 1, 0, 0), (0, 0, 0, 0, 1, 0, 0, 0), (0, 0, 1, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 1)]
[(0,)]
[(-1,)]
[(1, 0), (0, 0)]
[(0, 0), (0, 1)]
[(-1, 1), (1, 0)]
[(0, 1), (1, -1)]
[(0, 0, 0), (0, 0, 0), (0, 0, 0)]
[(0, 1, 0), (1, 0, 1), (0, 1, 0)]
[(-1, 1, 1), (1, -1, 1), (1, 1, -1)]
[(0, 0, 1), (1, 0, 0), (0, 1, -1)]
[(0, 1, 0, 0), (0, 0, 0, 1), (1, 0, 0, 0), (0, 0, 1, -1)]
[(0, 0, 1, 0), (0, 0, 1, 0), (1, 0, -1, 1), (0, 1, 0, 0)]
[(0, 0, 0, 1), (1, 0, 0, 0), (-1, 1, 1, 0), (1, 0, 0, 0)]
[(1, 0, 1, 0, -1), (0, 1, 0, 0, 0), (0, 0, 0, 0, 1), (0, 0, 0, 1, 0), (0, 0, 0, 0, 1)]
[(0, 0, 1, 0, 0), (0, 1, -1, 1, 0), (1, -1, 1, 0, 0), (0, 1, 1, -1, 0), (0, 0, -1, 1, 1)]
[(0, -1, 0, 1, 1), (1, -1, 1, -1, 1), (0, 1, 1, 0, -1), (1, 1, -1, 1, -1), (-1, 1, 0, 0, 1)]
[(0, 0, 1, 0, 0, 0, 0, 0), (1, 0, 1, 0, 1, 0, 0, 0), (0, 0, 0, 1, -1, 0, 0, 1), (0, 0, 1, -1, 1, 0, 0, 0), (0, 0, 0, 0, 0, 0, 1, 0), (0, 0, 0, 0, 0, 1, 0, 0), (0, 1, -1, 1, 0, 0, 0, 0), (0, 0, 1, 0, 0, 0, 0, 0)]

test-suite.sh

while read; do
        if python2 asmv.py <<< "$REPLY"; then
                echo "true"
        else
                echo "false"
        fi
done < test-cases.txt 2>&- | uniq -c

Вихідні дані

$ bash test-suite.sh
     12 true
     17 false

Як це працює

Не зважаючи на нулі, кожен рядок і стовпець повинен складатися з шаблону (1, -1) * 1 , тобто чергування випадків 1 і -1 , починаючи і закінчуючи рівнем 1 (тому сума дорівнює 1 ).

Щоб переконатися, що це так, ми поштовхуємо / транспонируем вхідну матрицю M , додаємо результат до M (тепер складається зі списку рядків і стовпців) і додаємо -1 до кожного рядка / стовпця.

Наприклад, якщо M є однією з таких матриць (дійсна, недійсна)

     0  1  0         0  0  0
     0  0  1         1  0  0
     1  0  0         0  1 -1

результати є

-1 | 0  1  0    -1 | 0  0  0
-1 | 0  0  1    -1 | 1  0  0
-1 | 1  0  0    -1 | 0  1 -1
------------    ------------
-1 | 0  0  1    -1 | 0  1  0
-1 | 1  0  0    -1 | 0  0  1
-1 | 0  1  0    -1 | 0  0 -1

Читання генерованої матриці рядків мусить призвести до плоскої послідовності з малюнком (-1, 1) * . Щоб переконатися, що це так, ми беремо сукупну суму всіх записів, починаючи з верхнього рядка.

Для прикладних матриць це призводить до

-1 -1  0  0 -1 -1 -1  0 -1  0  0  0 -1 -1 -1  0 -1  0  0  0 -1 -1  0  0
-1 -1 -1 -1 -2 -1 -1 -1 -2 -2 -1 -2 -3 -3 -2 -2 -3 -3 -3 -2 -3 -3 -3 -4

Для дійсної змінної матриці знаків, вихід буде складатися з -10 ' s, - оскільки кожен -1 скасовує попереднє 1 і навпаки - ніяких інших чисел.

На перший погляд, це може здатися невдалим перевірити, чи останній стовпець закінчується знаком 1 . Однак для матриці n × n, що містить k нулі, дійсні рядки будуть містити n + k . Якби всі стовпці, крім останнього, також були дійсними , у стовпцях було б n + k - 1 , що неможливо.

Щоб перевірити, що немає інших чисел, ми зберігаємо часткові суми у змінній s та оновлюємо їх для кожного запису з генерованою матрицею s+=[n][s].

Якщо s = 0 або s = -1 , це еквівалентно s+=n. Однак для всіх інших значень s він викликає IndexError , тому Python негайно припиняється кодом виходу 1 . Якщо цього не відбувається в будь-який момент, програма закінчується чисто кодом виходу 0 .


0

R, 54 байти

Анонімна функція, використовує ту саму логіку, що і відповіді Dennis's Python 2, Jelly та Julia.

function(x)all(abs(cumsum(rbind(-1,cbind(t(x),x))))<2)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.