Fülle eine Matrix mit ihren Summen auf


23

Herausforderung:

Füllen Sie die Matrix mit einer quadratischen Eingangsmatrix A auf allen vier Seiten mit einer Zeile und einer Spalte auf.

  • Der Wert jedes Elements in der oberen und unteren Zeile sollte die Summe der Elemente in jeder entsprechenden Spalte sein.
  • Der Wert jedes Elements in der linken und rechten Spalte sollte die Summe der Elemente in jeder entsprechenden Zeile sein.
  • Der Wert der Elemente in der oberen linken und unteren rechten Ecke sollte die Summe der Elemente in der Diagonale sein
  • Der Wert der Elemente in der oberen rechten und unteren linken Ecke sollte die Summe der Elemente in der Antidiagonale sein.

Beispiel:

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

Erläuterung:

Die Elemente oben links und unten rechts sind die Summe der Diagonalen 1 + 2 + 5 = 8 . Die Elemente oben rechts und unten links sind die Summe der Antidiagonalen 2 + 2 + 3 = 7 .

Die obere und untere Reihe (mit Ausnahme der Ecken) ist die Summe der Spalten in A : 1 + 3 + 2 = 6 , 5 + 2 + 5 = 12 und 3 + 4 + 5 = 12 . In ähnlicher Weise sind die linke und rechte Spalte (mit Ausnahme der Ecken) die Summe jeder der Reihen von A : 1 + 5 + 3 = 9 , 3 + 2 + 4 = 9 und 2 + 5 + 5 = 12 .

Eingang:

  • Eine nicht leere quadratische Matrix mit nicht negativen ganzen Zahlen.
  • Optionales Format

Ausgabe:

  • Die Matrix wird wie oben beschrieben aufgefüllt
  • Optionales Format, muss jedoch mit dem Eingabeformat identisch sein

Testfälle:

Verwenden Sie die Übermittlungen in dieser Challenge, wenn Sie das Eingabeformat (zum Beispiel [[1, 5],[0, 2]]) in ein geeigneteres Format konvertieren möchten .

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

Das ist , also gewinnt die kürzeste Lösung in jeder Sprache . Erklärungen sind ausdrücklich erwünscht.


2
Ist das, um magische Quadrate zu überprüfen?
mdahmoune

Nur zu überprüfen ist ein bisschen einfacher, aber es ist in der Tat leicht zu erkennen, ob ein Quadrat auf diese Weise magisch ist, ja :-)
Stewie Griffin

Antworten:


5

Oktave , 64 Bytes

Vielen Dank an Tom Carpenter für das Speichern von 4 Bytes und das Korrigieren eines Fehlers, den ich im Originalcode hatte!

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

Probieren Sie es online!

Erläuterung:

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

Beachten Sie, dass ich das geschrieben habe, lange nachdem ich die Herausforderung gepostet habe.



4

MATL , 27 26 Bytes

,!tXswyv]GXds5L(PGPXds5L(P

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Erläuterung

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

Natürlich ist MATL so konzipiert, dass es mit anderen Matrizen als Jelly arbeitet. > _>
Erik der Outgolfer

@EriktheOutgolfer Aber deine Antwort hat mehr Euro!
Luis Mendo

3
Ja, es hat Euro, Dollar und Yen ... das ist hier leider nicht das Gewinnkriterium. D:
Erik der Outgolfer

3

APL (Dyalog) , 37 Bytes

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

Probieren Sie es online!

1 1∘⍉ diagonal (beide Achsen in eine zusammenfalten)

d← Speichern Sie diese Funktion als d und wenden Sie sie auf das Argument an

+⌿ Stellen Sie die Spaltensummen voran

d∘⌽, voranstellen d auf das umgekehrte Argument angewendet

()⍪ Legen Sie folgendes aufeinander:

+/,⊢,+/ Zeilensummen, das unveränderte Argument Zeilensummen

()⍪ Legen Sie folgendes aufeinander:

d,+⌿,d∘⌽ angewendet auf das Argument, Spaltensummen, d angewendet auf das umgekehrte Argument


3

Gelee , 26 Bytes

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

Probieren Sie es online!

Sieht überraschend anders aus als Eriks Lösung .

Ich habe es endlich geschafft zu verstehen, wie es ¦funktioniert (durch Debuggen von Jellys Code, lol). Schade, dass es in meinem Fall eines erfordert, um damit zu arbeiten Ç.

Erläuterung

Der Code verwendet drei Links. Der erste Hilfslink füllt einen Vektor mit seiner Summe an beiden Enden auf, der zweite Hilfslink fixiert zwei Ecken der Matrix und der Hauptlink ruft diese entsprechend auf.

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

Dies ist der Vorschlag von @LeakyNun, der 54 Bytes einspart . Ich habe es dann selbst ein bisschen golfen.

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]

Probieren Sie es online!

Anfangslösung - Python 3 , 216 Bytes

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

Probieren Sie es online!



@LeakyNun Danke. Wurde gerade mit ~ 190 Bytes aktualisiert, das ist viel kürzer: P
Mr. Xcoder

2

Python 2 , 268 250 184 174 Bytes

10 Dank an 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()

Probieren Sie es online!

Einige Erklärungen Die Eingabe wird als Matrix hochgeladen. Zuerst berechnet der Code die Summe jeder Spalte und jeder Zeile mit numpy.sum. Dann berechnet es die Summe der Diagonalen mit numpy.trace. Danach erhält es die andere Diagonale, indem es die Matrix von links nach rechts dreht. Schließlich werden numpy.vstack und numpy.hstack verwendet, um die Teile zusammenzukleben.


@StewieGriffin Ok, ich habe gerade den Code aktualisiert :)
mdahmoune

1
Ich glaube, das funktioniert für 174 tio.run/…
Stewie Griffin

2

R, 129 Bytes

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

Eine anonyme Funktion, die eine quadratische Matrix als Eingabe verwendet. Ich werde eine Erklärung posten, wenn Interesse besteht.


2

PHP , 211 Bytes

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

Probieren Sie es online!

Erweitert

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 Bytes

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

Probieren Sie es online!

Leicht ungolfed:

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

Hierbei werden als Numpy-Array formatierte Eingaben verwendet. Anschließend wird mit den Indizierungswerkzeugen np.c_und np.r_ein neues Array in einem Durchgang erstellt . np.traceund np.sumwerden verwendet, um die Summen entlang der Diagonalen bzw. überall sonst zu berechnen.Twird verwendet, um die Transponierung vor und nach dem Verketten der Summen vorzunehmen, da dies kürzer ist, als alle Arrays zweidimensional zu machen und zu verwenden np.r_. m[::-1]Speichert Bytes im Vergleich zu rot90(m)oder fliplr(m)zum Auffinden der Spur für die zweite Diagonale.


Gute Antwort! Willkommen auf der Seite :)
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]]

Ein- und Ausgabe ist ein 2D-Array von Zahlen.

Erklärt

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

Testschnipsel

Die Eingabe / Ausgabe wurde mit Zeilenumbrüchen und Tabulatoren formatiert.

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 Bytes

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

Die Funktion fnimmt eine Matrix als 2D-Liste auf und gibt die resultierende Matrix aus. gist Helferfunktion.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.