Hitung Matriks-Vektor

14

Diberikan array integer setidaknya dua elemen, output Matrix-Vector (didefinisikan di bawah) dari array.

Untuk menghitung Matriks-Vektor , pertama-tama putar melalui narray input -ukuran untuk membuat matriks ukuran n x n, dengan elemen pertama dari array mengikuti diagonal utama. Ini membentuk bagian matriks. Untuk vektor, balik array input secara vertikal. Kemudian lakukan perkalian matriks normal. Vektor keluaran adalah hasilnya.

Sebagai contoh,

a = [1, 2, 3]

Pertama, putar array dua kali ke kanan, untuk mendapatkan [3, 1, 2]dan [2, 3, 1], kemudian susun mereka untuk membentuk 3x3matriks

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

Selanjutnya, balikkan array secara vertikal untuk membentuk vektor

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

Lakukan perkalian matriks biasa

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

Dan hasilnya adalah [14, 11, 11]atau [[14], [11], [11]](pilihan Anda apakah itu rata atau tidak).

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

Aturan

  • Input dan output dapat dianggap sesuai dengan tipe integer asli bahasa Anda.
  • Input dan output dapat diberikan dalam format apa pun yang nyaman .
  • Program lengkap atau fungsi dapat diterima. Jika suatu fungsi, Anda dapat mengembalikan output daripada mencetaknya.
  • Jika memungkinkan, harap sertakan tautan ke lingkungan pengujian online agar orang lain dapat mencoba kode Anda!
  • Celah standar dilarang.
  • Ini adalah sehingga semua aturan golf biasa berlaku, dan kode terpendek (dalam byte) menang.
AdmBorkBork
sumber

Jawaban:

8

Jelly , 5 byte

ṙJṚæ.

Cobalah online!

Penjelasan

Pertama:

mana yang baris vektor dan adalah kolom vektor.vkx

Ini menunjukkan bahwa perkalian matriks hanyalah produk titik antara baris dan kolom.

Kemudian, sebenarnya diputar ke kanan, dan yang diputar ke kanan, dllv1v0vkvk-1

Dari sudut yang lain, yang diputar ke kiri, dan yang diputar ke kiri, dllv1vnvnv1

Bagaimana itu bekerja

ṙ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)
Biarawati Bocor
sumber
5

Python 2 , 68 byte

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

Cobalah online!

tongkat
sumber
4

Python 2 , 73 byte

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

Cobalah online!

Arfie
sumber
(v*2)[i+j]trik yang bagus
Leaky Nun
4

Pyth , 10 byte

ms*VQ.>QdU

Suite uji .

Biarawati Bocor
sumber
3

Jelly , 9 byte

LḶN⁸ṙæ×W€

Cobalah online!

Fungsi yang mengembalikan array vertikal. Sebagai sebuah program lengkap, ia tampak seolah-olah mengembalikan array horizontal. Untuk mengembalikan array horizontal, Anda akan melakukannya LḶN⁸ṙ×⁸S€.

Erik the Outgolfer
sumber
2

Haskell , 49 byte

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

Cobalah online!

Untuk input v=[1,2]

  • iterate tail$v++v menghasilkan daftar [[1,2,1,2],[2,1,2],[1,2],[2],[],...]
  • fst<$>zip l vsama dengan take(length v)ldan hasil[[1,2,1,2],[2,1,2]]
  • sum.zipWith(*)v dipetakan pada setiap elemen dan untuk menghasilkan produk baris vektor-matriks.
Laikoni
sumber
Jauh lebih pintar dari jawaban saya! Saya fst<$>zip l vsangat suka .
jferard
2

R , 66 62 byte

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

Cobalah online!

Biarawati Bocor
sumber
menggunakan Map(function(i)c(n[-(1:i)],n[1:i])%*%n,length(n<-scan()):1)lebih pendek 3 byte; itu hanya mengembalikan daftar matriks.
Giuseppe
dan untuk loop for(i in seq(n<-scan()))F=c(c(n[-(1:i)],n[1:i])%*%n,F);F[1:i]adalah 61 byte tanpa mengembalikan format output yang aneh.
Giuseppe
2

Mathematica, 35 byte

Most@FoldList[RotateRight,#,1^#].#&

Cobalah online!

-9 byte dari @Tidak pohon

J42161217
sumber
2
Itu lebih pendek untuk menggunakan Mathematica ini perkalian matriks sendiri daripada untuk menciptakan sendiri: Most@FoldList[RotateRight,#,1^#].#&. (Tapi trik yang bagus Folddaripada menggunakan Nest!)
Bukan pohon
1

CJam , 17 byte

{__,,\fm>\f.*::+}

Cobalah online!

Erik the Outgolfer
sumber
1

Python 3 + numpy , 68 byte

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

Cobalah online!

notjagan
sumber
1

J , 14 byte

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

Cobalah online!

Penjelasan

+/ .*~#\.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
mil
sumber
Ini cukup bagus. Satu pertanyaan. Ketika Anda melakukannya 1&|., Anda tidak terikat 1dengan |., menciptakan monad? tetapi kemudian Anda menggunakan monad dengan arg kiri dan kanan, dengan monad kiri menentukan berapa kali diterapkan. Apa yang terjadi di sini?
Jonah
@Jonah Ini formulir khusus untuk &. Ketika digunakan sebagai u n&f v, itu berfungsi (n&f)^:u v. Lihat bagian bawah ikatan untuk melihat lebih banyak parsingnya.
mil
ah, TIL. Apakah itu sesuatu yang sering Anda gunakan?
Jonah
@Jonah Berguna untuk bermain golf dalam banyak kasus. Dalam hal ini, bisa saja dilakukan dalam jumlah byte yang sama menggunakan pangkat #\.|."{], tetapi saya memposting yang terpendek yang saya buat terlebih dahulu sebelum mencoba alternatif.
mil
1

APL, 17 byte

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

Penjelasan:

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

Haskell , 56 55 52 byte

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

Cobalah online!

Disimpan satu byte berkat @Laikoni

Disimpan tiga byte: l++lbukannyacycle l

jferard
sumber
Anda dapat menyimpan byte dengan zipWith(*)l$drop i$cycle l.
Laikoni
1

Sekam , 11 byte

mΣ§‡*´ṀKoṫ¢

Cobalah online!

Penjelasan

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

Oktaf - 67 48 byte

Terima kasih kepada Luis Mendo karena mencukur kode ini sebanyak 19 byte!

Catatan: Kode ini hanya dapat berjalan dalam Oktaf. MATLAB tidak mendukung ekspresi di dalam fungsi yang dapat membuat variabel sambil secara bersamaan mengevaluasi ekspresi yang membuatnya.

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

Kode asli dalam MATLAB dapat ditemukan di sini, tetapi dapat dijalankan dalam versi MATLAB. Kode ini adalah 67 byte:

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

Penjelasan

  1. a=input('');- Menerima vektor (baris) dari pengguna melalui input standar. Anda harus memasukkan vektor dalam bentuk Oktaf (mis[1,2,3] ).
  2. n=numel(...); - Memperoleh jumlah total elemen dalam vektor input.
  3. x=0:n-1- Membuat vektor baris yang meningkat dari 0hinggan-1 dalam langkah 1.
  4. (x=0:n-1)-x'- Melakukan penyiaran sehingga kita memiliki n x nmatriks sehingga setiap baris iadalah elemen dari 0 hingga n-1dengan setiap elemen di baris idikurangi olehi .
  5. mod(..., n)+1- Memastikan bahwa setiap nilai-nilai yang membungkus negatif sekitar untuk nsehingga setiap baris iberisi vektor dari 0 hingga n-1 sirkuler bergeser ke kiri oleh iunsur-unsur. Kami menambahkan 1 sebagai MATLAB / Oktaf mulai pengindeksan vektor atau matriks dengan 1.
  6. a(...) - Menciptakan a n x n matriks di mana menggunakan (4), kita mengakses indeks yang benar dari vektor input yang ditentukan oleh setiap nilai dari (4) sehingga mencapai matriks yang kita butuhkan.
  7. (...)*a'- Melakukan perkalian vektor matriks dengan transposing / flipping amenjadi vektor kolom sebelum melakukan perkalian.

Contoh Berjalan

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

Cobalah online!

rayryeng - Reinstate Monica
sumber
Anda dapat menggunakan ekspansi tersirat alih-alih bsxfun. Menentukan ntanpa -1menyimpan beberapa byte juga. Dan jika Anda membatasi ke Oktaf Anda dapat menetapkan adan 0:nke variabel dengan cepat dan menyimpan lebih banyak . Juga, datang ke sini lebih sering !! :-D
Luis Mendo
@LuisMendo ah ya. Saya lupa Octave telah ekspansi implisit sudah didukung. Juga menyimpan variabel di dalam inputfungsi adalah trik yang bagus. Saya tidak berpikir itu bisa mendukung itu. Saya sudah melihatnya hanya dalam C atau C ++ dari pengalaman saya sendiri. Terima kasih!
rayryeng
1
@LuisMendo Saya akan segera melakukan perubahan yang disarankan sebagai hasil edit. Saya sibuk, tetapi saya belum menjadikan ini prioritas karena entri ini pasti tidak akan pernah menang dalam hitungan byte.
rayryeng
@LuisMendo Berubah. Terima kasih banyak :) Saya harus mengerti kode ini karena saya mengubah penjelasan saya di atas.
rayryeng
Senang saya bisa membantu :-)
Luis Mendo
0

Javascript 79 byte

Mengambil dalam array input dan output array dari matriks matriks

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

Penjelasan

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
        )
    ))
)
sangat penting
sumber
0

Clojure, 80 byte

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

iteratemenghasilkan urutan yang tak terbatas, tetapi alih-alih menggunakan (take (count %) (iterate ...))untuk menghentikannya saya menggunakan %sebagai argumen tambahan untuk map.

NikoNyrh
sumber
0

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

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

Cobalah online!

Mengambil vektor input sebagai angka yang dipisahkan spasi. Keluaran baris terpisah angka yang mewakili vektor hasil.

Xcali
sumber
0

Common Lisp, 78 byte

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

Cobalah online!

Gandakan larik (dalam hal ini daftar Lisp) dan beralih di atas daftar dengan i(menggunakan x, melalui y, untuk menghentikan iterasi). Kemudian hitung elemen berikutnya dari hasil dengan menjumlahkan hasil dari mengalikan setiap elemen xdengan masing-masing elemen i(sekali lagi berhenti ketika daftar yang lebih pendek diakhiri).

Renzo
sumber