Если в качестве входных данных задана квадратная целочисленная матрица, выведите определитель матрицы.
правила
- Вы можете предположить, что все элементы в матрице, определитель матрицы и общее количество элементов в матрице находятся в пределах представимого диапазона целых чисел для вашего языка.
- Разрешается вывод десятичного значения / значения с плавающей запятой с дробной частью 0 (например,
42.0
вместо42
). - Встроенные функции разрешены, но рекомендуется включать решение, не использующее встроенные функции.
Тестовые случаи
[[42]] -> 42
[[2, 3], [1, 4]] -> 5
[[1, 2, 3], [4, 5, 6], [7, 8, 9]] -> 0
[[13, 17, 24], [19, 1, 3], [-5, 4, 0]] -> 1533
[[372, -152, 244], [-97, -191, 185], [-53, -397, -126]] -> 46548380
[[100, -200, 58, 4], [1, -90, -55, -165], [-67, -83, 239, 182], [238, -283, 384, 392]] -> 571026450
[[432, 45, 330, 284, 276], [-492, 497, 133, -289, -28], [-443, -400, 56, 150, -316], [-344, 316, 92, 205, 104], [277, 307, -464, 244, -422]] -> -51446016699154
[[416, 66, 340, 250, -436, -146], [-464, 68, 104, 471, -335, -442], [159, -407, 310, -489, -248, 370], [62, 277, 446, -325, 47, -193], [460, 460, -418, -28, 234, -374], [249, 375, 489, 172, -423, 125]] -> 39153009069988024
[[-246, -142, 378, -156, -373, 444], [186, 186, -23, 50, 349, -413], [216, 1, -418, 38, 47, -192], [109, 345, -356, -296, -47, -498], [-283, 91, 258, 66, -127, 79], [218, 465, -420, -326, -445, 19]] -> -925012040475554
[[-192, 141, -349, 447, -403, -21, 34], [260, -307, -333, -373, -324, 144, -190], [301, 277, 25, 8, -177, 180, 405], [-406, -9, -318, 337, -118, 44, -123], [-207, 33, -189, -229, -196, 58, -491], [-426, 48, -24, 72, -250, 160, 359], [-208, 120, -385, 251, 322, -349, -448]] -> -4248003140052269106
[[80, 159, 362, -30, -24, -493, 410, 249, -11, -109], [-110, -123, -461, -34, -266, 199, -437, 445, 498, 96], [175, -405, 432, -7, 157, 169, 336, -276, 337, -200], [-106, -379, -157, -199, 123, -172, 141, 329, 158, 309], [-316, -239, 327, -29, -482, 294, -86, -326, 490, -295], [64, -201, -155, 238, 131, 182, -487, -462, -312, 196], [-297, -75, -206, 471, -94, -46, -378, 334, 407, -97], [-140, -137, 297, -372, 228, 318, 251, -93, 117, 286], [-95, -300, -419, 41, -140, -205, 29, -481, -372, -49], [-140, -281, -88, -13, -128, -264, 165, 261, -469, -62]] -> 297434936630444226910432057
You may assume that all elements in the matrix, the determinant of the matrix, and the total number of elements in the matrix are within the representable range of integers for your language.
Ответы:
Желе , 15 байт
Попробуйте онлайн!
Как это работает
Почему это работает - математическая версия
Оператор det берет матрицу и возвращает скаляр. Матрица n- by- n может рассматриваться как набор из n векторов длины n , поэтому det действительно является функцией, которая берет n векторов из ℤ n. и возвращает скаляр.
Поэтому я пишу det ( v 1 , v 2 , v 3 , ..., v n ) для det [ v 1 v 2 v 3 ... v n ].
Обратите внимание, что det является линейным в каждом аргументе, то есть det ( v 1 + λ w 1 , v 2 , v 3 , ..., v n ) = det ( v 1 , v 2 , v 3 , ..., v n ) + λ det ( w 1 , v 2 , v 3 , ..., v n ). Следовательно, это линейное отображение из (ℤ n ) ⊗ n к ℤ.
Достаточно определить изображение базиса по линейной карте. Базис (ℤ n ) ⊗ n состоит из n- кратных тензорных произведений базисных элементов из ℤ n , т. Е. E 5 e 3 e 1 e 5 e 1 . Тензорные произведения, которые содержат идентичные тензоры, должны быть отправлены в ноль, поскольку определитель матрицы, в которой два столбца идентичны, равен нулю. Осталось проверить, на что отправляются тензорные произведения различных базисных элементов. Индексы векторов в тензорном произведении образуют биекцию, то есть перестановку, в которой четные перестановки отправляются в 1, а нечетные перестановки отправляются в -1.
Например, чтобы найти определитель [[1, 2], [3, 4]]: обратите внимание, что столбцами являются [1, 3] и [2, 4]. Разложим [1, 3], чтобы получить (1 e 1 + 3 e 2 ) и (2 e 1 + 4 e 2 ). Соответствующий элемент в тензорном произведении равен (1 e 1 ⊗ 2 e 1 + 1 e 1 ⊗ 4 e 2 + 3 e 2 ⊗ 2 e 1 + 3 e 2 ⊗ 4 e 2 ), который мы упрощаем до (2 e 1 1 e 1 + 4 e 1 ⊗ e 2 + 6 e 2 ⊗ e 1 + 12 e 2 ⊗ e 2). Следовательно:
det [[1, 2], [3, 4]]
= det (1 e 1 + 3 e 2 , 2 e 1 + 4 e 2 )
= det (2 e 1 ⊗ e 1 + 4 e 1 ⊗ e 2 + 6 e 2 ⊗ e 1 + 12 e 2 ⊗ e 2 )
= det (2 e 1 ⊗ e 1 ) + det (4 e 1 ⊗ e 2 ) + det (6 e 2 ⊗ e 1 ) + det (12 e22 e 2 )
= 2 det (e 1 ⊗ e 1 ) + 4 det (e 1 ⊗ e 2 ) + 6 det (e 2 ⊗ e 1 ) + 12 det (e 2 ⊗ e 2 )
= 2 (0) + 4 (1) + 6 (-1) + 12 (0)
= 4 - 6
= -2
Теперь осталось доказать, что формула для нахождения четности перестановки справедлива. То, что делает мой код, по сути, находит количество инверсий, то есть мест, где элемент слева больше, чем элемент справа (не обязательно последовательно).
Например, в перестановке 3614572 имеется 9 инверсий (31, 32, 61, 64, 65, 62, 42, 52, 72), поэтому перестановка является нечетной.
Обоснование состоит в том, что каждая транспозиция (замена двух элементов) либо добавляет одну инверсию, либо убирает одну инверсию, меняя четность числа инверсий, а четность перестановки - это четность числа транспозиций, необходимых для достижения перестановки.
Поэтому в заключение наша формула имеет вид:
Почему это работает - нематематическая версия
где σ является перестановкой 𝕊 п группы всех перестановок п букв и SGN является знаком перестановки, AKA (-1) , возведенная четности перестановки, и IJ является ( IJ ) -й записью в матрица ( я вниз, J поперек).
источник
R , 3 байта
Простое решение
Попробуйте онлайн!
R ,
9492 байтаВнедренное решение
перехитрил Ярко Дуббельдам
Попробуйте онлайн!
Рекурсивно использует разложение по несовершеннолетним вниз по первому столбцу матрицы.
источник
Желе ,
16151210 байтИспользует расширение Лапласа . Спасибо @miles за отыгрыш
35 байтов!Попробуйте онлайн!
Как это работает
источник
Wolfram Language (Mathematica) , между 14 и 42 байтами
У нас было 3-байтовое встроенное и 53-байтовое решение которое полностью избегает встроенных функций, так что вот несколько странных решений где-то посередине.
В Wolfram Language есть много очень интенсивных функций для разложения матриц на произведения других матриц с более простой структурой. Одним из более простых (то есть я слышал об этом раньше) является разложение Джордана. Каждая матрица аналогична (возможно, комплексной) верхней треугольной матрице, составленной из диагональных блоков с определенной структурой, называемой жордановым разложением этой матрицы. Сходство сохраняет определители, а определитель треугольной матрицы является произведением диагональных элементов, поэтому мы можем вычислить определитель со следующими 42 байтами :
Определитель также равен произведению собственных значений матрицы на кратность. К счастью, функция собственных значений Wolfram отслеживает кратность (даже для недиагонализируемых матриц), поэтому мы получаем следующее 20-байтовое решение:
Следующее решение - это обман, и я не совсем уверен, почему это работает. Вронскиан списка из n функций является определителем матрицы первых n -1 производных функций. Если мы дадим
Wronskian
функции матрицу целых чисел и скажем, что переменная дифференцирования равна 1, каким-то образом она выплескивает определитель матрицы. Это странно, но не включает буквы "Det
" и это всего лишь 14 байтов ...(The Casoratian детерминанта работает так же, для более 1 байт:
#~Casoratian~1&
)В области абстрактной алгебры определитель матрицы n x n (рассматриваемой как отображение k → k, которая является умножением на определитель) является n- й внешней степенью матрицы (после выбора изоморфизма k → k n k н ). На языке Wolfram мы можем сделать это со следующими 26 байтами :
И вот решение, которое работает только для положительных определителей. Если мы возьмем n- мерный единичный гиперкуб и применим к нему линейное преобразование, то n- мерный «объем» результирующей области является абсолютным значением определителя преобразования. Применение линейного преобразования к кубу дает параллелепипед, и мы можем взять его объем со следующими 39 байтами кода:
источник
Exp@*Tr@*MatrixLog
, но, к сожалению, это не работает для единичных матриц.Check[E^Tr@MatrixLog@#,0]&
.Check
раньше.Haskell , 71 байт
-3 байта благодаря Линн. Еще один байт пыли благодаря Крейг Рой.
Попробуйте онлайн! Добавлен
-O
флаг для оптимизации. Это не обязательно.Объяснение (устарело)
f
рекурсивно реализует расширение кофактора.Эта строка покрывает базовый случай матрицы 1 × 1 , и в этом случае определитель равен
mat[0, 0]
.При этом используется сопоставление с образцом в Haskell, чтобы разбить матрицу на голову (первую строку) и хвост (на остальную часть матрицы).
Перечислите заголовок матрицы (сжав бесконечный список целых чисел и заголовок) и переберите его.
Отрицательный результат зависит от того, является ли его индекс четным, поскольку вычисление определителя включает в себя чередование сложения и вычитания.
Это по существу удаляет i-й столбец хвоста, беря элементы i и объединяя его со строкой с первыми (i + 1) -ыми элементами, отброшенными для каждой строки в хвосте.
Вычислить определитель результата выше и умножить его на результат
(-1)*i*v
.Суммируйте результат из списка выше и возвращайте его.
источник
sum[(-1)^i*...
сfoldr(-)0[...
Протон , 99 байт
Попробуйте онлайн!
-3 байта благодаря мистеру Xcoder
-3 байта благодаря Эрику Аутгольферу
Расширение по первому ряду
источник
((~i%2)*2-1)
->((-i%2)|1)
j!=i
наj-i
илиi-j
.Октава , 28 байт
Попробуйте онлайн!
При этом используется QR - разложение матричного X в orthgonal матрицы Q и верхняя треугольная матрица R . Определитель X является произведением тех из Q и R . Ортогональная матрица имеет единичный определитель, а для треугольной матрицы определитель является произведением ее диагональных элементов.
qr
Функция Octave, вызываемая с одним выходом, дает R .Результат округляется до ближайшего целого числа. Для больших входных матриц неточности с плавающей точкой могут привести к превышению ошибки
0.5
и, следовательно, к неправильному результату.источник
det
встроенного. ;)Haskell , 59 байт
Попробуйте онлайн!
источник
C
176125 байтСпасибо @ceilingcat за игру в гольф 42 байта и спасибо @Lynn и @Jonathan Frech за сохранение каждого байта!
Вычисляет определитель, используя разложение Лапласа вдоль первого ряда.
Попробуйте онлайн!
раскатали:
источник
(i%2*-2+1)
→(1-i%2*2)
сохраняет еще один байт.n+1+c
может бытьn-~c
.i=s
вместоreturn s
Желе , 43 байта
Наконец-то я закончил писать свое не встроенное решение на языке игры в гольф!
Спасибо HyperNeutrino за сохранение байта!
Попробуйте онлайн! (интервал кода для ясности)
ужасно длинный способ удалить n-ые элементы из списка, улучшится позже
Этот ответ был превзойден ответами HyperNeutrino, Денниса и Лики Нун. Желе очень популярно как язык для игры в гольф.
Быстрое объяснение:
источник
Желе , 24 байта
Попробуйте онлайн!
объяснение
-2 байта благодаря решению пользователя 202729
источник
MATL , 3 байта / 5 байтов
Со встроенной функцией
Попробуйте онлайн!
Без встроенного
Спасибо Мише Лаврову за указание на ошибку, теперь исправленную
Попробуйте онлайн!
Это вычисляет детерминант как произведение собственных значений, округленных до ближайшего целого числа, чтобы избежать неточностей с плавающей точкой.
источник
R , 32 байта
Использует не Древовидный алгоритм взятия собственных значений матрицы и взятия реальной части их произведения.
Попробуйте онлайн!
источник
Октава , 30 байт
Попробуйте онлайн!
или скучное 4-байтовое решение (сэкономило 6 байтов благодаря Луису Мендо (забыл правила, касающиеся встроенных функций)):
Объяснение:
Подходит! :)
источник
TI-Basic, 2 байта
Ах хорошо.
Пожалуйста, не одобряйте тривиальные ответы.
Для старшеклассника (который вынужден владеть одним из этих калькуляторов) эта функция полезна, так что ...
источник
Haskell, 62 байта
Попробуйте онлайн! (Нижний колонтитул с контрольными примерами взят из решения @ totallyhuman.)
d
вычисляет определитель, используя разложение Лапласа вдоль первого столбца. Требуется на три байта больше, чем постоянный .источник
Python 2 , 95 байт
-12 байт благодаря Линн.
Порт моего Хаскелла ответ .
Попробуйте онлайн!
источник
[]
в качестве базового варианта:f=lambda m:sum((-1)**i*v*f([j[:i]+j[i+1:]for j in m[1:]])for i,v in enumerate(m[0]))if m else 1
за 95 байт!m==[]or sum(...)
дает 92 байта.Wolfram Language (Mathematica) ,
5352 байтаПопробуйте онлайн!
К сожалению, таким образом при вычислении определителя матрицы n на n используется память O ( n n ), что делает недоступными большие тестовые случаи.
Как это работает
Первая часть,
1##&@@@(t=Tuples)@#
вычисляет все возможные произведения термина из каждой строки данной матрицы.t[Range@Tr[1^#]&/@#]
дает список такой же длины, элементами которого являются такие вещи, как{3,2,1}
или{2,2,3}
говорящие, какую запись каждой строки мы выбрали для соответствующего продукта.Мы применяем
Signature
ко второму списку, который отображает четные перестановки1
, нечетные перестановки-1
и неперестановки0
. Это как раз тот коэффициент, с которым соответствующий продукт появляется в определителе.Наконец, мы берем скалярное произведение двух списков.
Если даже
Signature
слишком много встроенного, в 73 байта мы можем взятьзаменить его на
1##&@@Order@@@#~Subsets~{2}&
. Это вычисляетSignature
возможную перестановку, беря произведениеOrder
примененного ко всем парам элементов перестановки.Order
даст,1
если пара находится в порядке возрастания,-1
если она находится в порядке убывания, и0
если они равны.-1 байт благодаря @ user202729
источник
Python 3 ,
238 байтов,227 байтов,224 байта, 216 байтовПопробуйте онлайн!
Мое решение использует определение определителя для расчетов. К сожалению, сложность этого алгоритма
n!
и я не могу показать прохождение последнего теста, но в теории это возможно.источник
CJam (
5045 байт)Это анонимный блок (функция), который берет двумерный массив в стек и оставляет целое число в стеке.
Набор онлайн-тестов
рассечение
Это реализует алгоритм Фаддеева-ЛеВерье , и я думаю, что это первый ответ, который выберет такой подход.
Код никогда не работает напрямую ссн - к а также MК , но всегда с ( - 1 )Ксн - к а также ( - 1 )к + 1А МК , поэтому повторение
( - 1 )Ксн - к= 1Кt r ((-1 )к + 1А МК)( - 1 )к + 2А Мк + 1= ( - 1 )Ксн - кA - A ( ( - 1 )к + 1А МК)
источник
Wolfram Language (Mathematica) , 3 байта
Попробуйте онлайн!
В соответствии с мета-консенсусом , в основном, нетривиальные решения, которые требуют усилий для написания.
источник
Python 2 , 75 байт
Попробуйте онлайн!
источник
SageMath , различные
Вот несколько методов вычисления определителя, которые мне показались интересными, все они запрограммированы в SageMath. Их все можно попробовать здесь .
Построение, 3 байта
Этот не слишком интересный. Sage предоставляет псевдонимы глобального уровня для многих общих операций, которые обычно являются объектными методами, поэтому это меньше, чем
lambda m:m.det()
.Действительная часть произведения собственных значений, 36 байт
К сожалению,
eigenvalues
это не один из тех псевдонимов глобального уровня. Это, в сочетании с тем, что у Sage нет аккуратного способа составления функций, означает, что мы застряли на дорогостоящемlambda
. Эта функция символьные значения, которые автоматически преобразуются в числовые значения при печати, поэтому некоторые погрешности с плавающей запятой могут присутствовать в некоторых выходных данных.Произведение диагонали в иорданской нормальной форме, 60 байт
В иорданской нормальной форме матрица NxN представляется в виде блочной матрицы с N блоками по диагонали. Каждый блок состоит либо из одного собственного значения, либо из матрицы MxM с повторяющимся собственным значением по диагонали и
1
s по супердиагональной (диагональ сверху и справа от «главной» диагонали). В результате получается матрица со всеми собственными значениями (с кратностью) на главной диагонали и некоторыми1
s на супердиагональности, соответствующей повторным собственным значениям. Это возвращает произведение диагонали нормальной жордановой формы, которая является произведением собственных значений (с кратностью), так что это более окольный способ выполнения тех же вычислений, что и в предыдущем решении.Поскольку Сейдж хочет, чтобы нормальная форма Джордана находилась над тем же кольцом, что и исходная матрица, это работает, только если все собственные значения рациональны. Сложные собственные значения приводят к ошибке (если исходная матрица не находится над кольцом
CDF
(сложные двойные числа с плавающей запятой) илиSR
). Однако это означает, что брать реальную часть не нужно, по сравнению с вышеупомянутым решением.Произведение диагонали в разложении Смита
В отличие от нормальной формы Джордана, нормальная форма Смита гарантированно находится над тем же полем, что и исходная матрица. Вместо вычисления собственных значений и представления их с помощью диагональной матрицы блоков, декомпозиция Смита вычисляет элементарные делители матрицы (что является слишком сложной темой для этого поста), помещает их в диагональную матрицу
D
и вычисляет две матрицы с единицей. определительU
иV
такой, чтоD = U*A*V
(гдеA
находится исходная матрица). Так как определитель произведения матриц равен произведению определителей матриц (det(A*B*...) = det(A)*det(B)*...
), а такжеU
иV
определены имеющими единичные детерминанты,det(D) = det(A)
. Определитель диагональной матрицы - это просто произведение элементов на диагонали.Расширение Лапласа, 109 байт
Это выполняет расширение Лапласа вдоль первого ряда, используя рекурсивный подход.
det([[a]]) = a
используется для базового случая. Это должно быть короче, чтобы использоватьdet([[]]) = 1
для базового случая, но моя попытка в этой реализации имела ошибку, которую я еще не смог отследить.Формула Лейбница, 100 байтов
Это непосредственно реализует формулу Лейбница. Чтобы получить лучшее объяснение формулы и почему она работает, чем я мог бы написать, посмотрите этот превосходный ответ .
Реальная часть
e^(Tr(ln(M)))
, 48 байтовЭта функция возвращает символические выражения. Чтобы получить числовое приближение, позвоните
n(result)
перед печатью.Это подход, который я еще никому не видел. Я собираюсь дать более подробное объяснение этому.
Позвольте
A
быть квадратной матрицы над реалами. По определению определительA
равен произведению собственных значенийA
. СледA
равен суммеA
собственных значений. Для действительных чиселr_1
иr_2
,exp(r_1) * exp(r_2) = exp(r_1 + r_2)
. Поскольку матричная экспоненциальная функция определена как аналог скалярной экспоненциальной функции (особенно в предыдущем тождестве), а матричная экспонента может быть вычислена путем диагонализации матрицы и применения скалярной экспоненциальной функции к собственным значениям на диагонали, мы можем сказать,det(exp(A)) = exp(trace(A))
(продуктexp(λ)
для каждого собственного значенияλ
изA
равна сумме собственных значений .exp(A)
). Таким образом, если мы можем найти матрицу , мы можем вычислитьL
, чтоexp(L) = A
det(A) = exp(trace(L))
Мы можем найти такую матрицу с
L
помощью вычисленийlog(A)
. Матричный логарифм может быть вычислен так же, как матрица экспоненциальная: сформируйте квадратную диагональную матрицу, применив скалярную функцию логарифма к каждому собственному значениюA
(именно поэтому мы ограничены действительными значениямиA
). Поскольку мы заботимся только о следеL
, мы можем пропустить построение и просто напрямую суммировать экспоненты собственных значений. Собственные значения могут быть комплексными, даже если матрица не находится над комплексным кольцом, поэтому мы берем действительную часть суммы.источник
real(prod(m.eigenvalues()))
присмотра.Java 8,
266261259258 байтПослушай, мама, без встроенных модулей .. потому что у Java их нет ..>.>
-7 байт благодаря @ceilingcat .
Объяснение:
Попробуй это здесь. (Только последний контрольный пример слишком велик для
long
размера 2 63 -1.)источник
JavaScript (ES6), 91
Рекурсивный Лаплас
Меньше гольфа
Тест
источник
Python 2 + NumPy , 29 байт
Попробуйте онлайн!
источник
Юлия , 3 байта
Попробуйте онлайн!
источник
Пари / ГП , 6 байт
Попробуйте онлайн!
источник
Java (OpenJDK 8) ,
195 192177 байтПопробуйте онлайн!
Как и многие другие ответы, здесь также используется формула Лапласа. Чуть менее гольф-версия:
источник
J , 5 байт
Попробуйте онлайн!
источник