Прокладіть матрицю з її сумами


23

Виклик:

З огляду на квадратну вхідну матрицю A , прокладіть матрицю одним рядком та одним стовпцем з усіх чотирьох сторін.

  • Значення кожного елемента у верхньому та нижньому рядку має бути сумою елементів у кожному відповідному стовпчику.
  • Значення кожного елемента в лівому та правому стовпцях має бути сумою елементів у кожному відповідному рядку.
  • Значення елементів у верхньому лівому та правому нижньому кутах має бути сумою елементів по діагоналі
  • Значення елементів у правому верхньому та нижньому лівому куті має бути сумою елементів у діадіаналі.

Приклад:

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

Пояснення:

Лівий верхній і нижній правий елементи - це сума діагоналі 1 + 2 + 5 = 8 . Правий верхній і нижній лівий елементи - це сума антидіагоналі 2 + 2 + 3 = 7 .

Верхній і нижній ряд (крім кутів) - це сума кожного з стовпців у A : 1 + 3 + 2 = 6 , 5 + 2 + 5 = 12 і 3 + 4 + 5 = 12 . Аналогічно, лівий і правий стовпчик (крім кутів) - це сума кожного з рядків A : 1 + 5 + 3 = 9 , 3 + 2 + 4 = 9 і 2 + 5 + 5 = 12 .

Вхід:

  • Непорожня квадратна матриця з невід’ємними цілими числами.
  • Необов’язковий формат

Вихід:

  • Матриця підкладена, як пояснено вище
  • Необов’язковий формат, але він повинен бути таким же, як формат введення

Тестові приклади:

Використовуйте подані в цьому виклику, якщо ви хочете перетворити вхідний формат у більш підходящий (наприклад [[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

Це , тому найкоротше рішення в кожній мові виграє. Пояснення настійно заохочуються.


2
Це перевірити магічні квадрати?
mdahmoune

Просто перевірити це трохи простіше, але насправді легко зрозуміти, чи квадрат таким чином є магічним, так :-)
Стюі Гріффін

Відповіді:


5

Октава , 64 байти

Дякую Тому Карпентеру як за збереження 4-х байт, так і за виправлення помилки в оригінальному коді!

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

Спробуйте в Інтернеті!

Пояснення:

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

Зауважте, я написав це ще довго після того, як виклав виклик.



4

MATL , 27 26 байт

,!tXswyv]GXds5L(PGPXds5L(P

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

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

Звичайно, MATL призначений для роботи з матрицями на відміну від Jelly. > _>
Erik the Outgolfer

@EriktheOutgolfer Але у вашій відповіді є більше євро!
Луїс Мендо

3
Так, це євро доларів і ієн ... на жаль, це не критерій виграшу. Д:
Ерік Аутгольфер

3

APL (Dyalog) , 37 байт

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

Спробуйте в Інтернеті!

1 1∘⍉ по діагоналі (освітлення згортання обох осей в одну)

d← збережіть цю функцію як d та застосуйте її до аргументу

+⌿ додайте суми стовпців

d∘⌽, prepend d застосовано до аргументу, що перевернувся

()⍪ Укладіть наступне зверху:

+/,⊢,+/ рядок сум, немодифікований аргумент, рядкові підсумки

()⍪ Укладіть наступне зверху:

d,+⌿,d∘⌽ застосовано до аргументу, суми стовпців, d застосовано до аргументованого зворотного


3

Желе , 26 байт

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

Спробуйте в Інтернеті!

Виглядає напрочуд інакше, ніж рішення Еріка .

Нарешті мені вдалося зрозуміти, як ¦працює (налагоджуючи код Jelly, lol). Шкода, що з цим потрібно працюватиÇ в моєму випадку .

Пояснення

У коді використовуються три посилання. Перша допоміжна ланка прокладає вектор з його сумою на обох кінцях, друга допоміжна ланка фіксує два кути матриці, а головна ланка викликає їх відповідним чином.

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

Пітон 3 , 155 байт

Це пропозиція @LeakyNun, яка зберігає 54 байти . Потім я трохи полював це в гольф.

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]

Спробуйте в Інтернеті!

Початкове рішення - Python 3 , 216 байт

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

Спробуйте в Інтернеті!



@LeakyNun Дякую Щойно оновлено ~ 190 байт, це значно коротше: P
Містер Xcoder

2

Пітон 2 , 268 250 184 174 байт

10 завдяки Стюі Гріффін

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

Спробуйте в Інтернеті!

Деякі пояснення Вхід завантажується у вигляді матриці. Спочатку код обчислює суму кожного стовпця та кожного рядка, використовуючи numpy.sum. Потім він обчислює суму діагоналі шляхом numpy.trace. Після цього він отримує іншу діагональ, зробивши ліворуч праворуч переворот на матрицю. Нарешті, він використовує numpy.vstack і numpy.hstack, щоб склеїти шматки разом.


@StewieGriffin Добре, я щойно оновив код :)
mdahmoune

1
Я вважаю, що це працює для 174 tio.run/…
Гріффін

2

R, 129 байт

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

Анонімна функція, яка приймає квадратну матрицю як вхідний. Я викладу пояснення, якщо є інтерес.


2

PHP , 211 байт

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

Спробуйте в Інтернеті!

Розширено

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 байт

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

Спробуйте в Інтернеті!

Трохи незворушений:

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

Це приймає вхід, відформатований як масив numpy, а потім використовує інструменти np.c_та np.r_індексацію для створення нового масиву за один раз. np.traceі np.sumвикористовуються для обчислення сум відповідно по діагоналях та скрізь, відповідно. Tвикористовується для отримання транспозиції до і після об'єднання сум, оскільки це коротше, ніж зробити всі масиви двовимірними та використовувати np.r_. m[::-1]зберігає байти в порівнянні з rot90(m)або fliplr(m)для пошуку сліду для другої діагоналі.


Гарна відповідь! Ласкаво просимо на сайт :)
DJMcMayhem

1

JavaScript (ES6), 170 байт

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

Вхід і вихід - це 2D масив чисел.

Пояснив

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

Тест-фрагмент

Введення / вихід форматовано новими рядками та вкладками.

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 байт

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

Функція fприймає матрицю як двовимірний список, після чого виводить отриману матрицю. gє хелперною функцією.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.