# Challenge

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
B C D E F
G H I J K
L M N O P


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.

# Input

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.

# Output

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


# Credits

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

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

# 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"].

(cycle[t.r,r.t,r.t,r.t]?)
(g:h)?(a:b)=g\$a:h?t(r b)
_?a=a
r=reverse;t=zipWith(:)foldrrepeat[]


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

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

# Mathematica, 113 bytes

r=Reverse;(l=Length[s=#];Table[s[[i+1;;l-i,i+1;;l-i]]=r/@r@s[[i+1;;l-i,i+1;;l-i]],{i,⌊l/2⌋}];r/@Transpose@s)&


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

input

[{{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, "!", "@", "#", "&"}}]

output

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

@(a){k=a;k(x=2:end-1,x)=0;a=rot90(a);a(m)=rot90(a,-2)(m=~mod(bwdist(+k,'ch'),2));a}{5}


Try it online!