Проверка матрицы переменного знака


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 значения.

Это , поэтому цель состоит в том, чтобы минимизировать количество используемых байтов.

Контрольные примеры

Следующие тестовые примеры приведены в формате списка в стиле 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]]

Falsy:

[[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

Retina , 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(правдивый).

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

объяснение

К счастью, ввод представляет собой квадратную матрицу: транспонирование квадратов практически выполнимо в 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 и 1 , который заканчивается на 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

Это решение принимает двумерный массив в качестве входных данных и выводит массив истинности или ложности . Важно отметить, что в MATL истинный массив состоит из всех ненулевых элементов, в то время как результат Фальси имеет по крайней мере один нулевой элемент. Вот еще одна демонстрация массивов правды / фальши .

Попробуйте онлайн

Модифицированная версия, чтобы показать все тестовые случаи

объяснение

        % 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 в противном случае. Это то, что делают true и false , и - как показано в разделе проверки - это действительно может использоваться как условие, например, в скрипте Bash.

верификация

Тест-cases.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

Для действительной матрицы знакопеременных выходной результат будет состоять из -1 и 0 и - так как каждый -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 байта

Анонимная функция, использует ту же логику, что и ответы Денниса на 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.