Pad sebuah matriks dengan jumlahnya

23

Tantangan:

Diberikan matriks input persegi A , pad matriks dengan satu baris dan satu kolom di keempat sisi.

  • Nilai setiap elemen di baris atas dan bawah harus merupakan jumlah dari elemen di setiap kolom yang sesuai.
  • Nilai setiap elemen di kolom kiri dan kanan harus merupakan jumlah dari elemen di setiap baris yang sesuai.
  • Nilai elemen di kiri atas, dan sudut kanan bawah harus menjadi jumlah elemen di diagonal
  • Nilai elemen di kanan atas, dan sudut kiri bawah harus menjadi jumlah elemen di anti-diagonal.

Contoh:

A = 
1   5   3
3   2   4
2   5   5

Output:
 8    6   12   12    7
 9    1    5    3    9
 9    3    2    4    9
12    2    5    5   12
 7    6   12   12    8

Penjelasan:

Elemen kiri atas dan kanan bawah adalah jumlah dari diagonal 1 + 2 + 5 = 8 . Elemen kanan atas dan kiri bawah adalah jumlah dari anti-diagonal 2 + 2 + 3 = 7 .

Baris atas dan bawah (kecuali sudut) adalah jumlah dari masing-masing kolom dalam A : 1 + 3 + 2 = 6 , 5 + 2 + 5 = 12 dan 3 + 4 + 5 = 12 . Demikian pula, kolom kiri dan kanan (kecuali sudut) adalah jumlah dari setiap baris A : 1 + 5 + 3 = 9 , 3 + 2 + 4 = 9 dan 2 + 5 + 5 = 12 .

Memasukkan:

  • Matriks kuadrat tidak kosong, dengan bilangan bulat non-negatif.
  • Format opsional

Keluaran:

  • Matriks tersebut diisi seperti dijelaskan di atas
  • Format opsional, tetapi harus sama dengan format input

Kasus uji:

Gunakan kiriman dalam tantangan ini jika Anda ingin mengonversi format input ke format yang lebih cocok (misalnya [[1, 5],[0, 2]]).

0
----------------
0 0 0
0 0 0
0 0 0

1 5
0 2
----------------
3 1 7 5
6 1 5 6
2 0 2 2
5 1 7 3

17   24    1    8   15
23    5    7   14   16
 4    6   13   20   22
10   12   19   21    3
11   18   25    2    9 
----------------
65   65   65   65   65   65   65
65   17   24    1    8   15   65
65   23    5    7   14   16   65
65    4    6   13   20   22   65
65   10   12   19   21    3   65
65   11   18   25    2    9   65
65   65   65   65   65   65   65

15    1    2   12
 4   10    9    7
 8    6    5   11
 3   13   14    0
----------------
30   30   30   30   30   30
30   15    1    2   12   30
30    4   10    9    7   30
30    8    6    5   11   30
30    3   13   14    0   30
30   30   30   30   30   30

Ini adalah , sehingga solusi terpendek dalam setiap bahasa menang. Penjelasan sangat dianjurkan.

Stewie Griffin
sumber
2
Apakah itu untuk memeriksa kotak ajaib?
mdahmoune
Hanya mengeceknya sedikit lebih mudah, tetapi memang mudah untuk melihat apakah sebuah kotak ajaib dengan cara ini, ya :-)
Stewie Griffin

Jawaban:

5

Oktaf , 64 byte

Terima kasih kepada Tom Carpenter karena telah menghemat 4 byte, dan mengoreksi kesalahan yang saya miliki dalam kode asli!

@(a)[b=(t=@trace)(a),c=sum(a),d=t(flip(a));z=sum(a,2),a,z;d,c,b]

Cobalah online!

Penjelasan:

@(a)                 % Anonymous function that takes the matrix 'a' as input
 [ ... ]             % Concatenate everything inside to a single matrix
  b=(t=@trace)(a),   % Clever trick by Tom Carpenter. Save a function handle 
                     % for 't=trace', and call it with 'a' as input
                     % Save the result in the variable 'b'
  c=sum(a)           % Sum of all columns of 'a'
  d=t(flip(a));      % Save the trace of 'a' flipped as a variable 'd', while 
                     % concatenating [b,c,d] horizontally at the same time, creating the 
                     % first row of the output
  z=sum(a,2)         % The sum of each row of the input, and store it in a variable 'z'
  ,a,z;              % Concatenate it with 'a' and 'z' again, to create the middle part of the output
 d,c,b]              % Add [d,c,b] to complete the bottom row

Catatan, saya menulis ini lama setelah saya memposting tantangan.

Stewie Griffin
sumber
4

Jelly , 27 byte

,UŒDḢ$S$€,Ṛ$j€SW€jSẋ¥€2$j"$

Cobalah online!

Erik the Outgolfer
sumber
2
Saya ingin tahu bagaimana ini bekerja, tolong.
Kamerad SparklePony
@ComradeSparklePony Saya tidak tahu apakah saya punya waktu untuk menulis penjelasan sekarang, maaf.
Erik the Outgolfer
Tidak apa-apa, jangan khawatir.
Kamerad SparklePony
4

MATL , 27 26 byte

,!tXswyv]GXds5L(PGPXds5L(P

Cobalah online! Atau verifikasi semua kasus uji .

Penjelasan

,        % Do the following twice
  !      %   Tranpose. Takes input implititly in the first iteration
  t      %   Duplicate
  Xs     %   Row vector with the sum of each column
  wy     %   Push a copy to the bottom of the stack
  v      %   Concatenate stack vertically. This attaches the sum of
         %   each row (first iteration) and column (second), leaving 
         %   the matrix with the correct orientation (transposed twice)
]        % End
G        % Push input again
Xds      % Column vector with the diagonal of the matrix. Sum of vector
5L(      % Write that into first and last entries of the result matrix
         % matrix; that is, its upper-left and lower-right corners
P        % Flip result matrix vertically
GP       % Push input matrix vertically flipped
Xds      % Diagonal, sum. Since the input has been vertically flipped,
         % this gives the sum of the anti-diagonal of the input.
5L(      % Write that into the upper-left and lower-right corners of
         % the verticallly flipped version of the result matrix
P        % Flip vertically again, to restore initial orientation
         % Implicitly display
Luis Mendo
sumber
Tentu saja MATL dirancang untuk bekerja dengan matriks tidak seperti Jelly. > _>
Erik the Outgolfer
@EriktheOutgolfer Tapi jawaban Anda memiliki lebih banyak euro!
Luis Mendo
3
Ya itu punya dolar euro dan yen ... sayangnya itu bukan kriteria kemenangan di sini. D:
Erik the Outgolfer
3

APL (Dyalog) , 37 byte

(d,+⌿,d∘⌽)⍪(+/,⊢,+/)⍪d∘⌽,+⌿,d←+/1 1∘⍉

Cobalah online!

1 1∘⍉ diagonal (sedikit runtuh kedua sumbu menjadi satu)

d← simpan fungsi itu sebagai d dan terapkan pada argumen

+⌿ tambahkan jumlah kolom

d∘⌽, tambahkan d diterapkan pada argumen terbalik

(... )⍪ susun yang berikut di atas:

+/,⊢,+/ jumlah baris, argumen yang tidak dimodifikasi, jumlah baris

(... )⍪ susun yang berikut di atas:

d,+⌿,d∘⌽ diterapkan pada argumen, jumlah kolom, d diterapkan pada argumen terbalik

Adm
sumber
3

Jelly , 26 byte

ŒDµḊṖѵ€1¦ŒḌU
S;;S
Ç€Zµ⁺ÑÑ

Cobalah online!

Tampak sangat berbeda dari solusi Erik .

Saya akhirnya berhasil memahami cara ¦kerjanya (dengan men-debug kode Jelly, lol). Sayang sekali itu membutuhkan untuk bekerja dengan Çdalam kasus saya.

Penjelasan

Kode ini menggunakan tiga tautan. Link helper pertama memuat vektor dengan penjumlahannya di kedua ujungnya, link helper kedua memperbaiki dua sudut matriks dan tautan utama menyebutnya dengan tepat.

Ç€Zµ⁺ÑÑ    Main link. Argument: M (matrix)
Ç            Call the first helper link (pad row with sums)...
 €           ...on each row of the matrix.
  Z          Transpose, so that the second invocation uses the columns.
   µ         Begin a new monadic chain.
    ⁺        Repeat the previous chain (everything up to here).
     ÑÑ      Call the second helper link twice on the whole matrix.

S;;S    First helper link. Argument: v (1-dimensional list)
S         Sum the argument list.
 ;        Append the argument list to the sum.
  ;       Append...
   S      ...the sum of the argument list.

ŒDµḊṖѵ€1¦ŒḌU    Second helper link. Argument: M (matrix)
ŒD                 Get the diagonals of the matrix, starting with the main diagonal.
  µ                Begin a new monadic chain.
      µ€           Perform the following actions on each diagonal...
        1¦         ...and keep the result for the first item (main diagonal):
   Ḋ                 Remove the first item (incorrect top corner).
    Ṗ                Remove the last item (incorrect bottom corner).
     Ñ               Call the first helper link on the diagonal to pad it with its sum.
          ŒḌ       Convert the diagonals back to the matrix.
            U      Reverse each row, so that consecutive calls fix the other corners.
PurkkaKoodari
sumber
3

Python 3 , 155 byte

Ini adalah saran dari @ LeakyNun, yang menghemat 54 byte . Saya kemudian bermain golf sendiri sedikit.

def f(m):l=len(m);r=range(l);s=sum;b=[s(m[i][i]for i in r)];c=[s(m[i][l+~i]for i in r)];d=[*map(s,zip(*m))];return[b+d+c,*[[s(a),*a,s(a)]for a in m],c+d+b]

Cobalah online!

Solusi awal - Python 3 , 216 byte

def f(m):l=len(m);r,s=range(l),sum;a,b,c,d=s(m[i][i]for i in r),s(m[i][l-i-1]for i in r),[s(m[i][j]for j in r)for i in r],[s(m[i][j]for i in r)for j in r];print([[a]+d+[b]]+[[c[i]]+m[i]+[c[i]]for i in r]+[[b]+d+[a]])

Cobalah online!

Tuan Xcoder
sumber
162 byte
Leaky Nun
@ LeakyNun Terima kasih. Baru saja memperbarui dengan ~ 190 byte, ini jauh lebih pendek: P
Mr. Xcoder
2

Python 2 , 268 250 184 174 byte

10 terima kasih kepada Stewie Griffin

from numpy import *
a,c,v,s=sum,trace,vstack,matrix(input())
l,r,d,e=a(s,0),a(s,1),c(s),c(fliplr(s))
print hstack((v(([[d]],r,[[e]])),v((l,s,l)),v(([[e]],r,[[d]])))).tolist()

Cobalah online!

Beberapa penjelasan . Masukan diunggah dalam bentuk matriks. Pertama kode menghitung jumlah setiap kolom dan setiap baris menggunakan numpy.sum. Kemudian menghitung jumlah diagonal dengan numpy.trace. Setelah ini ia memperoleh diagonal lainnya dengan membuat flip kiri-kanan pada matriks. Akhirnya, ia menggunakan numpy.vstack dan numpy.hstack untuk merekatkan potongan.

mdahmoune
sumber
@StewieGriffin Ok, saya baru saja memperbarui kodenya :)
mdahmoune
1
Saya percaya ini bekerja untuk 174 tio.run/…
Stewie Griffin
2

R, 129 byte

pryr::f(t(matrix(c(d<-sum(diag(m)),c<-colSums(m),a<-sum(diag(m[(n<-nrow(m)):1,])),t(matrix(c(r<-rowSums(m),m,r),n)),a,c,d),n+2)))

Fungsi anonim yang mengambil matriks persegi sebagai input. Saya akan memposting penjelasan jika ada minat.

rturnbull
sumber
2

PHP , 211 byte

<?foreach($_GET as$l=>$r){$y=0;foreach($r as$k=>$c){$y+=$c;$x[$k]+=$c;$l-$k?:$d+=$c;($z=count($_GET))-1-$k-$l?:$h+=$c;}$o[]=[-1=>$y]+$r+[$z=>$y];}$o[]=[-1=>$h]+$x+[$z=>$d];print_r([-1=>[-1=>$d]+$x+[$z=>$h]]+$o);

Cobalah online!

Diperluas

foreach($_GET as$l=>$r){
  $y=0; # sum for a row
  foreach($r as$k=>$c){
    $y+=$c; # add to sum for a row
    $x[$k]+=$c; # add to sum for a column and store in array
    $l-$k?:$d+=$c; # make the diagonal sum left to right
    ($z=count($_GET))-1-$k-$l?:$h+=$c; # make the diagonal sum right to left
  }
  $o[]=[-1=>$y]+$r+[$z=>$y]; # add to result array the actual row with sum of both sides
}
$o[]=[-1=>$h]+$x+[$z=>$d]; # add to result array the last array
print_r([-1=>[-1=>$d]+$x+[$z=>$h]]+$o); #output after adding the first array to the result array
Jörg Hülsermann
sumber
2

Python 3 , 125 byte

from numpy import*
f=lambda m,t=trace,s=sum:c_[r_[t(m),s(m,1),t(m[::-1])],c_[s(m,0),m.T,s(m,0)].T,r_[t(m[::-1]),s(m,1),t(m)]]

Cobalah online!

Sedikit tidak berbulu:

import numpy as np

def f_expanded(m):
    return np.c_[np.r_[np.trace(m), np.sum(m, 1), np.trace(m[::-1])],
                 np.c_[np.sum(m, 0), m.T, np.sum(m, 0)].T,
                 np.r_[np.trace(m[::-1]), np.sum(m, 1), np.trace(m)]]

Ini mengambil input yang diformat sebagai array numpy, kemudian menggunakan alat np.c_dan np.r_pengindeksan untuk membangun array baru sekaligus. np.tracedan np.sumdigunakan untuk menghitung jumlah sepanjang diagonal dan di tempat lain, masing-masing. Tdigunakan untuk mengambil transpos sebelum dan sesudah menggabungkan jumlah karena lebih pendek daripada membuat semua array 2-dimensi dan menggunakan np.r_. m[::-1]menyimpan byte jika dibandingkan dengan rot90(m)ataufliplr(m) untuk menemukan jejak untuk diagonal kedua.

EFT
sumber
Jawaban bagus! Selamat datang di situs :)
DJMcMayhem
1

JavaScript (ES6), 170 byte

(a,m=g=>a.map((_,i)=>g(i)),s=x=>eval(x.join`+`))=>[[d=s(m(i=>a[i][i])),...c=m(i=>s(m(j=>a[j][i]))),g=s(m(i=>a[i][a.length-i-1]))],...a.map(b=>[r=s(b),...b,r]),[g,...c,d]]

Input dan output adalah array angka 2D.

Dijelaskan

(a,                             // input matrix: a
    m=g=>a.map((_,i)=>g(i)),    // helper func m: map by index
    s=x=>eval(x.join`+`)        // helper func s: array sum
) =>
[
    [
        d = s(m(i=>a[i][i])),           // diagonal sum: d
        ...c=m(i=>s(m(j=>a[j][i]))),    // column sums: c
        g = s(m(i=>a[i][a.length-i-1])) // antidiagonal sum: g
    ],
    ...a.map(b=>[r = s(b), ...b, r]),   // all rows with row sums on each end
    [g, ...c, d]                        // same as top row, with corners flipped
]

Cuplikan Tes

Input / output telah diformat dengan baris dan tab baru.

f=
(a,m=g=>a.map((_,i)=>g(i)),s=x=>eval(x.join`+`))=>[[d=s(m(i=>a[i][i])),...c=m(i=>s(m(j=>a[j][i]))),g=s(m(i=>a[i][a.length-i-1]))],...a.map(b=>[r=s(b),...b,r]),[g,...c,d]]

let tests=[[[0]],[[1,5],[0,2]],[[17,24,1,8,15],[23,5,7,14,16],[4,6,13,20,22],[10,12,19,21,3],[11,18,25,2,9]],[[15,1,2,12],[4,10,9,7],[8,6,5,11],[3,13,14,0]]];
<select id=S oninput="I.value=S.selectedIndex?tests[S.value-1].map(s=>s.join`\t`).join`\n`:''"><option>Tests<option>1<option>2<option>3<option>4</select> <button onclick="O.innerHTML=I.value.trim()?f(I.value.split`\n`.map(s=>s.trim().split(/\s+/g))).map(s=>s.join`\t`).join`\n`:''">Run</button><br><textarea rows=6 cols=50 id=I></textarea><pre id=O>

Justin Mariner
sumber
0

LOGO , 198 byte

to g :v[:h reduce "+ :v]
op(se :h :v :h)
end
to f :s[:a reduce "+ map[item # ?]:s][:b reduce "+ map[item # reverse ?]:s][:c apply "map se "sum :s]
op `[[,:a ,@:c ,:b],@[map "g :s][,:b ,@:c ,:a]]
end

Fungsi fmengambil dalam matriks sebagai daftar 2D, kemudian mengeluarkan matriks yang dihasilkan. gadalah fungsi pembantu.

pengguna202729
sumber