В математике умножение матриц или произведение матриц - это двоичная операция, которая производит матрицу из двух матриц. Определение мотивировано линейными уравнениями и линейными преобразованиями на векторах, которые имеют многочисленные приложения в прикладной математике, физике и технике. Более подробно, если A является матрицей n × m, а B является матрицей m × p, их матричное произведение AB является матрицей n × p, в которой m записей в строке A умножаются на m записей на a столбцы B и суммировать, чтобы произвести запись AB. Когда два линейных преобразования представлены матрицами, тогда произведение матрицы представляет собой композицию двух преобразований.
Источник: Википедия
Другими словами, умножить две матрицы, например:
1 2 3 1 4
2 3 4 × 3 1 =
3 4 5 4 6
Сначала возьмем строку 1 в первой матрице, столбец 1 во второй матрице и умножим 1
на 1
, 2
на 3
и 3
на 4
.
1 × 1 = 1
2 × 3 = 6
3 × 4 = 12
Теперь сложите их вместе, чтобы получить первый элемент:
1 2 3 1 4 19
2 3 4 × 3 1 =
3 4 5 4 6
Для второго числа в первом столбце результата вам нужно взять строку № 2 вместо строки № 1 и сделать то же самое.
1 × 2 = 2
3 × 3 = 9
4 × 4 = 16
= 27
После того, как вы выполните весь первый столбец, результат будет выглядеть так:
1 2 3 1 4 19
2 3 4 × 3 1 = 27
3 4 5 4 6 35
Теперь сделайте то же самое снова, но возьмите второй столбец вместо первого столбца, в результате чего:
1 2 3 1 4 19 24
2 3 4 × 3 1 = 27 35
3 4 5 4 6 35 46
Твое задание
Учитывая две матрицы (максимальные размеры 200x200), содержащие числа в диапазоне от -10000 до 10000, где число столбцов в первом равно количеству строк во втором, умножьте первый на второй. (Умножение матриц некоммутативно.)
Вы можете принимать и выводить данные в виде массива массивов (или эквивалентных), матрицы (если ваш язык имеет этот формат) или многострочной строки.
Вы не можете использовать любые встроенные модули для умножения матриц.
Контрольные примеры
1 2 1 2 3 4 5 13 16 19 22 25
3 4 × 6 7 8 9 10 = 27 34 41 48 55
5 6 41 52 63 74 85
2 3 3 5 15 13
3 4 × 3 1 = 21 19
5 3 11 27
1 3 1 3 7 15
9 3 × 2 4 = 15 39
1 -1000 -1999 -3997
Помните, это код-гольф , поэтому выигрывает код с наименьшим количеством байтов.
Ответы:
Желе ,
75 байтПринимает B и A в качестве аргументов и возвращает A × B .
Попробуйте онлайн!
Как это устроено
источник
æ×
, который составляет 2 байта.æ.
атом.05AB1E , 13 байтов
Попробуйте онлайн!
объяснение
источник
εUøεX*O
Python 2,
6966 байтЭто просто соответствует стандартной формуле, но лямбда-d для краткости :) Код без кода чрезвычайно прост!
Спасибо Алекси Торхамо за сохранение 3 байта! :)
Код Ungolfed:
источник
sum(map(int.__mul__,r,c))
чтобы сохранить 3 байта. (Не будет работать с плавающей запятой, но это тоже не требовалось)J
139 байтСохранено 4 байта благодаря милям!
Это закрытая вилка:
Что эквивалентно:
Который выполняет желаемое умножение; затем они суммируются.
При встроенном точечном произведении 5 байтов:
+/ .*
Контрольные примеры
источник
[:+/*"#:~
9 байтовHaskell ,
57 5654 байтаПопробуйте онлайн!
Использование:
foldr(zipWith(:))e
сe=[]:e
является более короткой формойtranspose
.источник
Haskell , 45 байт
Попробуйте онлайн!
Принимает аргументы в обратном порядке.
источник
R, 66 байт
Безымянная функция принимает две R-матрицы в качестве входных данных и возвращает продукт. Он использует,
apply
который используется для применения функций через поля массивов. Вfor
этом случае он работает как двойной цикл: для каждого столбцаB
и для каждой строкиA
возвращаем сумму (векторизованных) произведений.Сравните с чистым циклическим подходом (в
101
байтах):источник
outer(A,B,`*`)
а не встроенныеapply
вызовы?Mathematica, 20 байтов
Анонимная функция. Принимает два списка чисел ранга 2 в качестве входных данных и возвращает список чисел ранга 2 в качестве выходных данных. Для любопытных
Inner
- это функция, которая выполняет матричное умножение двух функций на два тензора.источник
Inner[1##&,##]&
что эквивалентноInner[1##&,##,Plus]&
...? И так1##&~Inner~##&
было бы еще лучше.C #,
168167 байтСпасибо @Mukul Kumar за сохранение 1 байта, на этот раз цикл while был на самом деле короче: P
Полная программа с тестовыми примерами:
источник
for(;i<n;)
->while(i<n)
оба 10 байтов.for (;i <n;i++)
->while (i++<n)
сохраняет 1 байтMATL ,
1211 байтМатрицы вводятся с использованием в
;
качестве разделителя строк.Попробуйте онлайн!
Умножение матриц без встроенного было частью моего ответа на Showcase языков . Однако, пытаясь повторно использовать исходный код для этого ответа, я понял, что в нем есть ошибка (вывод вектора строки был неправильно преобразован в вектор столбца). Это теперь исправлено, и здесь, и там. Для объяснения того, как работает код, см. Упомянутый пост (фрагмент длины 11).
источник
C ++ 14,
173168156146 байтC.back()
рассчитывать наi
C.clear()
и необходимостиC
быть пустым при запускеКак неназванная лямбда:
Требуется ввод и вывод, так как
vector<vector<int>>
вывод должен быть пустым заранее.Ungolfed:
Образец:
источник
push_back()
вместоemplace_back()
?Шелуха ,
76 байтОбратите внимание на порядок аргументов, попробуйте онлайн!
-1 байт благодаря @Zgarb!
объяснение
В основном просто делать то, что говорит определение умножения матриц:
источник
oΣz
может бытьδṁ
JavaScript (ES6), 66 байт
источник
C #, 131 байт
Я украл решение Йодля с предположением, что я мог бы написать это более эффективно, используя LINQ (в отличие от циклов for). Сделал несколько попыток, но несколько сломал его.
Здесь это несколько разбито:
Единственный реальный трюк здесь - это транспонирование матрицы
B.First().Select((f, i) => B.Select(r => r.ElementAt(i)))
. Как только мы транспонируем вторую матрицу, у нас есть два массиваA[i,x]
иB[j,x]
. Возьмите декартово произведение (i*j
) и Zip каждый из этихx
массивов длины вместе.Тестовый код:
источник
using System.Linq
; Я не уверен, что решения должны включать шаблон, какusing System
иstatic void Main()
Haskell , 49 байтов
Попробуйте онлайн!
Вход и выход представляют собой списки столбцов. Сопоставляет каждый столбец второй матрицы с этой строкой, заархивировал столбцы первой матрицы и масштабировал каждый, суммируя как вектор.
Я чувствую, что должен быть хороший способ сделать это бессмысленным и сэкономить несколько байтов, но я этого пока не вижу.
источник
Javascript, 128 байт
Вы получаете результат, просто проверяя $ - это обманывает, но эй, это сэкономило несколько байтов.
источник
PHP, 110 байт
Три петли для эльфийских массивов. Это так просто ... но не так много в гольфе.
источник
На самом деле , 14 байтов
Предложения по игре в гольф приветствуются! Попробуйте онлайн!
Ungolfing
источник
C 618 байт
Именованная функция и, безусловно, самое длинное представление здесь, отчасти из-за того, что преобразование входных данных массива символов в C 2-мерные целочисленные массивы занимает больше байтов, а также потому, что я не играл в гольф в C в течение самого длительного времени. Я все еще работаю над тем, чтобы сократить это, насколько я могу, и любые советы в этом очень ценятся.
Теперь, с этим, путь извлекается через командную строку с двумя матрицами, представленными двумя строками, каждая из которых содержит строки, разделенные запятыми, а каждая строка представлена целыми числами, разделенными пробелом. Например, матрицы:
будет введен как:
./a.out "1 2 3,4 5 6,7 8 9" "44 52,67 -79,83 90"
Полученная матрица выводится в STDOUT в виде многострочной строки. Например, выход для вышеуказанного ввода будет:
источник
Clojure, 60 байт
Много байтов потрачено на транспонирование второго аргумента.
источник
Рубин , 59 байт
Попробуйте онлайн!
источник