Есть много разных способов объяснить матричное умножение. Я буду придерживаться одной фигуры, так как считаю, что большинство людей здесь знакомы с ней (и эта цифра очень наглядна). Если вам нужна более подробная информация, я предлагаю вам посетить статью в Википедии или пояснение к WolframMathWorld .
Простое объяснение:
Предположим, у вас есть две матрицы, A и B , где A - 3 на 2, а B - 2 на 3. Если вы выполните умножение матриц на эти матрицы, либо AB , либо BA, вы получите следующие результаты:
Вызов:
Реализуйте умножение символьных матриц на вашем языке. В качестве входных данных вы должны взять две матрицы, где каждый элемент в матрицах представлен непробельным символом ASCII (кодовые точки 33-126). Вы должны вывести произведение этих матриц.
Правила относительно вывода:
Произведение двух записей не должно иметь никаких символов между ними. Это ab
, не a*b
, a·b
, times(a,b)
или что - то подобное. Это aa
не так a^2
.
Сумма терминов должна иметь пробел (кодовая точка 32 ASCII) между ними. Это a b
, не a+b
, plus(a,b)
или что - то подобное.
Обоснование этих двух правил таково: все символы, не являющиеся пробелами, допускаются в качестве символов в матрицах, поэтому их использование в качестве математических символов будет беспорядочным. Итак, что вы могли бы нормально написать как a*b+c*d
будет ab cd
.
Вы можете выбрать порядок условий. ab cd
, dc ab
иcd ba
математически говоря то же самое, так что вы можете выбрать порядок здесь. Порядок не обязательно должен быть последовательным, если он математически правильный.
Правила относительно матричного форматирования:
Матрица может быть введена в любом формате, который вам нравится, кроме одной строки без разделителей между строками (это потому, что выходные данные будут полностью испорчены). Обе матрицы должны быть введены в одном формате. Все приведенные ниже примеры являются допустимыми способами ввода и вывода матрицы.
"ab;cd" <- This will look awful, but it's still accepted.
"a,b\nc,d"
[[a,b],[c,d]]
[a, b]
[c, d]
Я знаю, что это допускает множество форматов, которые будут выглядеть беспорядочно, но проблема заключается в умножении матриц, а не в форматировании вывода.
Основные правила:
- Вы можете принять верный ввод. Умножение матриц всегда будет возможно с заданными размерами.
- Там будет только две матрицы.
- Вы можете предположить, что матрицы не пустые
- Встроенные функции принимаются (но, вероятно, немного громоздко из-за требований к форматированию).
- Вы можете, конечно, использовать escape-символы на входе, если это необходимо (
\'
вместо'
). - Любой стандартный метод ввода и вывода в порядке .
Тестовые случаи:
Две входные матрицы показаны пустой строкой между ними. Вывод отображается после Output:
. Когда есть две выходные матрицы, это просто показать другие выходные данные, которые будут приняты.
Тестовый пример № 1
Inputs:
[a]
[b]
Output:
[ab]
[ba] <- Also OK
Тестовый пример № 2
Inputs:
[a, b]
[1, 4]
[y, {]
[%, 4, 1]
[a, b, c]
Output:
[a% ba, a4 bb, a1 bc]
[1% 4a, 14 4b, 11 4c]
[y% {a, y4 {b, y1 {c]
Тестовый пример № 3:
Inputs:
[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 1, 2, 3]
[4, 5, 6, 7]
[a]
[b]
[c]
[d]
Output:
[1a 2b 3c 4d]
[5a 6b 7c 8d]
[9a 1b 2c 3d]
[4a 5b 6c 7d]
[d4 c3 b2 a1] <-- Also OK
[d8 c7 b6 a5]
[1b 9a c2 3d]
[a4 b5 d7 6c]
Если ваш ответ на правила о требовании ab cd
вместо a*b+c*d
: вы должны избегать громоздких форматов ввода / вывода , то я хотел бы отметить, что форматы ввода и вывода очень гибкие. Тот факт, что вы не можете использовать *
и +
для продуктов и сумм, может усложнить использование простого встроенного, но я не считаю это отрицательным моментом.
источник
Ответы:
Haskell ,
6261 байтПопробуйте онлайн! Пример использования:
Я нашел способ получить
transpose
функцию на один байт короче, чем с помощью импорта:Старая версия с импортом: (62 байта)
Попробуйте онлайн!
Это очень похоже на мой ответ на несимвольное матричное умножение :
a!b=[sum.zipWith(*)r<$>transpose b|r<-a]
замена умножения(*)
на конкатенацию строк(++)
иsum
наunwords
которую конкатенируется список строк с пробелом между ними. Импорт необходим дляtranspose
функции, так что в целом транспонирование второй матрицы занимает половину байтов ...Старая версия без импорта: (64 байта)
Попробуйте онлайн!
Поскольку импорт и
transpose
функция занимают столько байтов, я попытался решить задачу без импорта. До сих пор этот подход оказался на два байта длиннее, но он мог бы быть более пригодным для игры в гольф. Изменить: другой подход в верхней части теперь превосходит импорт!Понимание списка
[s:t|_:s:t<-b]
получает непустые хвосты списковb
, используя только,[t|_:t<-b]
чтобы получить хвосты, которые были бы на 4 байта короче (даже превосходя версию импорта), но добавляли пустую строку, как["","",""]
в матрицу, которая, я полагаю, не разрешена.источник
Mathematica, 36 байт
Inner
является обобщением Mathematica'sDot
(т.е. обычное матричное / векторное произведение). Он обобщает скалярное произведение, позволяя вам предоставить две функцииf
иg
, которые будут использоваться вместо обычного умножения и сложения соответственно. Мы заменяем умножение на#<>#2&
(которое объединяет два символа в одну строку) и сложениеStringRiffle@*List
, которое сначала оборачивает все слагаемые в списке, а затемStringRiffle
соединяет их вместе с пробелами.Можно потенциально использовать
Dot
оператор,.
а затем преобразовать результат, но проблема в том, что подобные вещи"a"*"a"
немедленно преобразуются в"a"^2
(то же самое для сумм), что было бы неприятно снова разбирать.источник
Рубин, 61 байт
Образец прогона:
источник
Clojure, 53 байта
Запуск с аргументами
[["a" "b"]["c" "e"]]
и[["f" "g"]["h" "i"]]
возвратами((("af" "bh") ("ag" "bi")) (("cf" "eh") ("cg" "ei")))
. Это на самом деле короче, чем числовая версия .источник
Dyalog APL , 10 байт
Принимает матрицы символов в качестве левого и правого аргументов. Возвращает матрицу списков символов. (APL представляет строки в виде списков символов.)
Попробуй APL онлайн!
Нормальный внутренний продукт в APL
+.×
, но сложение и умножение могут быть любыми функциями, в частности:Добавление было заменено
{
анонимной функцией:∊
плоский⍺ ' ' ⍵
список, состоящий из левого аргумента, пробела и правого аргумента⍵
}
Умножение было заменено конкатенацией,
,
источник
Желе , 7 байт
Это диадическая ссылка, которая принимает B и A в качестве аргументов (в указанном порядке) и возвращает AB . Ввод и вывод выполняются в виде двумерных массивов строк, которые на самом деле являются трехмерными массивами символов. Еще один байт можно сохранить, взяв в качестве входных данных двумерные массивы символов . Я не уверен, разрешено ли это.
Попробуйте онлайн!
Трудно определить, что делает Jelly под капотом, когда задействованы струны, так как он делает много брызг перед печатью. Вот как Jelly представляет ввод и вывод внутри.
Как это работает
источник
Пролог,> 256 байт
Я использую {_ | _}, который является findall / 3, _ [_, _], который является некоторым arg / 3, и sum (_), который является некоторой совокупностью. Все они могут быть использованы внутри / 2:
Вместе с дополнительными определениями для вышеупомянутых предикатов и нестандартным является / 2, который может возвращать больше, чем числа, его уверенность> 256 байтов.
источник
JavaScript (ES6), 65 байт
Принимает ввод как два двумерных массива символов и возвращает двумерный массив строк. Добавьте 10 байтов для поддержки ввода в виде двух одномерных массивов строк.
источник
Pyth, 14 байт
Программа, которая принимает ввод двух разделенных новой строкой двухмерных списков символов и печатает двумерный список строк.
Тестирование
Как это работает
[Объяснение будет позже]
источник
Пип , 17 байт
Это функция, которая принимает два вложенных списка (односимвольных) строк и возвращает вложенный список строк. Попробуйте онлайн! (с двумя тестами).
объяснение
Аргументы в
{}
-delimited функции возложены на локальные переменныеa
вe
. Первый аргумент лямбда-функции представлен как_
.источник