Alternatively shift columns and rows of a 2D array

Objective

Given a 2D array of any size, write a program or function to shift alternatively the columns and rows

Example

a b c d e
f g h i j
k l m n o


All elements in the first column shift down one row, the second column shift up one row, the third shift down one row and so on, wrapping when they reach the edge.

k g m i o
a l c n e
f b h d j


All elements in the first row shift to the right, the second to to the left, the third to the right etc., wrapping when they reach the edge.

o k g m i
l c n e a
j f b h d


• Can the array be any size, or specifically 3x5? – Jo King Jan 19 '18 at 10:43
• i was looking for any filled 2D array. sorry for not mentioning it. Ill add an edit – Karan Shishoo Jan 19 '18 at 10:44
• To be honest, the improper formatting makes the question look as if it was an off-topic question from a lazy SO user. – user202729 Jan 19 '18 at 10:52
• (BTW, don't accept an answer too soon) – user202729 Jan 19 '18 at 10:53
• @kshishoo For future challenges you can use the Sandbox to check for duplicates and/or gather some feedback before posting on main site – Rod Jan 19 '18 at 11:21

Husk, 7 bytes

‼ozṙİ_T


Try it online!

Explanation

‼ozṙİ_T  Implicit input: a list of lists.
‼        Do this twice:
T   Transpose,
oz       then zip with
İ_    the infinite list [-1,1,-1,1,-1,1,..
ṙ      using rotation. This rotates the rows in alternating directions.


MATL, 13 bytes

,!tZy:oEq2&YS


Try it online!

Explanation

,        % Do twice
!      %   Transpose. Takes input implicitly the first time
t      %   Duplicate
Zy     %   Size. Gives a vector with numbers of rows and of columns
:      %   Range from 1 to the first entry of the vector (number of rows)
o      %   Parity: gives 0 or 1 for eacn entry
Eq     %   Times 2, minus 1: transforms 0 into -1
2      %   Push 2
&YS    %   Circularly shift along the second dimension. This shifts the
%   first row by 1 (that is, to the right), the second by -1 (to
%   the left), etc.
% End (implicit). Display (implicit)


J, 26, 21 19 bytes

-5 bytes thanks to miles

(|."_1~_1^#\)@|:^:2


Explanation:

^:2 - repeate twice the following:

@|: - transpose and

#\ - find the length ot the prefixes (1, 2, 3 ... rows)

_1^ - raise -1 to the above powers, creating a list of alternating -1 1 -1 1...

|."_1~ - rotate each row of the input array with offset from the above list

Try it online!

(($_1 1"0)@#|."0 1])@|:^:2  How it works ^:2 - repeate twice the following: |: - transpose and |."0 1] - rotate each row of the input array, offsets in the list: @# - the number of rows in the array ($_1 1"0) - alternate _1 1 (3 -> _1 1 _1)

Try it online!

• You can generate the _1 1.. using (|."_1~_1^2|#\)@|:^:2 also – miles Jan 19 '18 at 12:57
• @miles Thanks, that's a great piece of code! – Galen Ivanov Jan 19 '18 at 13:51
• @miles in fact I don't need the 2| part – Galen Ivanov Jan 19 '18 at 13:59
• Yes, you actually don't, that's another 2 bytes saved. – miles Jan 20 '18 at 8:01

Wolfram Language (Mathematica), 55 bytes

Nest[MapIndexed[RotateLeft[#,(-1)^#2]&,Thread@#]&,#,2]&


Try it online!

Python 2, 83 bytes

x=input()
exec'x=[l[i%2*2-1:]+l[:i%2*2-1]for i,l in enumerate(zip(*x))];'*2
print x


Try it online!

Pyth, 15 bytes

L.e.>b^_1k.Tbyy


Try it online

Explanation

L.e.>b^_1k.Tbyy
L           b      Define a function on a list...
.T       ... which transposes it...
.e.>b^_1k         ... and rotates each row alternating left and right.
yyQ   Apply twice to the (implicit) input array.


APL+WIN, 30 bytes

Prompts for screen input of a 2d array

((↑⍴m)⍴¯1 1)⌽((1↓⍴m)⍴¯1 1)⊖m←⎕


JavaScript (ES6), 116 bytes

a=>(g=(a,s,w=(s||a).length)=>a.map((r,y)=>r.map((_,x)=>a[s?y:(x&1?y+1:y-1+w)%w][s?(y&1?x+1:x-1+w)%w:x])))(g(a),a[0])


Demo

let f =

a=>(g=(a,s,w=(s||a).length)=>a.map((r,y)=>r.map((_,x)=>a[s?y:(x&1?y+1:y-1+w)%w][s?(y&1?x+1:x-1+w)%w:x])))(g(a),a[0])

console.log(f([
['a','b','c','d','e'],
['f','g','h','i','j'],
['k','l','m','n','o']
]).join('\n'))

Jelly, 10 bytes

ZJ-*ṙ"@Zµ⁺


Try it online!

APL (Dyalog Unicode), 26 bytes

{(¯1 1⍴⍨≢⍵)⌽(¯1 1⍴⍨≢⍉⍵)⊖⍵}


Try it online!

Prefix Dfn.

How?

{(¯1 1⍴⍨≢⍵)⌽(¯1 1⍴⍨≢⍉⍵)⊖⍵}⍝ Main function, prefix. Input matrix is ⍵.
⊖⍵}⍝ Rotate the columns of ⍵ according to the left arg:
(       ⍉⍵)    ⍝ Transpose ⍵ (makes a 3x5 matrix become 5x3)
≢       ⍝ Tally (yields the number of rows of the matrix)
⍨        ⍝ Swap arguments of the following fn/op
⍴         ⍝ Shape
¯1 1          ⍝ This vector. This yields a vector of ¯1 1 with size = number of columns of ⍵.
⌽                ⍝ Rotate the rows of ⍵ according to the left arg:
{(¯1 1⍴⍨≢⍵)                ⍝ Does the same as the preceding expression, without transposing ⍵.


APL (Dyalog Unicode), 15 bytes (SBCS)

{⍵⌽⍨¯1*⍳≢⍵}∘⍉⍣2


Try it online!

JavaScript (ES6), 94 91 bytes

a=>(g=a=>a[0].map((_,i)=>(b=a.map(a=>a[i]),i%2?[...b.slice(1),b[0]]:[b.pop(),...b])))(g(a))


There's probably a golfier way to do the rotation...

Clean, 93 bytes

import StdEnv,StdLib
k=[0,1:k]
^l=[[[last a:init a],tl a++[hd a]]!!b\\a<-transpose l&b<-k]

^o^


As a partial function literal, that happens to look like a face.

Try it online!

q/kdb+, 32 bytes

Solution:

{rotate'[#:[x+:]#-1 1](+)x}/[2;]


Example:

q)3 5#.Q.a / reshape "a..o" into 3 row, 5 column grid
"abcde"
"fghij"
"klmno"
q){rotate'[#:[(+)x]#-1 1](+)x}/[2;]3 5#.Q.a
"okgmi"
"lcnea"
"jfbhd"


Explanation:

Flip the grid in order to apply rotation to columns, the second iteration flips once again thus the rotation is applied to the rows on the second pass.

Rotation is based a the list -1 1 -1 1.. of the length of the row/column being rotated.

A healthy 9 bytes have been golfed off from this easier-to-read version

{rotate'[count[flip x]#-1 1;flip x]}/[2;] / ungolfed solution
{                                  }/[2;] / perform lambda 2 times
rotate'[                  ;      ]       / perform rotate on each-both
flip x        / flip x<->y of grid
#-1 1               / take from list -1 1
count[flip x]                    / the length of the flipped grid


05AB1E, 14 bytes

2FøvyNÉiÀëÁ}})


Try it online!

Explanation

2F               # 2 times do:
ø              # zip
vy            # for each row(y), index(N) do:
NÉiÀ        # if N is odd, rotate left
ëÁ      # else rotate right
}}    # end if and inner loop
)   # wrap in list


APL NARS, 36 bytes, 18 chars

c←b∘b←{⍵⌽⍨-×-\⍳≢⍵}∘⍉


This {⍵⌽⍨-×-\⍳≢⍵} would rotate each row of the matrix argument follow the vector -1 1 -1 1 etc(that has its vector length the length of the argument matrix rows). Test:

  ⎕←a←3 5⍴⎕A
ABCDE
FGHIJ
KLMNO
⎕←c a
OKGMI
LCNEA
JFBHD


bash et al, 84

Non-competing shell solution.

This is based around a function that alternates the direction of the rotation of the rows. The same procedure done on the transposed array will rotate the columns. For example transpose | rotate | transpose | rotate.

The alternating rotation can be done on single character arrays with sed like this:

sed -E 's/(.*) (.)$/\2 \1/; n; s/^(.) (.*)/\2 \1/'  The transposition can be done with rs or datamash: rs -g1 -T datamash -t' ' transpose  Taken together: r() { sed -E 's/(.*) (.)$/\2 \1/; n; s/^(.) (.*)/\2 \1/'; }
t() { rs -g1 -T; }
<f t | r | t | r


Output:

o k g m i
l c n e a
j f b h d