Given a square matrix of characters (single-byte printable ASCII characters), rotate each "ring" of the matrix in opposite directions.

Let's take an example:

1 2 3 4 5
6 7 8 9 A

Then, the outermost ring is rotated clockwise 90 degrees, like so:

1 2 3 4 5    L G B 6 1
6       A    M       2
B       F => N       3
G       K    O       4
L M N O P    P K F A 5

The second ring is rotated counterclockwise 90 degrees:

7 8 9    9 E J
C   E => 8   I
H I J    7 C H

The final ring is rotated clockwise 90 degrees, but since it is a single number (letter in our example), then it is not really affected.

The final result is:

L G B 6 1
M 9 E J 2
N 8 D I 3
O 7 C H 4
P K F A 5

If the matrix has an even side length, the innermost ring will be a 2x2 square and should still be rotated.


A list of lists in any reasonable standard format. For example, a newline-delimited space-delimited string or a list of space-delimited strings is acceptable, but a list of the values as rings around the matrix is not acceptable. The characters are not necessarily unique.


A list of lists in any reasonable standard format. Same rules as the input.

Test Cases

1 2 3    7 4 1
4 5 6 => 8 5 2
7 8 9    9 6 3

1 2 3 4 5 6    Y S M G A 1
A B C D E F    Z E K Q W 2
G H I J K L => ! D O I V 3
M N O P Q R    @ C P J U 4
S T U V W X    # B H N T 5
Y Z ! @ # $    $ X R L F 6


Heavily inspired by a related challenge that rotates each element counterclockwise one position (not by 90 degrees).

  • \$\begingroup\$ Related \$\endgroup\$
    – rahnema1
    Jun 21, 2017 at 18:20
  • \$\begingroup\$ @rahnema1 Right, I remember that post. This post is mostly inspired by that one; I will credit. Thanks! \$\endgroup\$
    – hyper-neutrino
    Jun 21, 2017 at 18:21
  • \$\begingroup\$ @Mr.Xcoder Whoops. You are right, thanks. \$\endgroup\$
    – hyper-neutrino
    Jun 21, 2017 at 18:21
  • \$\begingroup\$ @HyperNeutrino can we take the dimension of the matrix as a part of input? \$\endgroup\$
    – Uriel
    Jun 21, 2017 at 19:20
  • \$\begingroup\$ All characters in your examples are unique. Will this always be the case? \$\endgroup\$
    – Dennis
    Jun 21, 2017 at 19:27

8 Answers 8


Haskell, 94 bytes

An anonymous function taking and returning a list of Strings.

Use as (cycle[t.r,r.t,r.t,r.t]?)["123", "456", "789"].

(g:h)?(a:b)=g$a:h?t(r b)

Try it online!

How it works

  • r is reverse. t is one byte shorter than importing Data.List.transpose. t.r rotates a list of lists 90 degrees clockwise, and r.t rotates it counterclockwise.
  • The operator ? takes two arguments, a list of functions and a matrix as a list of strings.
    • An empty matrix is just returned.
    • Otherwise, ? strips the first function f off the list of functions, and the first line a off the matrix.
    • Then it rotates the remainder b of the matrix clockwise, and recurses with that and the remaining functions. This gradually strips the matrix from the outside in, one ring each four steps.
    • Then it prepends the original line a to the result, and applies the function f to it to adjust the orientation of the matrix.
  • The anonymous function calls ? with the input matrix as a list of strings, and an infinite list of functions, which repeats cyclically every four steps.
    • For most of the steps the function is counterclockwise rotation, which undoes the implicit clockwise rotation done by ? when recursing.
    • However, the first step and every fourth step afterwards is instead clockwise rotation.
      • This function is applied when a ring of the matrix is complete, causing each ring to be 180 degrees rotated with respect to the next one.
      • By luck, this is also the correct transformation to apply to the final, completed matrix to get the final result.

Python 2, 104 bytes

def f(x):l=len(x)-1;r=range(l+1);return[[[x[l-i][j],x[i][l-j]][min(i,j,l-i,l-j)%2]for i in r]for j in r]

Try it online!

x[l-i][j] are the coordenates of a clockwise turn, x[i][l-j] for a counterclowise turn. min(i,j,l-i,l-j)%2 is used to pick the right direction

  • \$\begingroup\$ returning rotations recursively. \$\endgroup\$
    – tuskiomi
    Jun 21, 2017 at 20:10
  • \$\begingroup\$ @tuskiomi hmm?? \$\endgroup\$
    – Rod
    Jun 21, 2017 at 21:35
  • \$\begingroup\$ @tuskiomi I tried a recursive approach in ES6. It was about twice as long as a simple port of this answer... \$\endgroup\$
    – Neil
    Jun 22, 2017 at 12:28

Mathematica, 113 bytes


it is better to input as char string like "E" for special letters like E,I...


[{{1, 2, 3, 4, 5, 6}, {A, B, C, D, "E", F}, {G, H, "I", J, K, L}, {M, N, O, P, Q, R}, {S, T, U, V, W, X}, {Y, Z, "!", "@", "#", "&"}}]


{{Y, S, M, G, A, 1}, {Z, "E", K, Q, W, 2}, {"!", D, O, "I", V, 3}, {"@", C, P, J, U, 4}, {"#", B, H, N, T, 5}, {"&", X, R, L, F, 6}}


Octave, 86 bytes


Try it online!


APL (Dyalog Unicode), 35 bytes (SBCS)

Full program. Prompts for APL matrix expression. Requires 0-based indexing.


Try it online!

m←⎕ prompt for matrix and assign to m

 tally the number of rows in it

ɩndices zero through one less than that

{ apply the following lambda to each element (denoted in the code) of that:

2⍴⍵reshape the index to a two-element list

b← assign to b (for beginning)

- negate that

e← assign to e (for end)

m↓⍨ drop that many (negative, so trailing) rows and columns from m

b↓ drop that many leading rows and columns from that

 flip upside down


(m)← assign to the following sub-array of m:

  e↓ drop the appropriate number of rows and columns from the end (bottom right)

  b↓ drop the appropriate number of rows and columns from the beginning (top left)

m⊣ ignore the pass-through values of all the assignments, in favour of the updated value of m




APL (Dyalog Unicode), 81 bytes


Try it online!

A 2-train which takes the matrix as its right argument.

The idea behind this is to peel the matrix into its rings, like so:

│123456│123456│      │      │
│ABCDEF│A    F│ BCDE │      │
│GHIJKL│G    L│ H  K │  IJ  │
│MNOPQR│M    R│ N  Q │  OP  │
│STUVWX│S    X│ TUVW │      │
│YZ!@#$│YZ!@#$│      │      │

Then each of these rings are rotated left/right based on their index.

My algorithm for getting the rings has a lot of room for improvement (Porting the python solution may be shorter).


⎕UCS convert the matrix to its unicode values

u←⎕UCS store conversion function as u

{...} apply the following function on the matrix:

w←⍵ store argument as w

⍳⌈.5×≢ range 1..ceil(length(w)/2)

Getting the rings

{...}¨ for each value i in the range:

0×w to the input, converted to zeroes,

1@(...) replace the following coordinates with 1s:

1+|⍵-≢⍵ upper limit: length(w) - i

(⍵-1)↓⍳ create range from i to that

,∘.,⍨ get all points in that range

y← store in y

∨/¨(⍵,x)∘∊¨ check which ones are part of the ring, and get a list of booleans

y/⍨ filter y using the boolean array

multiply w with that (vectorizes)

⌽[1+2|⍵]∘⍉ Rotate right if i is odd, otherwise left


+/ sum all the matrices (vectorizes)


u convert back to character matrix.


R, 98 bytes


Try it online!

At each recursive step, rotate the matrix clockwise by transposing it and reversing the rows. Then, if it should be an anticlockwise rotation, reverse all the elements. Finally, replace the 'internal matrix' with the results of a recursive call, with the rotation set to the opposite direction.

f=function(m,r=T,       # recursive function: 
                        # m=matrix
                        # r=direction of rotation (TRUE=clockwise, FALSE=anticlockwise)
d=length(m)^.5){        # d=length of matrix side
  n=t(m)[d:1,]          # n=m rotated clockwise by transposing & reversing rows
  if(r)n[]=rev(n)       # if it's an anticlockwise rotation, reverse the elements
  if(d>2)               # if the 'internal matrix' has a side-length of >1:
    n[e,e]=             # replace it with
    f(m[e<-3:d-1,e],!r) # a recursive call, reversing the direction
n}                      # finally, return n

Jelly, 19 18 bytes


Try it online!


ŒJUC;L‘_ɗ@ṂḂʋ¦€œịṁ   Main monadic link
ŒJ                   Multidimensional indices
  U                  Reverse each
              €      For each
            ʋ          (
    ;                    Join with
        ɗ                (
     L   @                 Length of the input
      ‘                    Increment
       _                   Subtract the argument
          Ṃ              Minimum
           Ḃ             Parity
            ʋ          )
             ¦         At the obtained index
   C                   subtract it from 1
               œị    Index into the input
                 ṁ   Reshape to be the same as the input

Your Answer

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

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