Обчисліть вектор матриці


14

Давши цілий масив щонайменше з двох елементів, виведіть вектор матриці (визначений нижче) масиву.

Щоб обчислити вектор матриці , спершу обертайтеся через nмасив введення розміру n x n, щоб створити матрицю розміру , причому перший елемент масиву слід за основною діагоналлю. Це утворює матричну частину. Для вектора переверніть вхідний масив вертикально. Потім виконайте нормальне множення матриці. Вихідний вектор - результат.

Наприклад,

a = [1, 2, 3]

Спочатку оберніть масив два рази вправо, щоб отримати, [3, 1, 2]а [2, 3, 1]потім складіть їх, щоб утворити 3x3матрицю

[[1, 2, 3]
 [3, 1, 2]
 [2, 3, 1]]

Далі переверніть масив вертикально, щоб сформувати вектор

[[1, 2, 3]    [[1]
 [3, 1, 2]  x  [2]
 [2, 3, 1]]    [3]]

Виконайте звичайне матричне множення

[[1, 2, 3]    [[1]    [[1+4+9]    [[14]
 [3, 1, 2]  x  [2]  =  [3+2+6]  =  [11]
 [2, 3, 1]]    [3]]    [2+6+3]]    [11]]

І вихід є [14, 11, 11]або [[14], [11], [11]](ваш вибір, згладжений він чи ні).

Приклад №2

a = [2, 5, 8, 3]

[[2, 5, 8, 3]    [[2]    [[4+25+64+9]     [[102]
 [3, 2, 5, 8]  x  [5]  =  [6+10+40+24]  =  [80]
 [8, 3, 2, 5]     [8]     [16+15+16+15]    [62]
 [5, 8, 3, 2]]    [3]]    [10+40+24+6]]    [80]]

[102, 80, 62, 80]

Правила

  • Можна вважати, що вхід і вихід відповідають цілому цілому типу вашої мови.
  • Введення та вихід можуть бути задані у будь-якому зручному форматі .
  • Прийнятна або повна програма, або функція. Якщо функція, ви можете повернути вихід, а не надрукувати його.
  • Якщо можливо, додайте посилання на онлайн-тестувальне середовище, щоб інші люди могли спробувати ваш код!
  • Стандартні лазівки заборонені.
  • Це тому застосовуються всі звичайні правила гольфу, і найкоротший код (у байтах) виграє.

Відповіді:


8

Желе , 5 байт

ṙJṚæ.

Спробуйте в Інтернеті!

Пояснення

По-перше:

де є рядки векторів і є стовпець вектор.vkx

Це демонструє, що множення матриць - це лише крапковий добуток між рядками та стовпцями.

Потім, насправді повертається вправо, і буде повернений вправо, і т.д.v1v0vkvk-1

З іншого боку, це повертається вліво, і це повертається вліво, і т.д.v1vnvnv1

Як це працює

ṙJṚæ.   input: z (a list of length n)
ṙJ      [rot(z,1), rot(z,2), ..., rot(z,n)] (to the left)
  Ṛ     [rot(z,n), ..., rot(z,2), rot(z,1)]
   æ.   [rot(z,n).z , ..., rot(z,2).z , rot(z,1).z] (dot product)




3

Желе , 9 байт

LḶN⁸ṙæ×W€

Спробуйте в Інтернеті!

Функція, яка повертає вертикальний масив. Як повноцінна програма виглядає так, ніби вона повертає горизонтальний масив. Щоб повернути горизонтальний масив, який слід зробити LḶN⁸ṙ×⁸S€замість цього.



2

Хаскелл , 49 байт

f v=sum.zipWith(*)v.fst<$>zip(iterate tail$v++v)v

Спробуйте в Інтернеті!

Для введення v=[1,2]

  • iterate tail$v++v дає список [[1,2,1,2],[2,1,2],[1,2],[2],[],...]
  • fst<$>zip l vте саме, що take(length v)lі врожайність[[1,2,1,2],[2,1,2]]
  • sum.zipWith(*)v відображається на кожному елементі і отримує добуток векторного матричного рядка.

Набагато розумніший за мою відповідь! Мені fst<$>zip l vдуже подобається .
jferard

2

R , 66 62 байт

sapply(length(n<-scan()):1,function(i)c(n[-(1:i)],n[1:i])%*%n)

Спробуйте в Інтернеті!


використання Map(function(i)c(n[-(1:i)],n[1:i])%*%n,length(n<-scan()):1)на 3 байти коротше; він просто повертає список матриць.
Джузеппе

а цикл for for(i in seq(n<-scan()))F=c(c(n[-(1:i)],n[1:i])%*%n,F);F[1:i]- 61 байт без повернення дивного формату виводу.
Джузеппе

2

Математика, 35 байт

Most@FoldList[RotateRight,#,1^#].#&

Спробуйте в Інтернеті!

-9 байт від @Не дерево


2
Це коротше використовувати власні множення матриць системи Mathematica , ніж відтворити його самостійно: Most@FoldList[RotateRight,#,1^#].#&. (Але приємний трюк, використовуючи Foldзамість Nest!)
Не дерево




1

J , 14 байт

+/ .*~#\.1&|.]

Спробуйте в Інтернеті!

Пояснення

+/ .*~#\.1&|.]  Input: array M
      #\.       Length of each suffix, forms the range [len(M), ..., 2, 1]
             ]  Identity, get M
         1&|.   For each 'x' in the suffix lengths, rotate left M  by 'x'
+/ .*~          Dot product with M

Це досить приємно. Одне питання. Коли ви 1&|.чи не ви приклеювання 1до |., створюючи монади? але тоді ви використовуєте монаду як з лівого, так і з правого аргументу, а лівий визначає, скільки разів він застосовується. Що тут відбувається?
Йона

@Jonah Це спеціальна форма для &. Коли він використовується як u n&f v, він працює (n&f)^:u v. Дивіться нижню частину облігації, щоб побачити більше її аналізів.
миль

ах, TIL. це те, що ти часто використовуєш?
Джона

@Jonah Це корисно для гольфу в багатьох випадках. У цьому випадку це могло бути виконано в рівній кількості байтів, використовуючи ранг #\.|."{], але я розмістив найкоротший, який я придумав, перш ніж спробувати альтернативи.
миль

1

APL, 17 байт

(↑¯1⌽(⍳≢)⌽¨⊂)+.×⍪

Пояснення:

(↑¯1⌽(⍳≢)⌽¨⊂)+.×⍪

 ↑                      matrix format of
  ¯1⌽                   right rotate by 1 of
     (⍳≢)               the 1..[length N]
         ⌽¨             rotations of
           ⊂            the enclosed input
             +.×        inner product with
                ⍪       1-column matrix of input



1

Лушпиння , 11 байт

mΣ§‡*´ṀKoṫ¢

Спробуйте в Інтернеті!

Пояснення

mΣ§‡*´ṀKoṫ¢  Implicit input, e.g. [1,2,3]
          ¢  Cycle: [1,2,3,1,2,3,...
        oṫ   Tails: [[1,2,3,1,2,3...],[2,3,1,2,3...],[3,1,2,3...]...
     ´ṀK     Replace each element of input with input: [[1,2,3],[1,2,3],[1,2,3]]
   ‡*        Vectorized multiplication (truncated with respect to shortest list)
  §          applied to the last two results: [[1,4,9],[2,6,3],[3,2,6]]
mΣ           Sum of each row: [14,11,11]

1

Октава - 67 48 байт

Дякуємо Луїсу Мендо за те, що поголив цей код на 19 байт!

Примітка. Цей код може працювати лише в Octave. MATLAB не підтримує вирази всередині функцій, які можуть створювати змінні, одночасно оцінюючи вирази, які їх створюють.

n=numel(a=input(''));a(mod((x=0:n-1)-x',n)+1)*a'

Оригінальний код у MATLAB можна знайти тут, але його можна запустити в будь-якій версії MATLAB. Цей код становить 67 байт:

a=input('');n=numel(a)-1;a(mod(bsxfun(@minus,0:n,(0:n)'),n+1)+1)*a'

Пояснення

  1. a=input('');- Отримує (рядовий) вектор від користувача через стандартний вхід. Ви повинні ввести вектор у формі Октави (тобто [1,2,3]).
  2. n=numel(...); - Отримує загальну кількість елементів у вхідному векторі.
  3. x=0:n-1- Створює вектор рядка, який збільшується від 0до n-1кроків 1.
  4. (x=0:n-1)-x'- Виконує трансляцію, щоб у нас була n x nматриця, щоб кожен рядок був iелементом від 0 до n-1кожного елемента в рядку, iвіднімаєтьсяi .
  5. mod(..., n)+1- Переконайтесь, що будь-які значення, негативні, обертаються nтак, щоб кожен рядок iмістив вектор від 0 до n-1 кругового зміщення вліво наi елементів . Додаємо 1, оскільки MATLAB / Octave починає індексувати вектори або матриці з 1.
  6. a(...)- Створює n x nматрицю, де за допомогою (4) ми отримуємо доступ до правильних показників вхідного вектора, продиктованих кожним значенням з (4), таким чином, досягаючи необхідної нам матриці.
  7. (...)*a'- Виконує множення матричного вектора, переміщуючи / гортаючи, aщоб стати вектором стовпця до виконання множення.

Приклад працює

>> n=numel(a=input(''));a(mod((x=0:n-1)-x',n)+1)*a'
[1,2,3]

ans =

         14.00
         11.00
         11.00

>> n=numel(a=input(''));a(mod((x=0:n-1)-x',n)+1)*a'
[2,5,8,3]

ans =

        102.00
         80.00
         62.00
         80.00

Спробуйте в Інтернеті!


Ви можете використовувати неявне розширення замість bsxfun. Визначення nбез -1збереження також декількох байт. А якщо ви обмежитеся на Octave, ви можете призначити aта 0:nзмінні на льоту та зберегти ще кілька . Також приходьте сюди частіше !! :-D
Луїс Мендо

@LuisMendo ах так. Я забуваю, що Octave вже підтримує неявну розширення. Також збереження змінної всередині inputфункції - чудова хитрість. Я не думав, що це може це підтримати. Я бачив це лише на C або C ++ з власного досвіду. Спасибі!
rayryeng

1
@LuisMendo Я незабаром розміщу ваші запропоновані зміни як редагування. Я був зайнятий, але я не зробив це пріоритетним завданням, оскільки цей запис, безумовно, ніколи не переможе в байті
rayryeng

@LuisMendo Змінено. Дуже дякую :) Зрозумів код, коли я міняв своє пояснення вище.
rayryeng

Радий, що можу допомогти :-)
Луїс Мендо

0

Javascript 79 байт

Приймає вхідний масив і виводить масив матричного вектора

a=>(b=[...a],a.map(x=>([...b].reduce((m,n,i)=>m+=n*a[i],0,b.push(b.shift())))))

Пояснення

a=>(
    b=[...a],                    // copy the input into b
    a.map(x=>(                   // transform a into a new array
        [...b].reduce(           // copy b into a new array and reduce
            (m,n,i)=>m+=n*a[i],  // memo += the element in the array * the ith
                                 // element in a
            0,                   // start memo at 0
            b.push(b.shift())    // shift the first element in b to the end
                                 // not used by reduce, but performing this op
                                 // here saves a few bytes
        )
    ))
)

0

Clojure, 80 байт

#(map(fn[_ c](apply +(map * c %)))%(iterate(fn[c](into[(last c)](butlast c)))%))

iterateстворює нескінченну послідовність, але замість того, (take (count %) (iterate ...))щоб зупинити її, я використовую %як додатковий аргумент map.


0

Perl 5 , 65 + 1 (-a) = 66 байт

@o=@F;for(@o){$r=0;$r+=$_*$F[$i++%@F]for@o;say$r;unshift@F,pop@F}

Спробуйте в Інтернеті!

Приймає вектор введення як пробіли, розділені числами. Виводить рядкові числа, розділені числами, що представляють результат результату.



0

Лист звичайний, 78 байт

(lambda(x)(loop as i on(append x x)as y in x collect(reduce'+(mapcar'* i x))))

Спробуйте в Інтернеті!

Подвійний масив (в даному випадку список Lisp) та повторіть його над списками i(використовуючи xчерез y, щоб зупинити ітерацію). Потім обчисліть наступний елемент результату, підсумовуючи результат множення кожного елемента xз кожним елементом i(знову зупиняється, коли коротший список припиняється).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.