Berechnen Sie den Matrix-Vektor


14

Bei einem ganzzahligen Array von mindestens zwei Elementen wird der unten definierte Matrix-Vektor des Arrays ausgegeben .

Um den Matrix-Vektor zu berechnen , drehen Sie sich zuerst durch das Größeneingabearray n, um eine Größenmatrix zu erstellen n x n, wobei das erste Element des Arrays der Hauptdiagonale folgt. Dies bildet den Matrixteil. Drehen Sie für den Vektor das Eingabearray vertikal. Führen Sie dann eine normale Matrixmultiplikation durch. Der Ausgabevektor ist das Ergebnis.

Beispielsweise,

a = [1, 2, 3]

Drehen Sie zuerst das Array zweimal nach rechts, um eine Matrix zu erhalten, [3, 1, 2]und [2, 3, 1]stapeln Sie sie dann, um eine 3x3Matrix zu bilden

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

Drehen Sie das Array anschließend vertikal, um den Vektor zu bilden

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

Führen Sie die übliche Matrixmultiplikation durch

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

Und die Ausgabe ist [14, 11, 11]oder [[14], [11], [11]](Ihre Wahl, ob sie abgeflacht ist oder nicht).

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

Regeln

  • Es kann davon ausgegangen werden, dass die Eingabe und Ausgabe in den systemeigenen Ganzzahltyp Ihrer Sprache passen.
  • Die Ein- und Ausgabe kann in jedem beliebigen Format erfolgen .
  • Es ist entweder ein vollständiges Programm oder eine Funktion zulässig. Bei einer Funktion können Sie die Ausgabe zurückgeben, anstatt sie zu drucken.
  • Fügen Sie nach Möglichkeit einen Link zu einer Online-Testumgebung hinzu, damit andere Benutzer Ihren Code ausprobieren können!
  • Standardlücken sind verboten.
  • Dies ist daher gelten alle üblichen Golfregeln, und der kürzeste Code (in Byte) gewinnt.

Antworten:


8

Gelee , 5 Bytes

ṙJṚæ.

Probieren Sie es online!

Erläuterung

Zuerst:

wo sind Zeilenvektoren und ist ein Spaltenvektor ist .vkx

Dies zeigt, dass die Matrixmultiplikation nur ein Skalarprodukt zwischen Zeilen und Spalten ist.

Dann wird tatsächlich gedreht nach rechts, und wird gedreht nach rechts usw.v1v0vkvk-1

Aus einem anderen Blickwinkel, wird gedreht nach links, und wird gedreht nach links usw.v1vnvnv1

Wie es funktioniert

ṙ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

Gelee , 9 Bytes

LḶN⁸ṙæ×W€

Probieren Sie es online!

Eine Funktion, die ein vertikales Array zurückgibt. Als vollständiges Programm sieht es so aus, als würde es ein horizontales Array zurückgeben. Um ein horizontales Array zurückzugeben, müssen Sie dies LḶN⁸ṙ×⁸S€stattdessen tun .



2

Haskell , 49 Bytes

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

Probieren Sie es online!

Für eine Eingabe v=[1,2]

  • iterate tail$v++v ergibt die Liste [[1,2,1,2],[2,1,2],[1,2],[2],[],...]
  • fst<$>zip l vist das gleiche wie take(length v)lund ergibt[[1,2,1,2],[2,1,2]]
  • sum.zipWith(*)v wird auf jedes Element abgebildet, um das Vektor-Matrix-Zeilenprodukt zu erhalten.

Viel schlauer als meine Antwort! Ich mag es fst<$>zip l vsehr.
Jferard

2

R , 66 62 Bytes

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

Probieren Sie es online!


using Map(function(i)c(n[-(1:i)],n[1:i])%*%n,length(n<-scan()):1)ist 3 Bytes kürzer; es wird nur eine Liste von Matrizen zurückgegeben.
Giuseppe

und eine for-Schleife for(i in seq(n<-scan()))F=c(c(n[-(1:i)],n[1:i])%*%n,F);F[1:i]hat 61 Bytes, ohne ein seltsames Ausgabeformat zurückzugeben.
Giuseppe





1

J , 14 Bytes

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

Probieren Sie es online!

Erläuterung

+/ .*~#\.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

Das ist ganz nett. Eine Frage. Wenn Sie 1&|.sind nicht binden Sie 1an |., eine Monade zu schaffen? Aber dann benutzt du diese Monade sowohl mit einem linken als auch mit einem rechten Argument, wobei das linke bestimmt, wie oft es angewendet wird. Was ist denn hier los?
Jonah

@Jonah Es ist ein spezielles Formular für &. Wenn es als verwendet wird u n&f v, wird es ausgeführt (n&f)^:u v. Sehen Sie sich den unteren Rand der Bindung an, um mehr Teile davon zu sehen.
Meilen

ah, bis. Verwenden Sie das häufig?
Jonah

@Jonah In vielen Fällen ist es nützlich, um Golf zu spielen. In diesem Fall hätte es mit Rank in der gleichen Anzahl von Bytes geschehen können #\.|."{], aber ich habe den kürzesten Wert angegeben, den ich zuerst gefunden habe, bevor ich Alternativen ausprobiert habe.
Meilen

1

APL, 17 Bytes

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

Erläuterung:

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

Haskell , 56 55 52 Bytes

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

Probieren Sie es online!

Dank @Laikoni ein Byte gespeichert

Drei Bytes gespeichert: l++lstattcycle l


Mit können Sie ein Byte speichern zipWith(*)l$drop i$cycle l.
Laikoni

1

Schale , 11 Bytes

mΣ§‡*´ṀKoṫ¢

Probieren Sie es online!

Erläuterung

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

Oktave - 67 48 Bytes

Vielen Dank an Luis Mendo, der diesen Code um 19 Byte reduziert hat!

Hinweis: Dieser Code kann nur in Octave ausgeführt werden. MATLAB unterstützt keine Ausdrücke in Funktionen, die Variablen erstellen und gleichzeitig die Ausdrücke auswerten können, die sie erstellen.

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

Der Originalcode in MATLAB ist hier zu finden, kann aber in jeder Version von MATLAB ausgeführt werden. Dieser Code ist 67 Bytes:

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

Erläuterung

  1. a=input('');- Erhält einen (Zeilen-) Vektor vom Benutzer über die Standardeingabe. Sie müssen den Vektor in Oktavform eingeben [1,2,3].
  2. n=numel(...); - Ermittelt die Gesamtzahl der Elemente im Eingabevektor.
  3. x=0:n-1- Erstellt einen Zeilenvektor, der von 0bis zu n-1in Schritten von 1 erhöht wird .
  4. (x=0:n-1)-x'- Führt Rundsendungen aus, sodass wir eine n x nMatrix haben, sodass jede Zeile iElemente von 0 bis zu sind, n-1wobei jedes Element in der Zeile von isubtrahiert wirdi .
  5. mod(..., n)+1- Stellt sicher, dass alle negativen Werte nso umbrochen werden, dass jede Zeile iden Vektor von 0 bis n-1 kreisförmig nach links verschoben enthälti Elemente enthält. Wir addieren 1, wenn MATLAB / Octave Vektoren oder Matrizen mit 1 indiziert.
  6. a(...)- Erstellt eine n x nMatrix, in der mit (4) auf die korrekten Indizes des Eingabevektors zugegriffen wird, die von jedem Wert aus (4) vorgegeben werden, wodurch die von uns benötigte Matrix erhalten wird.
  7. (...)*a'- Führt eine Matrixvektormultiplikation durch Transponieren / Kippen durch a, um vor der Multiplikation einen Spaltenvektor zu erhalten.

Beispielläufe

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

Probieren Sie es online!


Sie können statt implizite Erweiterung verwenden bsxfun. Das Definieren nohne -1spart auch ein paar Bytes. Und wenn Sie sich auf Octave beschränken, können Sie Variablen im laufenden Betrieb zuweisen aund weitere speichern . Komme auch öfter hierher !! :-D0:n
Luis Mendo

@ LuisMendo ah ja. Ich vergesse, dass Octave die implizite Erweiterung bereits unterstützt. Auch das Speichern der Variablen innerhalb der inputFunktion ist ein großartiger Trick. Ich hätte nicht gedacht, dass es das unterstützen könnte. Ich habe es aus eigener Erfahrung nur in C oder C ++ gesehen. Vielen Dank!
Rayryeng Reinstate Monica

1
@LuisMendo Ich werde Ihre Änderungsvorschläge bald als Bearbeitung veröffentlichen. Ich war beschäftigt, aber ich habe dies nicht zu einer Priorität gemacht, da dieser Eintrag in der Byteanzahl mit Sicherheit nie gewinnen wird.
Rayryeng - Wiedereinsetzung von Monica

@ LuisMendo geändert. Vielen Dank :) Ich habe den Code verstanden, als ich meine Erklärung oben geändert habe.
Rayryeng - Wiedereinsetzung von Monica

Ich bin froh, dass ich helfen konnte :-)
Luis Mendo

0

Javascript 79 Bytes

Nimmt ein Eingabearray auf und gibt ein Array des Matrixvektors aus

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

Erläuterung

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

iterateerzeugt eine unendliche Sequenz, aber anstatt sie (take (count %) (iterate ...))zu stoppen, verwende ich %als zusätzliches Argument für 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}

Probieren Sie es online!

Nimmt den Eingabevektor als durch Leerzeichen getrennte Zahlen. Gibt durch Zeilenvorschub getrennte Zahlen aus, die den Ergebnisvektor darstellen.



0

Common Lisp, 78 Bytes

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

Probieren Sie es online!

Verdoppeln Sie das Array (in diesem Fall eine Lisp-Liste) und durchlaufen Sie die Unterlisten mit i(mit x, bis y, stoppen Sie die Iteration). Berechnen Sie dann das nächste Element des Ergebnisses, indem Sie das Ergebnis der Multiplikation jedes Elements xmit jedem Element von aufsummieren i(stoppen Sie erneut, wenn die kürzere Liste beendet ist).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.