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.

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)




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



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.

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!


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

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

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



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]

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!


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

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.


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.



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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.