Riempi una matrice con le sue somme


23

Sfida:

Data una matrice di input quadrata A , riempire la matrice con una riga e una colonna su tutti e quattro i lati.

  • Il valore di ciascun elemento nella riga superiore e inferiore dovrebbe essere la somma degli elementi in ciascuna colonna corrispondente.
  • Il valore di ciascun elemento nella colonna sinistra e destra dovrebbe essere la somma degli elementi in ciascuna riga corrispondente.
  • Il valore degli elementi nell'angolo in alto a sinistra e nell'angolo in basso a destra dovrebbe essere la somma degli elementi sulla diagonale
  • Il valore degli elementi nell'angolo in alto a destra e nell'angolo in basso a sinistra dovrebbe essere la somma degli elementi nell'anti-diagonale.

Esempio:

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

Spiegazione:

Gli elementi in alto a sinistra e in basso a destra sono la somma della diagonale 1 + 2 + 5 = 8 . Gli elementi in alto a destra e in basso a sinistra sono la somma dell'anti-diagonale 2 + 2 + 3 = 7 .

La riga superiore e inferiore (tranne gli angoli) sono la somma di ciascuna delle colonne in A : 1 + 3 + 2 = 6 , 5 + 2 + 5 = 12 e 3 + 4 + 5 = 12 . Allo stesso modo, la colonna sinistra e destra (tranne gli angoli) sono la somma di ciascuna delle righe di A : 1 + 5 + 3 = 9 , 3 + 2 + 4 = 9 e 2 + 5 + 5 = 12 .

Ingresso:

  • Una matrice quadrata non vuota, con numeri interi non negativi.
  • Formato opzionale

Produzione:

  • La matrice è imbottita come spiegato sopra
  • Formato opzionale, ma deve essere uguale al formato di input

Casi test:

Utilizzare gli invii in questa sfida se si desidera convertire il formato di input in uno più adatto (ad esempio [[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

Questo è , quindi vince la soluzione più breve in ogni lingua . Le spiegazioni sono fortemente incoraggiate.


2
È per controllare i quadrati magici?
mdahmoune,

Il controllo è un po 'più semplice, ma è davvero facile vedere se un quadrato è magico in questo modo, sì :-)
Stewie Griffin

Risposte:


5

Ottava , 64 byte

Grazie a Tom Carpenter sia per salvare 4 byte, e la correzione di un errore che ho avuto nel codice originale!

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

Provalo online!

Spiegazione:

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

Nota, l'ho scritto molto tempo dopo aver pubblicato la sfida.



4

MATL , 27 26 byte

,!tXswyv]GXds5L(PGPXds5L(P

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

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

Naturalmente MATL è progettato per funzionare con matrici a differenza di Jelly. > _>
Erik the Outgolfer,

@EriktheOutgolfer Ma la tua risposta ha più euro!
Luis Mendo,

3
Sì, ha euro e yen in euro ... purtroppo non è questo il criterio vincente qui. D:
Erik the Outgolfer

3

APL (Dyalog) , 37 byte

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

Provalo online!

1 1∘⍉ diagonale (acceso. comprimi entrambi gli assi in uno)

d← memorizza quella funzione come d e la applica all'argomento

+⌿ anteporre le somme delle colonne

d∘⌽, anteponi d applicato all'argomento invertito

(... )⍪ impila quanto segue in alto:

+/,⊢,+/ somme di riga, argomento non modificato, somme di riga

(... )⍪ impila quanto segue in alto:

d,+⌿,d∘⌽ applicato all'argomento, somme di colonna, d applicato all'argomento invertito


3

Gelatina , 26 byte

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

Provalo online!

Sembra sorprendentemente diverso dalla soluzione di Erik .

Finalmente sono riuscito a capire come ¦funziona (eseguendo il debug tramite il codice di Jelly, lol). Peccato che ci sia bisogno di lavorare con il Çmio caso.

Spiegazione

Il codice utilizza tre collegamenti. Il primo collegamento helper riempie un vettore con la sua somma su entrambe le estremità, il secondo collegamento helper corregge due angoli della matrice e il collegamento principale li chiama in modo appropriato.

Ç€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.

3

Python 3 , 155 byte

Questo è il suggerimento di @LeakyNun, che consente di risparmiare 54 byte . L'ho anche giocato un po 'a golf.

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]

Provalo online!

Soluzione iniziale - 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]])

Provalo online!



@LeakyNun Grazie.
Stavo

2

Python 2 , 268 250 184 174 byte

10 grazie a 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()

Provalo online!

Alcune spiegazioni L'input viene caricato come matrice. Innanzitutto il codice calcola la somma di ogni colonna e di ogni riga usando numpy.sum. Quindi calcola la somma della diagonale per numpy.trace. Dopodiché ottiene l'altra diagonale facendo capovolgere sinistra-destra sulla matrice. Infine, utilizza numpy.vstack e numpy.hstack per incollare i pezzi insieme.


@StewieGriffin Ok, ho appena aggiornato il codice :)
mdahmoune,

1
Credo che questo funzioni
Stewie Griffin il

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

Una funzione anonima che accetta una matrice quadrata come input. Invierò una spiegazione se c'è interesse.


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

Provalo online!

allargato

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

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

Provalo online!

Leggermente non golfato:

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

Questo prende input formattato come un array intorpidito, quindi usa gli strumenti di indicizzazione np.c_e np.r_per creare un nuovo array in una volta sola. np.tracee np.sumsono usati per calcolare le somme lungo le diagonali e ovunque, rispettivamente. Tè usato per prendere la trasposizione prima e dopo la concatenazione delle somme perché è più breve rispetto a rendere tutti gli array bidimensionali e usando np.r_. m[::-1]salva i byte rispetto a rot90(m)o fliplr(m)per trovare la traccia per la seconda diagonale.


Bella risposta! Benvenuti nel sito :)
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]]

L'input e l'output sono una matrice 2D di numeri.

spiegato

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

Test dello snippet

L'input / output è stato formattato con nuove righe e schede.

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>


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

La funzione faccetta una matrice come un elenco 2D, quindi emette la matrice risultante. gè la funzione di aiuto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.