Remplissez une matrice avec ses sommes


23

Défi:

Étant donné une matrice d'entrée carrée A , complétez la matrice avec une ligne et une colonne sur les quatre côtés.

  • La valeur de chaque élément de la ligne supérieure et inférieure doit être la somme des éléments de chaque colonne correspondante.
  • La valeur de chaque élément dans la colonne de gauche et de droite doit être la somme des éléments de chaque ligne correspondante.
  • La valeur des éléments en haut à gauche et en bas à droite doit être la somme des éléments sur la diagonale
  • La valeur des éléments en haut à droite et en bas à gauche doit être la somme des éléments dans l'anti-diagonale.

Exemple:

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

Explication:

Les éléments en haut à gauche et en bas à droite sont la somme de la diagonale 1 + 2 + 5 = 8 . Les éléments en haut à droite et en bas à gauche sont la somme de l'anti-diagonale 2 + 2 + 3 = 7 .

Les rangées du haut et du bas (sauf les coins) sont la somme de chacune des colonnes de A : 1 + 3 + 2 = 6 , 5 + 2 + 5 = 12 et 3 + 4 + 5 = 12 . De même, les colonnes gauche et droite (sauf les coins) sont la somme de chacune des lignes de A : 1 + 5 + 3 = 9 , 3 + 2 + 4 = 9 et 2 + 5 + 5 = 12 .

Contribution:

  • Une matrice carrée non vide, avec des entiers non négatifs.
  • Format optionnel

Sortie:

  • La matrice rembourrée comme expliqué ci-dessus
  • Format facultatif, mais il doit être identique au format d'entrée

Cas de test:

Utilisez les soumissions de ce défi si vous souhaitez convertir le format d'entrée en un format plus approprié (par exemple [[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

C'est le , donc la solution la plus courte dans chaque langue l' emporte. Les explications sont fortement encouragées.


2
Est-ce pour vérifier les carrés magiques?
mdahmoune

Le simple contrôle est un peu plus facile, mais il est en effet facile de voir si un carré est magique de cette façon, oui :-)
Stewie Griffin

Réponses:


5

Octave , 64 octets

Merci à Tom Carpenter d'avoir économisé 4 octets et d'avoir corrigé une erreur que j'avais dans le code d'origine!

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

Essayez-le en ligne!

Explication:

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

Remarque, j'ai écrit ceci longtemps après avoir posté le défi.



4

MATL , 27 26 octets

,!tXswyv]GXds5L(PGPXds5L(P

Essayez-le en ligne!Ou vérifiez tous les cas de test .

Explication

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

Bien sûr, MATL est conçu pour fonctionner avec des matrices contrairement à Jelly. > _>
Erik the Outgolfer

@EriktheOutgolfer Mais votre réponse a plus d'euros!
Luis Mendo

3
Oui, il y a des euros et des yens ... malheureusement ce n'est pas le critère gagnant ici. D:
Erik the Outgolfer le

3

APL (Dyalog) , 37 octets

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

Essayez-le en ligne!

1 1∘⍉ diagonale (lit. réduire les deux axes en un)

d← stocker cette fonction comme d et l'appliquer à l'argument

+⌿ ajouter les sommes des colonnes

d∘⌽, ajout de d appliqué à l'argument inversé

()⍪ Empilez les éléments suivants en haut:

+/,⊢,+/ sommes de ligne, l'argument non modifié, sommes de ligne

()⍪ Empilez les éléments suivants en haut:

d,+⌿,d∘⌽ appliqué à l'argument, somme des colonnes, d appliqué à l'argument inversé


3

Gelée , 26 octets

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

Essayez-le en ligne!

Semble étonnamment différent de la solution d' Erik .

J'ai finalement réussi à comprendre comment ça ¦marche (en déboguant à travers le code de Jelly, lol). Dommage qu'il nécessite un pour travailler avecÇ dans mon cas.

Explication

Le code utilise trois liens. Le premier lien auxiliaire remplit un vecteur avec sa somme aux deux extrémités, le deuxième lien auxiliaire fixe les deux coins de la matrice et le lien principal les appelle de manière appropriée.

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

C'est la suggestion de @LeakyNun, qui économise 54 octets . Je l'ai ensuite joué un peu au 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]

Essayez-le en ligne!

Solution initiale - Python 3 , 216 octets

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

Essayez-le en ligne!



@LeakyNun Merci. Je venais de mettre à jour avec ~ 190 octets, c'est beaucoup plus court: P
M. Xcoder

2

Python 2 , 268 250 184 174 octets

10 merci à 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()

Essayez-le en ligne!

Quelques explications L'entrée est téléchargée sous forme de matrice. Tout d'abord, le code calcule la somme de chaque colonne et de chaque ligne à l'aide de numpy.sum. Ensuite, il calcule la somme de la diagonale par numpy.trace. Après cela, il obtient l'autre diagonale en faisant un retournement gauche-droite sur la matrice. Enfin, il utilise numpy.vstack et numpy.hstack pour coller les pièces ensemble.


@StewieGriffin Ok, je viens de mettre à jour le code :)
mdahmoune

1
Je crois que cela fonctionne pour 174 tio.run/…
Stewie Griffin

2

R, 129 octets

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

Une fonction anonyme qui prend une matrice carrée en entrée. Je posterai une explication s'il y a un intérêt.


2

PHP , 211 octets

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

Essayez-le en ligne!

Étendu

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 octets

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

Essayez-le en ligne!

Légèrement non golfé:

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

Cela prend une entrée formatée sous forme de tableau numpy, puis utilise les outils d'indexation np.c_et np.r_pour créer un nouveau tableau en une seule fois. np.traceet np.sumsont utilisés pour calculer les sommes le long des diagonales et partout ailleurs, respectivement. Test utilisé pour prendre la transposition avant et après la concaténation des sommes, car il est plus court que de rendre tous les tableaux bidimensionnels et d'utiliser np.r_. m[::-1]enregistre les octets par rapport à rot90(m)ou fliplr(m)pour trouver la trace de la deuxième diagonale.


Bonne réponse! Bienvenue sur le site :)
DJMcMayhem

1

JavaScript (ES6), 170 octets

(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'entrée et la sortie sont un tableau 2D de nombres.

Expliqué

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

Extrait de test

L'entrée / sortie a été formatée avec des nouvelles lignes et des tabulations.

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 octets

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 fonction fprend une matrice sous forme de liste 2D, puis affiche la matrice résultante. gest la fonction d'assistance.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.