Calculer le vecteur matriciel

14

Étant donné un tableau entier d'au moins deux éléments, affichez le vecteur matrice (défini ci-dessous) du tableau.

Pour calculer le vecteur matriciel , faites d'abord pivoter le ntableau d'entrée de taille pour créer une matrice de taille n x n, le premier élément du tableau suivant la diagonale principale. Cela forme la partie matrice. Pour le vecteur, retournez le tableau d'entrée verticalement. Effectuez ensuite une multiplication matricielle normale. Le vecteur de sortie est le résultat.

Par exemple,

a = [1, 2, 3]

En premier lieu , faire tourner la matrice deux fois vers la droite, pour obtenir [3, 1, 2]et [2, 3, 1], ensuite les empiler pour former une 3x3matrice

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

Ensuite, retournez le tableau verticalement pour former le vecteur

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

Effectuer la multiplication matricielle habituelle

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

Et la sortie est [14, 11, 11]ou [[14], [11], [11]](votre choix d'aplatir ou non).

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

Règles

  • L'entrée et la sortie peuvent être supposées correspondre au type d'entier natif de votre langue.
  • L'entrée et la sortie peuvent être données dans n'importe quel format pratique .
  • Un programme complet ou une fonction sont acceptables. S'il s'agit d'une fonction, vous pouvez renvoyer la sortie plutôt que de l'imprimer.
  • Si possible, veuillez inclure un lien vers un environnement de test en ligne afin que d'autres personnes puissent essayer votre code!
  • Les failles standard sont interdites.
  • Il s'agit de donc toutes les règles de golf habituelles s'appliquent et le code le plus court (en octets) l'emporte.
AdmBorkBork
la source

Réponses:

8

Gelée , 5 octets

ṙJṚæ.

Essayez-le en ligne!

Explication

D'abord:

où sont des vecteurs de ligne et est un vecteur de colonne .vkx

Cela montre que la multiplication matricielle n'est qu'un produit scalaire entre les lignes et les colonnes.

Ensuite, est en fait tourné vers la droite, et est tourné vers la droite, etc.v1v0vkvk-1

Sous un autre angle, est tourné vers la gauche, et est tourné vers la gauche, etc.v1vnvnv1

Comment ça fonctionne

ṙ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)
Leaky Nun
la source
3

Gelée , 9 octets

LḶN⁸ṙæ×W€

Essayez-le en ligne!

Une fonction qui renvoie un tableau vertical. En tant que programme complet, il semble qu'il renvoie un tableau horizontal. Pour retourner un tableau horizontal, vous le feriez à la LḶN⁸ṙ×⁸S€place.

Erik le Outgolfer
la source
2

Haskell , 49 octets

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

Essayez-le en ligne!

Pour une entrée v=[1,2]

  • iterate tail$v++v donne la liste [[1,2,1,2],[2,1,2],[1,2],[2],[],...]
  • fst<$>zip l vest le même que take(length v)let donne[[1,2,1,2],[2,1,2]]
  • sum.zipWith(*)v est mappé sur chaque élément et pour produire le produit de ligne à matrice vectorielle.
Laikoni
la source
Beaucoup plus intelligent que ma réponse! J'aime fst<$>zip l vbeaucoup.
jferard
2

R , 66 62 octets

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

Essayez-le en ligne!

Leaky Nun
la source
l'utilisation Map(function(i)c(n[-(1:i)],n[1:i])%*%n,length(n<-scan()):1)est de 3 octets plus courte; il renvoie juste une liste de matrices.
Giuseppe
et une boucle for for(i in seq(n<-scan()))F=c(c(n[-(1:i)],n[1:i])%*%n,F);F[1:i]fait 61 octets sans retourner un format de sortie étrange.
Giuseppe
1

J , 14 octets

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

Essayez-le en ligne!

Explication

+/ .*~#\.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
miles
la source
C'est assez sympa. Une question. Lorsque vous n'êtes 1&|.pas lié 1à la |.création d'une monade? mais ensuite vous utilisez cette monade avec un argument à gauche et à droite, celui de gauche déterminant le nombre de fois où il est appliqué. Que se passe t-il ici?
Jonah
@Jonah C'est une forme spéciale pour &. Lorsqu'il est utilisé en tant que u n&f v, il est performant (n&f)^:u v. Voir le bas du lien pour en voir plus d'analyses.
miles
ah, TIL. est-ce quelque chose que vous utilisez souvent?
Jonah
@Jonah Il est utile pour le golf dans de nombreux cas. Dans ce cas, cela aurait pu être fait dans un nombre égal d'octets en utilisant rank #\.|."{], mais j'ai publié le plus court que j'ai trouvé avant d'essayer des alternatives.
miles
1

APL, 17 octets

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

Explication:

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

Haskell , 56 55 52 octets

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

Essayez-le en ligne!

Un octet enregistré grâce à @Laikoni

Trois octets enregistrés: l++lau lieu decycle l

jferard
la source
Vous pouvez enregistrer un octet avec zipWith(*)l$drop i$cycle l.
Laikoni
1

Husk , 11 octets

mΣ§‡*´ṀKoṫ¢

Essayez-le en ligne!

Explication

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
la source
1

Octave - 67 48 octets

Merci à Luis Mendo d'avoir réduit ce code de 19 octets!

Remarque: ce code ne peut être exécuté qu'en octave. MATLAB ne prend pas en charge les expressions à l'intérieur des fonctions qui peuvent créer des variables tout en évaluant simultanément les expressions qui les créent.

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

Le code d'origine dans MATLAB peut être trouvé ici, mais peut être exécuté dans n'importe quelle version de MATLAB. Ce code fait 67 octets:

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

Explication

  1. a=input('');- Reçoit un vecteur (ligne) de l'utilisateur via une entrée standard. Vous devez saisir le vecteur sous forme d'octave (c'est-à-dire[1,2,3] ).
  2. n=numel(...); - Obtient le nombre total d'éléments dans le vecteur d'entrée.
  3. x=0:n-1- Crée un vecteur ligne qui augmente de 0jusqu'àn-1 par pas de 1.
  4. (x=0:n-1)-x'- Effectue la diffusion de sorte que nous ayons une n x nmatrice de sorte que chaque ligne isoit des éléments de 0 à n-1chaque élément de la ligne isoustrait pari .
  5. mod(..., n)+1- Garantit que toutes les valeurs négatives s'enroulent autour de nsorte que chaque ligne icontienne le vecteur de 0 à décalé n-1 circulairement vers la gauche pari éléments. Nous ajoutons 1 lorsque MATLAB / Octave commence l'indexation des vecteurs ou matrices par 1.
  6. a(...)- Crée une n x nmatrice où en utilisant (4), nous accédons aux indices corrects du vecteur d'entrée dictés par chaque valeur de (4), obtenant ainsi la matrice dont nous avons besoin.
  7. (...)*a' - Effectue la multiplication des vecteurs matriciels par transposition / retournement a pour devenir un vecteur colonne avant de faire la multiplication.

Exemples d'exécutions

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

Essayez-le en ligne!

rayryeng - Réintégrer Monica
la source
Vous pouvez utiliser l'expansion implicite au lieu de bsxfun. La définition nsans -1enregistre également quelques octets. Et si vous vous limitez à Octave, vous pouvez assigner aet 0:nà des variables à la volée et en économiser davantage . Aussi, venez ici plus souvent !! :-D
Luis Mendo
@LuisMendo ah oui. J'oublie qu'Octave a une extension implicite déjà prise en charge. L'enregistrement de la variable à l'intérieur de la inputfonction est également une excellente astuce. Je ne pensais pas que cela pourrait soutenir cela. Je ne l'ai vu qu'en C ou C ++ d'après ma propre expérience. Merci!
rayryeng
1
@LuisMendo Je placerai bientôt vos modifications suggérées comme modification. J'ai été occupé, mais je n'en ai pas fait une priorité car cette entrée ne gagnera certainement jamais en nombre d'octets.
rayryeng
@LuisMendo a changé. Merci beaucoup :) J'ai compris le code car je modifiais mon explication ci-dessus.
rayryeng
Heureux d'avoir pu aider :-)
Luis Mendo
0

Javascript 79 octets

Prend un tableau d'entrée et sort un tableau du vecteur de matrice

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

Explication

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
        )
    ))
)
impitoyable
la source
0

Clojure, 80 octets

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

iterateproduit une séquence infinie, mais au lieu d'utiliser (take (count %) (iterate ...))pour l'arrêter, j'utilise %comme argument supplémentaire pourmap .

NikoNyrh
la source
0

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

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

Essayez-le en ligne!

Prend le vecteur d'entrée comme des nombres séparés par des espaces. Produit des nombres séparés par des sauts de ligne représentant le vecteur de résultat.

Xcali
la source
0

Lisp commun, 78 octets

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

Essayez-le en ligne!

Doublez le tableau (dans ce cas une liste Lisp) et parcourez les sous-listes avec i(en utilisant x, à travers y, pour arrêter l'itération). Ensuite, calculez l'élément suivant du résultat en additionnant le résultat de la multiplication de chaque élément de xavec chaque élément de i(arrêt à nouveau lorsque la liste la plus courte est terminée).

Renzo
la source