Calcular el vector matriz

14

Dada una matriz entera de al menos dos elementos, genera el vector matriz (definido a continuación) de la matriz.

Para calcular el vector matriz , primero gire a través de la nmatriz de entrada de tamaño para crear una matriz de tamaño n x n, con el primer elemento de la matriz siguiendo la diagonal principal. Esto forma la porción de la matriz. Para el vector, voltee la matriz de entrada verticalmente. Luego realice la multiplicación normal de la matriz. El vector de salida es el resultado.

Por ejemplo,

a = [1, 2, 3]

Primero, gire la matriz dos veces hacia la derecha, para obtener [3, 1, 2]y [2, 3, 1]luego apílelos para formar una 3x3matriz

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

Luego, voltea la matriz verticalmente para formar el vector

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

Realizar la multiplicación matricial habitual

[[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]]

Y la salida es [14, 11, 11]o [[14], [11], [11]](su elección de si está aplanada o no).

Ejemplo # 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]

Reglas

  • Se puede suponer que la entrada y la salida se ajustan al tipo de entero nativo de su idioma.
  • La entrada y la salida se pueden dar en cualquier formato conveniente .
  • Un programa completo o una función son aceptables. Si es una función, puede devolver el resultado en lugar de imprimirlo.
  • Si es posible, incluya un enlace a un entorno de prueba en línea para que otras personas puedan probar su código.
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).
AdmBorkBork
fuente

Respuestas:

8

Jalea , 5 bytes

ṙJṚæ.

Pruébalo en línea!

Explicación

En primer lugar:

donde están los vectores de fila y es un vector de columna .vkx

Esto demuestra que la multiplicación de matrices es solo un producto de puntos entre filas y columnas.

Luego, en realidad se gira hacia la derecha, y se gira hacia la derecha, etc.v1v0vkvk-1

Desde otro ángulo, se gira hacia la izquierda, y se gira hacia la izquierda, etc.v1vnvnv1

Cómo funciona

ṙ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)
Monja permeable
fuente
3

Jalea , 9 bytes

LḶN⁸ṙæ×W€

Pruébalo en línea!

Una función que devuelve una matriz vertical. Como programa completo, parece que devuelve una matriz horizontal. Para devolver una matriz horizontal que haría en su LḶN⁸ṙ×⁸S€lugar.

Erik el Outgolfer
fuente
2

Haskell , 49 bytes

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

Pruébalo en línea!

Para una entrada v=[1,2]

  • iterate tail$v++v produce la lista [[1,2,1,2],[2,1,2],[1,2],[2],[],...]
  • fst<$>zip l ves igual take(length v)ly produce[[1,2,1,2],[2,1,2]]
  • sum.zipWith(*)v se mapea en cada elemento y produce el producto de fila de matriz de vectores.
Laikoni
fuente
¡Mucho más inteligente que mi respuesta! Me gusta fst<$>zip l vmucho
jferard
2

R , 66 62 bytes

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

Pruébalo en línea!

Monja permeable
fuente
usar Map(function(i)c(n[-(1:i)],n[1:i])%*%n,length(n<-scan()):1)es 3 bytes más corto; solo devuelve una lista de matrices.
Giuseppe
y un bucle for for(i in seq(n<-scan()))F=c(c(n[-(1:i)],n[1:i])%*%n,F);F[1:i]tiene 61 bytes sin devolver un formato de salida extraño.
Giuseppe
1

J , 14 bytes

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

Pruébalo en línea!

Explicación

+/ .*~#\.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
millas
fuente
Esto es muy lindo Una pregunta. Cuando usted 1&|.no estás unión 1a |., la creación de una mónada? pero luego usas esa mónada con un argumento izquierdo y derecho, y el izquierdo determina cuántas veces se aplica. ¿Que está pasando aqui?
Jonás
@ Jonás Es una forma especial para &. Cuando se usa como u n&f v, está funcionando (n&f)^:u v. Vea la parte inferior del enlace para ver más análisis del mismo.
millas
ah, TIL. ¿Es algo que usas a menudo?
Jonás
@ Jonás Es útil para jugar al golf en muchos casos. En este caso, podría haberse hecho en un número igual de bytes usando el rango #\.|."{], pero publiqué el más corto que se me ocurrió antes de probar alternativas.
millas
1

APL, 17 bytes

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

Explicación:

(↑¯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
marinus
fuente
1

Haskell , 56 55 52 bytes

f l=[sum$zipWith(*)l$drop i$l++l|i<-[0..length l-1]]

Pruébalo en línea!

Guardado un byte gracias a @Laikoni

Guardado tres bytes: en l++llugar decycle l

jferard
fuente
Puede guardar un byte con zipWith(*)l$drop i$cycle l.
Laikoni
1

Casco , 11 bytes

mΣ§‡*´ṀKoṫ¢

Pruébalo en línea!

Explicación

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]
Zgarb
fuente
1

Octava - 67 48 bytes

¡Gracias a Luis Mendo por reducir este código en 19 bytes!

Nota: Este código solo puede ejecutarse en Octave. MATLAB no admite expresiones dentro de funciones que pueden crear variables al mismo tiempo que evalúa las expresiones que las crean.

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

El código original en MATLAB se puede encontrar aquí, pero se puede ejecutar en cualquier versión de MATLAB. Este código tiene 67 bytes:

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

Explicación

  1. a=input('');- Recibe un vector (fila) del usuario a través de la entrada estándar. Debe ingresar el vector en forma de octava (es decir[1,2,3] ).
  2. n=numel(...); - Obtiene el número total de elementos en el vector de entrada.
  3. x=0:n-1- Crea un vector de fila que aumenta de 0hastan-1 en pasos de 1.
  4. (x=0:n-1)-x'- Realiza la transmisión de modo que tengamos una n x nmatriz para que cada fila isean elementos desde 0 hasta n-1con cada elemento en fila isustraído pori .
  5. mod(..., n)+1- Asegura que cualquier valor que sea negativo se ajuste a, de nmodo que cada fila icontenga el vector desde 0 hasta desplazado n-1 circularmente a la izquierda pori elementos. Agregamos 1 cuando MATLAB / Octave comienza a indexar vectores o matrices con 1.
  6. a(...)- Crea una n x nmatriz donde usando (4), accedemos a los índices correctos del vector de entrada dictados por cada valor de (4), logrando así la matriz que necesitamos.
  7. (...)*a'- Realiza la multiplicación de vectores de matriz mediante transposición / volteo apara convertirse en un vector de columna antes de hacer la multiplicación.

Ejecuciones de ejemplo

>> 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

Pruébalo en línea!

rayryeng - Restablece a Monica
fuente
Puede usar la expansión implícita en lugar de bsxfun. Definir nsin -1guardar algunos bytes también. Y si restringe a Octave, puede asignar ay 0:nvariables sobre la marcha y guardar algo más . Además, ven aquí más a menudo! :-D
Luis Mendo
@LuisMendo ah sí. Olvidé que Octave ya tiene una expansión implícita compatible. También guardar la variable dentro de la inputfunción es un gran truco. No pensé que pudiera soportar eso. Lo he visto solo en C o C ++ desde mi propia experiencia. ¡Gracias!
rayryeng - Restablecer Mónica
1
@LuisMendo Colocaré sus cambios sugeridos como una edición pronto. He estado ocupado, pero no he hecho de esto una prioridad, ya que esta entrada seguramente nunca ganará en el recuento de bytes.
rayryeng - Restablece a Monica el
@LuisMendo cambiado. Muchas gracias :) Entendí el código ya que estaba cambiando mi explicación anterior.
rayryeng - Restablecer Monica
Me alegro de poder ayudar :-)
Luis Mendo
0

Javascript 79 bytes

Toma una matriz de entrada y genera una matriz del vector matriz

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

Explicación

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
        )
    ))
)
asgallant
fuente
0

Clojure, 80 bytes

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

iterateproduce una secuencia infinita, pero en lugar de usarlo (take (count %) (iterate ...))para detenerlo, lo uso %como argumento adicional para map.

NikoNyrh
fuente
0

Perl 5 , 65 + 1 (-a) = 66 bytes

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

Pruébalo en línea!

Toma el vector de entrada como números separados por espacios. Emite números separados por salto de línea que representan el vector resultante.

Xcali
fuente
0

Lisp común, 78 bytes

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

Pruébalo en línea!

Duplique la matriz (en este caso, una lista Lisp) e itere sobre las sublistas con i(usando x, a través y, para detener la iteración). Luego calcule el siguiente elemento del resultado sumando el resultado de multiplicar cada elemento de xcon cada elemento de i(deteniéndose nuevamente cuando finaliza la lista más corta).

Renzo
fuente