Zigzagify a Matrix
J, 31 30 14 12 11 bytes
[:;<@|.`</.
Ych. Too big.
Takes a matrix as input.
Explanation
J has an advantage here. There's a command called oblique (/.
) which takes the oblique lines in turn and applies a verb to them. In this case I'm using a gerund to apply two verbs alternately: <
(box) and <@|.
(reverse and box). Then it's just a matter of unboxing everything using ;
(raze).
Jelly, 24 19 15 13 11 bytes
pS€żị"¥pỤị⁵
Takes number of rows, number of columns and a flat list as separate command-line arguments.
Try it online!
How it works
pS€żị"¥pỤị⁵ Main link. Argument: m (rows), n (columns), A (list, flat)
p Compute the Cartesian product [1, ..., m] × [1, ..., n]. This yields
the indices of the matrix M, i.e., [[1, 1], [1, 2], ..., [m, n]].
S€ Compute the sums of all index pairs.
p Yield the Cartesian product.
¥ Dyadic chain. Arguments: Sums, Cartesian product.
ị" For each index pair in the Cartesian product, retrieve the coordinate
at the index of its sum, i.e., map [i, j] to i if i + j is odd and to
j if i + j is even.
ż Zip the sums with the retrieved indices.
Ụ Sort [1, ..., mn] by the corresponding item in the resulting list.
ị⁵ Retrieve the corresponding items from A.
Pyth, 24 23 21 20 19 18 17 bytes
ssm_W=!Td.T+LaYkQ
Alternate 17-byte version: ssuL_G=!T.T+LaYkQ
Q input
+L prepend to each subarray...
aYk (Y += ''). Y is initialized to [], so this prepends [''] to
the first subarray, ['', ''] to the second, etc.
['' 1 2 3 4
'' '' 5 6 7 8
'' '' '' 9 1 2 3]
.T transpose, giving us
['' '' ''
1 '' ''
2 5 ''
3 6 9
4 7 1
8 2
3]
m_W=!Td black magic
s join subarrays together
s join *everything* on empty string (which means ''s used for
padding disappear)
Thanks to @FryAmTheEggman for a byte, @Jakube for 2 bytes, and @isaacg for a byte!
Explanation of "black magic" alluded to above: m_W=!Td
essentially reverses every other subarray. It does this by mapping _W=!T
over each subarray; W
is conditional application, so it _
s (reverses) all subarrays where =!T
is true. T
is a variable preinitialized to ten (truthy), and =!T
means (T = !T)
. So it toggles the value of a variable that starts out truthy and returns the new value, which means that it will alternate between returning falsy, truthy, falsy, truthy... (credit to Jakube for this idea)
Test suite here.