Tính toán ma trận-Vector


14

Cho một mảng số nguyên có ít nhất hai phần tử, xuất ra Ma trận-Vector (được xác định bên dưới) của mảng.

Để tính toán Ma trận-Vector , trước tiên hãy xoay qua nmảng kích thước- đầu vào để tạo ma trận có kích thước n x n, với phần tử đầu tiên của mảng theo đường chéo chính. Điều này tạo thành phần ma trận. Đối với vectơ, lật mảng đầu vào theo chiều dọc. Sau đó thực hiện phép nhân ma trận bình thường. Các vector đầu ra là kết quả.

Ví dụ,

a = [1, 2, 3]

Đầu tiên, xoay mảng hai lần sang phải, để lấy [3, 1, 2][2, 3, 1]sau đó xếp chúng lại để tạo thành 3x3ma trận

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

Tiếp theo, lật mảng theo chiều dọc để tạo thành vector

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

Thực hiện phép nhân ma trận thông thường

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

Và đầu ra là [14, 11, 11]hoặc [[14], [11], [11]](sự lựa chọn của bạn về việc nó có bị xẹp hay không).

Ví dụ # 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]

Quy tắc

  • Đầu vào và đầu ra có thể được coi là phù hợp với kiểu số nguyên của ngôn ngữ của bạn.
  • Đầu vào và đầu ra có thể được đưa ra trong bất kỳ định dạng thuận tiện .
  • Hoặc là một chương trình đầy đủ hoặc một chức năng được chấp nhận. Nếu một chức năng, bạn có thể trả lại đầu ra thay vì in nó.
  • Nếu có thể, vui lòng bao gồm một liên kết đến một môi trường thử nghiệm trực tuyến để người khác có thể thử mã của bạn!
  • Sơ hở tiêu chuẩn bị cấm.
  • Đây là vì vậy tất cả các quy tắc chơi gôn thông thường đều được áp dụng và mã ngắn nhất (tính bằng byte) sẽ thắng.

Câu trả lời:


8

Thạch , 5 byte

ṙJṚæ.

Hãy thử trực tuyến!

Giải trình

Thứ nhất:

nơi là hàng vectơ và là mộtvkx cột vector.

Điều này chứng tỏ rằng phép nhân ma trận chỉ là chấm sản phẩm giữa các hàng và cột.

Sau đó, thực sự được quay sang phải, và được xoayv1v0vkvk-1 sang phải, v.v.

Từ một góc độ khác, được quay sang trái, và được xoayv1vnvnv1 sang trái, v.v.

Làm thế nào nó hoạt động

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






2

Haskell , 49 byte

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

Hãy thử trực tuyến!

Đối với một đầu vào v=[1,2]

  • iterate tail$v++v mang lại danh sách [[1,2,1,2],[2,1,2],[1,2],[2],[],...]
  • fst<$>zip l vgiống như take(length v)lvà sản lượng[[1,2,1,2],[2,1,2]]
  • sum.zipWith(*)v được ánh xạ trên mỗi phần tử và để tạo ra sản phẩm hàng ma trận vector.

Thông minh hơn nhiều so với câu trả lời của tôi! Tôi fst<$>zip l vrất thích
jferard

2

R , 66 62 byte

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

Hãy thử trực tuyến!


sử dụng Map(function(i)c(n[-(1:i)],n[1:i])%*%n,length(n<-scan()):1)ngắn hơn 3 byte; nó chỉ trả về một danh sách các ma trận.
Giuseppe

và một vòng lặp for for(i in seq(n<-scan()))F=c(c(n[-(1:i)],n[1:i])%*%n,F);F[1:i]là 61 byte mà không trả về một định dạng đầu ra kỳ lạ.
Giuseppe





1

J , 14 byte

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

Hãy thử trực tuyến!

Giải trình

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

Điều này là khá tốt đẹp. Một câu hỏi. Khi bạn làm 1&|.được không bạn việc kết hợp 1để |.tạo nên một đơn nguyên? nhưng sau đó bạn sử dụng đơn nguyên đó với cả hai bên trái và bên phải, với bên trái xác định số lần áp dụng. Những gì đang xảy ra ở đây?
Giô-na

@Jonah Đó là một hình thức đặc biệt cho &. Khi được sử dụng như u n&f v, nó đang thực hiện (n&f)^:u v. Xem dưới cùng của trái phiếu để xem thêm các phân tích của nó.
dặm

ah, TIL. đó có phải là thứ bạn sử dụng thường xuyên không?
Giô-na

@Jonah Nó hữu ích cho việc chơi golf trong nhiều trường hợp. Trong trường hợp này, nó có thể đã được thực hiện với số lượng byte bằng nhau bằng cách sử dụng thứ hạng #\.|."{], nhưng tôi đã đăng bài ngắn nhất mà tôi đã đưa ra trước khi thử các lựa chọn thay thế.
dặm

1

APL, 17 byte

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

Giải trình:

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

Husk , 11 byte

mΣ§‡*´ṀKoṫ¢

Hãy thử trực tuyến!

Giải trình

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

Octave - 67 48 byte

Cảm ơn Luis Mendo đã cạo mã này xuống 19 byte!

Lưu ý: Mã này chỉ có thể chạy trong Octave. MATLAB không hỗ trợ các biểu thức bên trong các hàm có thể tạo các biến đồng thời đánh giá các biểu thức tạo ra chúng.

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

Mã gốc trong MATLAB có thể được tìm thấy ở đây, nhưng có thể chạy trong bất kỳ phiên bản MATLAB nào. Mã này là 67 byte:

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

Giải trình

  1. a=input('');- Nhận một vectơ (hàng) từ người dùng thông qua đầu vào tiêu chuẩn. Bạn phải nhập vectơ ở dạng Octave (nghĩa là[1,2,3] ).
  2. n=numel(...); - Lấy tổng số phần tử trong vectơ đầu vào.
  3. x=0:n-1- Tạo một vectơ hàng tăng từ 0lên đến n-1bước 1.
  4. (x=0:n-1)-x'- Thực hiện phát sóng sao cho chúng ta có một n x nma trận sao cho mỗi hàng ilà các phần tử từ 0 đến n-1với mỗi phần tử trong hàng bị itrừ bởii .
  5. mod(..., n)+1- Đảm bảo rằng bất kỳ giá trị nào được phủ định xung quanh nsao cho mỗi hàng ichứa vectơ từ 0 lên đến dịch chuyển n-1 tròn sang trái bởi icác phần tử. Chúng ta thêm 1 khi MATLAB / Octave bắt đầu lập chỉ mục các vectơ hoặc ma trận với 1.
  6. a(...) - Tạo ra một n x n ma trận trong đó sử dụng (4), chúng ta truy cập vào các chỉ số chính xác của vectơ đầu vào được xác định theo từng giá trị từ (4) do đó đạt được ma trận chúng ta cần.
  7. (...)*a'- Thực hiện phép nhân vectơ ma trận bằng cách hoán vị / lật ađể trở thành vectơ cột trước khi thực hiện phép nhân.

Chạy ví dụ

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

Hãy thử trực tuyến!


Bạn có thể sử dụng mở rộng ngầm thay vì bsxfun. Xác định nmà không -1lưu một vài byte quá. Và nếu bạn giới hạn ở Octave, bạn có thể gán a0:ncho các biến khi đang di chuyển và tiết kiệm thêm một số . Ngoài ra, đến đây thường xuyên hơn !! :-D
Luis Mendo

@LuisMendo ah vâng. Tôi quên Octave đã mở rộng ngầm đã được hỗ trợ. Ngoài ra lưu các biến bên trong inputhàm là một mẹo hay. Tôi không nghĩ rằng nó có thể hỗ trợ điều đó. Tôi đã thấy nó chỉ trong C hoặc C ++ từ kinh nghiệm của riêng tôi. Cảm ơn!
rayryeng - Phục hồi Monica

1
@LuisMendo Tôi sẽ sớm đưa ra các thay đổi được đề xuất của bạn dưới dạng chỉnh sửa. Tôi đã bận rộn, nhưng tôi chưa ưu tiên điều này vì mục này chắc chắn sẽ không bao giờ giành được số byte.
rayryeng - Phục hồi Monica

@LuisMendo Thay đổi. Cảm ơn bạn rất nhiều :) Phải hiểu mã khi tôi thay đổi lời giải thích của tôi ở trên.
rayryeng - Phục hồi lại

Vui mừng tôi có thể giúp :-)
Luis Mendo

0

Javascript 79 byte

Đưa vào một mảng đầu vào và xuất ra một mảng của vectơ ma trận

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

Giải trình

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 byte

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

iteratetạo ra một chuỗi vô hạn, nhưng thay vì sử dụng (take (count %) (iterate ...))để dừng nó, tôi sử dụng %như một đối số phụ map.


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}

Hãy thử trực tuyến!

Lấy vectơ đầu vào là các số được phân tách bằng dấu cách. Đầu ra các dòng được phân tách các số đại diện cho vectơ kết quả.



0

Lisp thông thường, 78 byte

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

Hãy thử trực tuyến!

Nhân đôi mảng (trong trường hợp này là danh sách Lisp) và lặp lại qua danh sách con với i(sử dụng x, thông qua y, để dừng lặp lại). Sau đó tính toán phần tử tiếp theo của kết quả bằng cách tính tổng kết quả của việc nhân từng phần tử xvới từng phần tử của i(dừng lại khi danh sách ngắn hơn kết thúc).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.