Calcular o vetor de matriz

14

Dada uma matriz inteira de pelo menos dois elementos, produza o vetor matriz (definido abaixo) da matriz.

Para calcular o vetor de matriz , primeiro gire pela nmatriz de tamanho- entrada para criar uma matriz de tamanho n x n, com o primeiro elemento da matriz seguindo a diagonal principal. Isso forma a parte da matriz. Para o vetor, vire a matriz de entrada verticalmente. Em seguida, execute a multiplicação normal da matriz. O vetor de saída é o resultado.

Por exemplo,

a = [1, 2, 3]

Primeiro, gire a matriz duas vezes para a direita, para obter [3, 1, 2]e [2, 3, 1], em seguida, empilhe-as para formar uma 3x3matriz

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

Em seguida, vire a matriz verticalmente para formar o vetor

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

Realizar multiplicação matricial usual

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

E a saída é [14, 11, 11]ou [[14], [11], [11]](sua escolha é achatada ou não).

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

Regras

  • Pode-se presumir que a entrada e a saída se encaixam no tipo inteiro nativo do seu idioma.
  • A entrada e saída podem ser fornecidas em qualquer formato conveniente .
  • Um programa completo ou uma função são aceitáveis. Se uma função, você pode retornar a saída em vez de imprimi-la.
  • Se possível, inclua um link para um ambiente de teste on-line para que outras pessoas possam experimentar seu código!
  • As brechas padrão são proibidas.
  • Isso é portanto todas as regras usuais de golfe se aplicam e o código mais curto (em bytes) vence.
AdmBorkBork
fonte

Respostas:

8

Gelatina , 5 bytes

ṙJṚæ.

Experimente online!

Explicação

Primeiramente:

onde são vetores de linha e é um vetor de coluna .vkx

Isso demonstra que a multiplicação de matrizes é apenas um produto de ponto entre linhas e colunas.

Então, é realmente girado para a direita, e é girado para a direita, etc.v1v0vkvk-1

De outro ângulo, é girado para a esquerda, e é girado para a esquerda, etc.v1vnvnv1

Como 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)
Freira Furada
fonte
5

Python 2 , 68 bytes

lambda x:[sum(map(int.__mul__,x,x[i:]+x[:i]))for i in range(len(x))]

Experimente online!

Cajado
fonte
4

Python 2 , 73 bytes

def f(v):r=range(len(v));return[sum(v[i]*(v*2)[i+j]for i in r)for j in r]

Experimente online!

Arfie
fonte
(v*2)[i+j]bom truque #
Leaky Nun /
3

Geléia , 9 bytes

LḶN⁸ṙæ×W€

Experimente online!

Uma função que retorna uma matriz vertical. Como um programa completo, parece que retorna uma matriz horizontal. Para retornar uma matriz horizontal, você faria LḶN⁸ṙ×⁸S€.

Erik, o Outgolfer
fonte
2

Haskell , 49 bytes

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

Experimente online!

Para uma entrada v=[1,2]

  • iterate tail$v++v produz a lista [[1,2,1,2],[2,1,2],[1,2],[2],[],...]
  • fst<$>zip l vé o mesmo que take(length v)le produz[[1,2,1,2],[2,1,2]]
  • sum.zipWith(*)v é mapeado em cada elemento e para produzir o produto de linha da matriz vetorial.
Laikoni
fonte
Muito mais esperto que a minha resposta! Eu gosto fst<$>zip l vmuito
Jferard 28/07
2

R , 66 bytes de 62

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

Experimente online!

Freira Furada
fonte
usar Map(function(i)c(n[-(1:i)],n[1:i])%*%n,length(n<-scan()):1)é 3 bytes mais curto; apenas retorna uma lista de matrizes.
Giuseppe
e um loop for(i in seq(n<-scan()))F=c(c(n[-(1:i)],n[1:i])%*%n,F);F[1:i]for tem 61 bytes sem retornar um formato de saída estranho.
Giuseppe
1

Python 3 + numpy , 68 bytes

lambda v:dot([roll(v,i)for i in range(len(v))],v)
from numpy import*

Experimente online!

notjagan
fonte
1

J , 14 bytes

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

Experimente online!

Explicação

+/ .*~#\.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
milhas
fonte
Isso é bem legal. Uma questão. Quando você 1&|.não está ligando 1para |., criando uma mônada? mas você usa essa mônada com um argumento esquerdo e direito, com o esquerdo determinando quantas vezes ele é aplicado. O que está acontecendo aqui?
Jonah
@ Jonah É uma forma especial para &. Quando usado como u n&f v, está executando (n&f)^:u v. Veja a parte inferior do vínculo para ver mais análises.
miles
ah, até isso é algo que você usa com frequência?
Jonah
@ Jonah É útil para jogar golfe em muitos casos. Nesse caso, isso poderia ter sido feito em um número igual de bytes usando a classificação #\.|."{], mas eu publiquei o menor que eu criei antes de tentar alternativas.
miles
1

APL, 17 bytes

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

Explicação:

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

Haskell , 56 55 52 bytes

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

Experimente online!

Guardou um byte graças a @Laikoni

Salva três bytes: em l++lvez decycle l

jferard
fonte
Você pode salvar um byte com zipWith(*)l$drop i$cycle l.
Laikoni 28/07
1

Casca , 11 bytes

mΣ§‡*´ṀKoṫ¢

Experimente online!

Explicação

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

Oitava - 67 48 bytes

Obrigado a Luis Mendo por reduzir este código em 19 bytes!

Nota: Esse código pode ser executado apenas no Octave. O MATLAB não suporta expressões dentro de funções que podem criar variáveis ​​enquanto avalia simultaneamente as expressões que as criam.

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

O código original no MATLAB pode ser encontrado aqui, mas pode ser executado em qualquer versão do MATLAB. Este código tem 67 bytes:

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

Explicação

  1. a=input('');- Recebe um vetor (linha) do usuário através da entrada padrão. Você deve inserir o vetor no formato Oitava (ou seja,[1,2,3] ).
  2. n=numel(...); - Obtém o número total de elementos no vetor de entrada.
  3. x=0:n-1- Cria um vetor de linha que aumenta de 0até n-1nas etapas 1.
  4. (x=0:n-1)-x'- Executa a transmissão de forma que tenhamos uma n x nmatriz para que cada linha iseja elementos de 0 até que n-1cada elemento na linha seja isubtraído por i.
  5. mod(..., n)+1- Garante que todos os valores negativos sejam redundantes para nque cada linha icontenha o vetor de 0 até n-1 circular circular para a esquerda pelos ielementos. Adicionamos 1 quando o MATLAB / Octave inicia a indexação de vetores ou matrizes com 1.
  6. a(...)- Cria uma n x nmatriz onde, usando (4), acessamos os índices corretos do vetor de entrada ditado por cada valor de (4), atingindo a matriz de que precisamos.
  7. (...)*a'- Executa a multiplicação do vetor de matriz, transpondo / invertendo apara se tornar um vetor de coluna antes de fazer a multiplicação.

Execuções de exemplo

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

Experimente online!

rayryeng - Restabelecer Monica
fonte
Você pode usar expansão implícita em vez de bsxfun. Definir nsem -1salva também alguns bytes. E se você restringir ao Octave, poderá atribuir ae 0:nàs variáveis ​​rapidamente e economizar um pouco mais . Além disso, venha aqui mais vezes !! :-D
Luis Mendo
@LuisMendo ah yes. Eu esqueço que o Octave já possui expansão implícita. Também salvar a variável dentro da inputfunção é um ótimo truque. Não achei que pudesse suportar isso. Eu vi isso apenas em C ou C ++ a partir de minha própria experiência. Obrigado!
rayryeng - Restabelece Monica
1
@LuisMendo Em breve, colocarei as alterações sugeridas como edição. Eu tenho estado ocupado, mas não fiz disso uma prioridade, pois essa entrada certamente nunca vencerá na contagem de bytes.
rayryeng - Restabelece Monica
@LuisMendo Changed. Muito obrigado :) Preciso entender o código, pois estava alterando minha explicação acima.
rayryeng - Restabelece Monica
Ainda bem que pude ajudar :-)
Luis Mendo
0

Javascript 79 bytes

Recebe uma matriz de entrada e gera uma matriz do vetor de matriz

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

Explicação

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

Clojure, 80 bytes

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

iterateproduz uma sequência infinita, mas, em vez de usar (take (count %) (iterate ...))para pará-lo, uso %como argumento extra para map.

NikoNyrh
fonte
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}

Experimente online!

Toma o vetor de entrada como números separados por espaço. Gera números separados por avanço de linha que representam o vetor de resultado.

Xcali
fonte
0

Lisp comum, 78 bytes

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

Experimente online!

Duplique a matriz (neste caso, uma lista Lisp) e itere sobre as sublistas com i(usando x, through ypara interromper a iteração). Em seguida, calcule o próximo elemento do resultado, somando o resultado da multiplicação de cada elemento de xpor cada elemento de i(novamente parando quando a lista mais curta for encerrada).

Renzo
fonte