15
\$\begingroup\$

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

I will follow the tradition of selecting the shortest working code as the best answer

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

17 Answers 17

7
\$\begingroup\$

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)
\$\endgroup\$
6
\$\begingroup\$

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!

Original version:

(($_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!

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

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.
\$\endgroup\$
3
\$\begingroup\$

Wolfram Language (Mathematica), 55 bytes

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

Try it online!

\$\endgroup\$
3
\$\begingroup\$

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!

\$\endgroup\$
2
\$\begingroup\$

APL+WIN, 30 bytes

Prompts for screen input of a 2d array

((↑⍴m)⍴¯1 1)⌽((1↓⍴m)⍴¯1 1)⊖m←⎕
\$\endgroup\$
2
\$\begingroup\$

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 ⍵.
\$\endgroup\$
0
2
\$\begingroup\$

APL (Dyalog Unicode), 15 bytes (SBCS)

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

Try it online!

\$\endgroup\$
0
2
\$\begingroup\$

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

\$\endgroup\$
2
\$\begingroup\$

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.
\$\endgroup\$
2
\$\begingroup\$

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
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6),  116  76 bytes

m=>(g=m=>m[0].map((_,x)=>m.map(_=>m[y++%h][x],h=m.length,y=x&1||h-1)))(g(m))

Try it online!

Commented

m => (                 // m[] = input matrix
  g = m =>             // g is the main helper function taking a matrix m[]
    m[0].map((_, x) => // for each column at position x in m[]:
      m.map(_ =>       //   for each row of m[]:
        m[y++ % h][x], //     yield the x-th value of the row (y mod h) and increment y
        h = m.length,  //     h = number of rows
        y = x & 1      //     start with y = 1 if x is odd,
            || h - 1   //     or h - 1 if x is even
      )                //   end of inner map()
  )                    // end of outer map()
)(g(m))                // invoke g twice on the input matrix
\$\endgroup\$
1
\$\begingroup\$

Jelly, 10 bytes

ZJ-*ṙ"@Zµ⁺

Try it online!

\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$
1
0
\$\begingroup\$

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
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.