Матрица занимает первое место?


21

Учитывая матрицу целых чисел, проверьте, является ли она рангом один, означая, что каждая строка кратна одному и тому же вектору. Например, в

 2   0  -20  10  
-3   0   30 -15
 0   0   0   0

каждая строка кратна 1 0 -10 5.

Это же определение также работает со столбцами вместо строк. В качестве альтернативы, матрица занимает первое место, если она похожа на таблицу умножения:

 *    1   0  -10  5
    ----------------
 2 |  2   0  -20  10  
-3 | -3   0   30 -15
 0 |  0   0   0   0

Мы присвоили метки строк и меток r[i]столбцов, c[j]чтобы каждая запись матрицы M[i][j]была произведением соответствующих меток как M[i][j] = r[i] * c[j].

Входные данные:

Целочисленная матрица как 2D контейнер на ваш выбор. Например, список списков, двумерный массив или аналогичный. Вы не должны принимать ширину или высоту в качестве дополнительных входных данных, если формат массива не требует этого.

Матрица может быть не квадратной. В ней будет хотя бы одна ненулевая запись - вам не нужно иметь дело с пустыми или нулевыми матрицами.

Вы можете предположить, что целые числа не вызовут проблем переполнения.

Выход:

Согласованное значение для матриц ранга один и другое согласованное значение для других матриц.

Встроенные модули:

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

Тестовые случаи:

Ранг-один:

[[2, 0, -20, 10], [-3, 0, 30, -15], [0, 0, 0, 0]]
[[0, 0, 0], [0, 3, 0], [0, 0, 0]]
[[-10]]
[[0, 0, 0], [0, 4, 11], [0, -4, -11]]

Не на первом месте

[[-2, 1], [2, 4]]
[[0, 0, 3], [-22, 0, 0]]
[[1, 2, 3], [2, 4, 6], [3, 6, 10]]
[[0, -2, 0, 0], [0, 0, 0, 1], [0, 0, -2, 0]]

Leaderboard:


2
Любопытно, что ответ Mathematica с использованием встроенных функций будет выглядеть следующим образом (16 байт):MatrixRank@#==1&
JungHwan Мин.


2
Красивая теорема состоит в том, что ранг столбца равен рангу строки для конечномерных матриц.
Утренняя монахиня

3
Должны ли мы беспокоиться о точности точности? Например, они могут заставить матрицу ранга 1 казаться рангом 2
Луис Мендо

@LuisMendo Вы должны справиться с проблемами точности, такими как собственные значения 1.0000000001, но можете предположить, что матрица невелика и специально не выбрана для неправильной классификации.
xnor

Ответы:


13

Желе , 6 байт

ẸÐfÆrE

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

Как это устроено

ẸÐfÆrE  Main link. Argument: M (2D array)

ẸÐf     Filter by any, removing rows of zeroes.
   Ær   Interpret each row as coefficients of a polynomial and solve it over the
        complex numbers.
     E  Test if all results are equal.

точность

Ærиспользует численные методы, поэтому его результаты обычно неточны. Например, вход [6, -5, 1] , представляющий полином 6 - 5x + x² , приводит к корням 3.0000000000000004 и 1.9999999999999998 . Однако умножение всех коэффициентов многочлена на одну и ту же ненулевую константу приводит к одинаково неточным корням. Например, Ærполучает одинаковые корни для [6, -5, 1] и [6 × 10 100 , -5 × 10 100 , 10 100 ] .

Следует отметить, что ограниченная точность типов float и сложных типов может привести к ошибкам. Например, Ærполучили бы одинаковые корни для [1, 1] и [10 100 , 10 100 + 1] . Поскольку мы можем предположить, что матрица невелика и специально не выбрана для неправильной классификации , это должно быть хорошо.


5
умножение всех коэффициентов многочлена на одну и ту же ненулевую константу приводит к одинаково неточным корням. Это блестящий подход
Луис Мендо,

8

Haskell , 50 байтов

rберет список списков Integers и возвращает, Falseесли матрица имеет ранг один, в Trueпротивном случае.

r l=or[map(x*)b<map(y*)a|a<-l,b<-l,(x,y)<-zip a b]

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

Как это устроено

  • Генерирует все пары строк aи b(включая равные строки), а для каждой пары позволяет xи yпроходит через соответствующие элементы.
  • Умножает строку bна xи строку aна y. Матрица будет иметь ранг один в том и только в том случае, если результаты всегда равны.
  • Поскольку пары генерируются в обоих порядках, <их можно использовать для проверки наличия неравенства. Список результатов теста объединяется с orуказанием Trueналичия непропорциональных строк.

7

Mathematica, 51 33 байта

RowReduce@#~Count~Except@{0..}<2&

вход

[{{2,0, -20,10}, {- 3,0,30, -15}, {0,0,0,0}}]

-14 байтов от user202729 Еще
3 байта сохранено от junghwanmin


Я предлагаю вместо того, чтобы построить таблицу с длиной, равной длине of First@#, вы можете вычислить, 0First@#так как 0 умножается на все, равное 0, а умножение является списочным. Также вы можете рассмотреть возможность использования Tr[1^<list>]для расчета длины списка.
user202729

очень приятно. Я буду редактировать!
J42161217,

Вместо того 0#&@@#, {0..}чтобы работать тоже. И тогда Infixработает, так что окончательный код может быть RowReduce@#~Count~{0..}==Tr[1^#]-1&, сохраняя 2 байта.
JungHwan Мин.

На самом деле, Exceptмогут быть использованы, чтобы избавиться от Trвещей. -3 байта:RowReduce@#~Count~Except@{0..}==1&
JungHwan Мин.

Я думаю, что матрица с уменьшенной строкой гарантированно будет отлична от нуля (поскольку исходная матрица отлична от нуля), поэтому результат подсчета будет положительным целым числом, поэтому <2его можно использовать вместо ==1.
user202729

4

JavaScript (ES6), 68 67 65 байт

Этот основан на ответе Нейла 05AB1E и значительно более эффективен, чем мой первоначальный подход.

Возвращает falseза первое место и в trueпротивном случае.

f=(a,R,V,X)=>a.some(r=>r.some((v,x)=>R?v*V-r[X]*R[x]:f(a,r,v,x)))

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


Оригинальный ответ, 84 байта

Возвращает falseза первое место и в trueпротивном случае.

a=>a.some(r=>r.some((x,i)=>(isNaN(x/=a.find(r=>r.some(x=>x))[i])?r:1/r[0]?r=x:x)-r))

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

Как?

a => a.some(r =>          // given a matrix a, for each row r of a:
  r.some((x, i) =>        //   for each value x of r at position i:
    (                     //
      isNaN(x /=          //     divide x by a[ref][i]
        a.find(r =>       //       where ref is the index of the first row that
          r.some(x => x)  //       contains at least one non-zero value
        )[i]              //       (guaranteed to exist by challenge rules)
      ) ?                 //     we get NaN for 0/0, in which case:
        r                 //       use r, so that this column is ignored
      :                   //     else:
        1 / r[0] ?        //       if r is still holding the current row:
          r = x           //         set it to x (either a float, +Inf or -Inf)
        :                 //       else:
          x               //         use x
    ) - r                 //     subtract r from the value set above (see table)
  )                       //   end of some()
)                         // end of every()

Вычитание, которое выполняется в конце кода, может привести к множеству различных ситуаций, которые приведены ниже:

A                   | B              | A - B       | False / True
--------------------+----------------+-------------+-------------
array of 1 number   | same array     | 0           | False
array of 2+ numbers | same array     | NaN         | False
a number            | same number    | 0           | False
+Infinity           | +Infinity      | NaN         | False
-Infinity           | -Infinity      | NaN         | False
a number            | another number | <> 0        | True
+Infinity           | -Infinity      | +Infinity   | True
-Infinity           | +Infinity      | -Infinity   | True
a number            | +/-Infinity    | +/-Infinity | True
+/-Infinity         | a number       | +/-Infinity | True

Тест не пройден , как только мы получим значение truthy: это происходит , когда мы сталкиваемся два различных коэффициентов (кроме 0/0 ) между а (х, у) и а (I, R) в любой строке у матрицы, где r - индекс ненулевой строки.


Да, мне просто интересно, что сам ...
Нил

@Neil Хотите опубликовать его как новый ответ? Просто дай мне знать.
Arnauld


3

Желе , 12 байт

ẸÐfµ÷"ЀZE€Ẹ

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

объяснение

ẸÐfµ÷"ЀZE€Ẹ  Main link
 Ðf           Filter; keep all elements where
Ẹ             At least one element is truthy (remove zero-rows)
      Ѐ      For each row on the right side
    ÷"        Divide it by each row in the original
        Z     Zip the array
          €   For each submatrix
         E    Are all rows equal?
           Ẹ  Is at least one of the elements from above truthy?

Объяснение может быть немного неверным, так как это моя интерпретация мили миль моего первоначального алгоритма

-5 байт благодаря милям


... Ваш код привязан к деньгам. (Я получаю дежа вю ...)
полностью человек

@icrieverytim Эй, по крайней мере, число знаков доллара на этот раз меньше половины длины кода! : P
HyperNeutrino

1
@icrieverytim исправил ошибку, а теперь еще меньше знаков доллара: P
HyperNeutrino

Я считаю, что это должно работать также для 12 байтов ẸÐfµ÷"ЀZE€Ẹ TIO
миль

@ Майлз О, хорошо! Ваш подход немного отличается (я думаю?), Поэтому вы можете опубликовать это как свой собственный ответ, который вам хотелось бы :)
HyperNeutrino

3

05AB1E , 16 байтов

2ãεø2ãε`R*`Q}W}W

Попробуйте онлайн! Использует свойство таблицы умножения о том, что противоположные углы любого прямоугольника имеют одинаковое произведение. Объяснение:

2ãε           }     Loop over each pair of rows
   ø                Transpose the pair into a row of pairs
    2ãε     }       Loop over each pair of columns
       `R*`Q        Cross-multiply and check for equality
             W W    All results must be true

3

TI-Basic (серия TI-83), 28 27 28 байтов (62 символа)

:Prompt [A]
:{0→X
:Matr►list(ref([A])ᵀ,L₁,X
:not(max(abs(ᶫX

Вычисляет форму строки в эшелоне матрицы [A], сохраняет ее первую строку (подлежащую отбрасыванию) в, L₁а вторую - в ᶫX. Тогда max(abs(ᶫXбудет ноль, если ᶫXсостоит только из нулей, и положительное значение в противном случае, котороеnot( изменится на 1, если матрица имеет ранг один, в противном случае - на 0.

Для матрицы с 1 строкой ᶫXустанавливается {0}и затем не изменяется, когда мы пытаемся посмотреть на несуществующую вторую строку матрицы.


-1 байт благодаря Скотту Милнеру

+1 байт, чтобы исправить ошибку измерения для 1-рядных матриц. Оказывается, Matr►list( команда жалуется, если вы пытаетесь извлечь вторую строку из матрицы только с одной строкой; однако, если вы попытаетесь извлечь первую и вторую строки из матрицы, произойдет молчание.


1
Вы можете сохранить байт Prompt [A]вместо Ans→[A].
Скотт Милнер

@ScottMilner Спасибо! Вероятно, есть способ избежать любого, если мы используем что-то вроде ClrListинициализации ᶫX, но я не совсем понял, чтобы работать в меньшем пространстве.
Миша Лавров

Избавьтесь от второй строки, поскольку Matr►list(список будет перезаписан, даже если он не существует, и вы сэкономите 5 байтов.
kamoroso94

1
@ kamoroso94 Смысл второй строки - не создавать список, когда он не существует: суть второй строки - создать значение по умолчанию для второй строки, когда матрица имеет только одну строку. Если вы избавитесь от второй строки, код сбоев для матриц 1xN.
Миша Лавров

2
@ kamoroso94 Мы должны заменить L1 на ᶫY, а не Y; в противном случае калькулятор подумает «извлечь Y-ю строку матрицы в ᶫX», а не «извлечь первую строку в ᶫY, а вторую строку в ᶫX».
Миша Лавров

3

Брахилог , 27 байт

{⊇Ċ}ᶠzᵐ{↰₁ᶠ{⟨hz{t↔}⟩×ᵐ=}ᵐ}ᵐ

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

Использует подход Нейла «произведения противоположных углов каждого прямоугольника должны быть равны». Совокупный продукт является дорогостоящим и занимает 10 целых байтов, но это все же короче, чем любой подход, основанный на делении, который я пробовал, в основном из-за наличия в вопросе двух последовательных выходных данных для правдивого и фальшивого - сделать фальси только false., а не иногда ошибка деления на ноль, использует слишком много байтов.

{⊇Ċ}ᶠzᵐ{↰₁ᶠ{⟨hz{t↔}⟩×ᵐ=}ᵐ}ᵐ
{⊇Ċ}ᶠ                        Get each pair of rows from the matrix
                             eg.: [ [[a, b, c], [k, l, m]], ... ]
     zᵐ                      Zip each pair's elements
                                  [ [[a, k], [b, l], [c, m]], ... ]
       {                 }ᵐ  Map this over each pair of rows:
                                  [[a, k], [b, l], [c, m]]
        ↰₁ᶠ                  Get each pair of paired elements from the rows
                                  [[[a, k], [b, l]], [[b, l], [c, m]], [[a, k], [c, m]]]
           {           }ᵐ    Map this over each pair of pairs
                                  [[a, k], [b, l]]
            ⟨hz{t↔}⟩         Zip the first pair with the reverse of the second
                                  [[a, l], [k, b]]
                    ×ᵐ       Multiply within each sublist
                                  [al, kb]
                      =      The results should be equal
                             (If the results are unequal for any pair, the whole predicate fails,
                              and outputs false.)

Альтернативный подход, основанный на поэлементном делении ( 30 байтов ):

{≡ᵉ¬0&}ˢ\↰₁ˢ{c׬0&⟨hz∋⟩ᶠ/ᵐ²=ᵐ}

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



1

SageMath, 40 байт

lambda M:any(M.rref()[1:])*(M.nrows()>1)

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

Эта анонимная функция возвращает, Falseесли матрица ранга один, иTrue противном случае.

Функция принимает матрицу в Mкачестве входных данных, преобразует ее в сокращенную форму row-echelon ( M.rref()) и проверяет, чтобы anyстроки после первой строки были ненулевыми. Затем это значение умножается на M.nrows()>1(матрица имеет более одной строки?).


1

Python 3 , 93 91 байт

lambda m,e=enumerate:any(h*g-r[j]*s[i]for r in m for i,h in e(r)for s in m for j,g in e(s))

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

Как это устроено

Проверяет, имеет ли какой-либо 2-минорный ненулевой определитель. В этом случае ранг должен быть не менее 2: «неисчезающий p-минор (подматрица p × p с ненулевым определителем) показывает, что строки и столбцы этой подматрицы линейно независимы, и, следовательно, эти строки и столбцы полной матрицы линейно независимы (в полной матрице), поэтому ранг строки и столбца, по крайней мере, так же велик, как и детерминантный ранг "(из Википедии )

Примечание: побрили два байта благодаря комментарию user71546.


1
91 - короче, если поместить перечисление в аргументы функции и, таким образом, исключить необходимость f=:lambda m,e=enumerate:any(h*g-r[j]*s[i]for r in m for i,h in e(r)for s in m for j,g in e(s))
Шиеру Асакото

@ user71546 Спасибо! Сделал это!
Лука Сити

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.