| Bytes | Lang | Time | Link |
|---|---|---|---|
| 140 | Julia | 250616T192835Z | Sort of |
| 328 | Python3 | 250616T155322Z | Ajax1234 |
| 060 | APL Dyalog | 171015T213542Z | Adá |
| 158 | Python | 171011T063532Z | KSab |
| 059 | Dyalog APL | 171013T110239Z | Uriel |
| 021 | Jelly | 171015T171646Z | Dennis |
| 113 | JavaScript | 171011T065815Z | tsh |
Julia, 140 bytes
!X=begin
n=size(X,1)
c=n÷2+1
for j in 1:4
X=rotr90(X)
for i in 1:c-1
b=i+1:n-i
X[i+1,b].+=X[i,b]
X[i,b].=-1
end
end
filter(a->a>=0,X[:])end
Lots of features of Julia made this an attractive problem to try. Matrix rotation is built in (rotr90), so we can just repeat one accumulation step four times, once for each side of the matrix. The X[:] on the last line dumps X as a vector in column major order, and filter makes for a compact way to drop off-diagonal elements.
As a fun easter egg, mutating functions in Julia are usually denoted by adding a ! to the end of the function name (e.g. fill returns a new array but fill! modifies an existing one in-place). Overloading unary operators is a standard golf trick in Julia, so overloading ! for this mutating function made me happy.
Python3, 328 bytes
def f(b):
B,L=[*zip(*b)],len(b)
for x in range(L):
for y in range(L):
if x==y or x==L-y-1:b[x][y]+=sum(b[x][:y])*(y<=L//2)+sum(b[x][y+1:])*(y>=L//2)+sum(B[y][:x])*(x<=L//2)+sum(B[y][x+1:])*(x>=L//2)
return[j for i,a in enumerate(zip(*b))for j in[a[i-L*(i>=L//2)],a[L-1-i-L*(i>=L//2)]][:[2,1][i==L//2]][::[1,-1][i>L//2]]]
APL (Dyalog), 60 bytes*
In collaboration with my colleague Marshall.
Anonymous prefix lambda. Takes matrix as argument and returns vector. Assumes ⎕IO (Index Origin) to be zero, which is default on many systems.
{(,⍉{+/,(s×-×⍺)↓⍵×i∊¨⍨s←⌊⊃r÷2}⌺r⊢⍵)/⍨,(⊢∨⌽)=/¨i←⍳r←⍴⍵}
{…} anonymous lambda; ⍵ is right argument (as rightmost letter of the Greek alphabet):
⍴⍵ shape of the argument (list of two identical elements)
r← store as r (as in rho)
⍳ all ɩndices of an array of that size, i.e. (0 0),(0 1)…
i← store in i (as in iota)
=/¨ Boolean where the coordinates are equal (i.e. the diagonal)
(…) apply this anonymous tacit prefix function:
⌽ reverse the argument
⊢∨ OR that with the unmodified argument
, ravel (straighten into simple list)
We now have a Boolean mask for the diagonals.
(…)/⍨ use that to filter the following:
⊢⍵ yield (to separate from r) the argument
{…}⌺r call the following anonymous infix lambda on each element, with the r-neighbourhood (padded with zeros as needed) as right argument (⍵), and a two element list of number padded rows,columns (negative for bottom/right, zero for none) as left argument (⍺):
r÷2 divide r with two
⊃ pick the first element (they are identical)
⌊ floor it
s← store as s (for shape)
i∊⍨¨ for each element of i, Boolean if s is a member thereof
⍵× multiply the neighbourhood therewith
(…)↓ drop the following number of rows and columns (negative for bottom/right):
×⍺ signum of the left argument (i.e. the direction of paddings)
- negate
s× multiply s therewith
, ravel (straighten into list)
+/ sum (plus reduction)
Now we have full matrix of sums, but we need to filter all the values read columnwise.
⍉ transpose
, ravel (straighten into simple list)
* By counting ⌺ as ⎕U233A . Try it online!
Python, 159 158 bytes
def f(m):l=len(m)-1;r=range(1,l);return m[0][::l]+f([[sum(m[x][1%y*y:(y>l-2)-~y])+m[0][y]*(x<2)+m[l][y]*(x>l-2)for y in r]for x in r])+m[l][::l]if l else m[0]
Dyalog APL, 101 99 64 62 59 bytes
{+/∘,¨⍵∘רd∘=¨k[⍋k←↑∪/,d←∘.((+/1x×××⌊/∘|),)⍨(⍳x)-⌈.5×x←≢⍵]}
Using Dennis' awesome algorithm.
Jelly, 25 23 21 bytes
AṂ×ṠṚ
LHŒRṗ2Ç€ḅLĠịFS€
Alternate version, 19 bytes
AṂ×ṠṚ
LHŒRṗ2Ç€ĠịFS€
This didn't use to work because Ġ behaved improperly for nested arrays. The only difference is that the pairs [q, p] mentioned in How it works are sorted lexicographically instead of mapping them to p + nq before sorting.
Background
We start by replacing its elements with coordinates, increasing leftwards and downwards and placing (0, 0) in the center of the matrix.
For a 7x7 matrix M, we get the following coordinates.
(-3,-3) (-3,-2) (-3,-1) (-3, 0) (-3, 1) (-3, 2) (-3, 3)
(-2,-3) (-2,-2) (-2,-1) (-2, 0) (-2, 1) (-2, 2) (-2, 3)
(-1,-3) (-1,-2) (-1,-1) (-1, 0) (-1, 1) (-1, 2) (-1, 3)
( 0,-3) ( 0,-2) ( 0,-1) ( 0, 0) ( 0, 1) ( 0, 2) ( 0, 3)
( 1,-3) ( 1,-2) ( 1,-1) ( 1, 0) ( 1, 1) ( 1, 2) ( 1, 3)
( 2,-3) ( 2,-2) ( 2,-1) ( 2, 0) ( 2, 1) ( 2, 2) ( 2, 3)
( 3,-3) ( 3,-2) ( 3,-1) ( 3, 0) ( 3, 1) ( 3, 2) ( 3, 3)
We now compute the minimum absolute value of each coordinate pair and multiply the signs of both coordinate by it, mapping (i, j) to (sign(i)m, sign(j)m), where m = min(|i|, |j|).
(-3,-3) (-2,-2) (-1,-1) ( 0, 0) (-1, 1) (-2, 2) (-3, 3)
(-2,-2) (-2,-2) (-1,-1) ( 0, 0) (-1, 1) (-2, 2) (-2, 2)
(-1,-1) (-1,-1) (-1,-1) ( 0, 0) (-1, 1) (-1, 1) (-1, 1)
( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0)
( 1,-1) ( 1,-1) ( 1,-1) ( 0, 0) ( 1, 1) ( 1, 1) ( 1, 1)
( 2,-2) ( 2,-2) ( 1,-1) ( 0, 0) ( 1, 1) ( 2, 2) ( 2, 2)
( 3,-3) ( 2,-2) ( 1,-1) ( 0, 0) ( 1, 1) ( 2, 2) ( 3, 3)
Matrix elements that correspond to the same pair have to be summed. To determine the order of the sums, we map each pair (p, q) to p + nq, where n is the number of rows/columns of M.
-24 -16 -8 0 6 12 18
-16 -16 -8 0 6 12 12
-8 -8 -8 0 6 6 6
0 0 0 0 0 0 0
-6 -6 -6 0 8 8 8
-12 -12 -6 0 8 16 16
-18 -12 -6 0 8 16 24
The order of sums corresponds to the order of integers the correspond to its summands.
How it works
LHŒRṗ2Ç€ḅLĠịFS€ Main link. Argument: M (matrix)
L Compute n, the length (number of rows) of M.
H Halve it.
ŒR Symmetric range; map t to [-int(t), ..., 0, int(t)].
ṗ2 Compute the second Cartesian power, yielding all pairs [i, j]
with -t ≤ i, j ≤ t.
Ç€ Map the helper link over the resulting array of pairs.
L Yield n.
ḅ Unbase; map each pair [q, p] to (p + nq).
Ġ Group the indices of the resulting array of n² integers by their
corresponding values, ordering the groups by the values.
F Flatten M.
ị Index into the serialized matrix.
S€ Compute the sum of each group.
AṂ×ṠṚ Helper link. Argument: [i, j] (index pair)
A Absolute value; yield [|i|, |j|].
Ṃ Minimum; yield m := min(|i|, |j|).
Ṡ Sign; yield [sign(i), sign(j)].
× Multiply; yield [p, q] := [sign(i)m, sign(j)m].
Ṛ Reverse; yield [q, p].
JavaScript, 113 bytes
s=>(l=s.length-1,a=[],s.map((v,y)=>v.map((n,x)=>a[q=2*[x,y,l-y].sort((u,v)=>u-v)[1]+(y>l/2),q-=q>l]=~~a[q]+n)),a)
f=
s=>(l=s.length-1,a=[],s.map((v,y)=>v.map((n,x)=>a[q=2*[x,y,l-y].sort((u,v)=>u-v)[1]+(y>l/2),q-=q>l]=~~a[q]+n)),a)
<p><textarea id="i" style="width: 400px; height: 120px">1 2 3 2 1
0 3 2 3 0
4 2 5 6 3
7 4 7 9 4
0 6 7 2 5</textarea></p>
<p><button onclick="o.value=f(i.value.trim().split`\n`.map(l=>l.trim().split(/\s+/).map(v => parseInt(v,10)))).join` `">Run</button></p>
<p><output id="o"></output></p>