[Question]
  [
# 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](https://codegolf.stackexchange.com/questions/111991/rotating-a-2d-matrix) that rotates each element counterclockwise one position (not by 90 degrees).
  
[Answer]
# [Haskell](https://www.haskell.org/), 94 bytes
An anonymous function taking and returning a list of `String`s.
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(:)`foldr`repeat[]
```
[Try it online!](https://tio.run/##TYxbS8NAEEbf51fEGOgurQG1Vo0usVqtl3q/VI3BTuKkWbquZbMVFP97TKqCDwPng3Mmx2JCSpWvKLWQ2pLB1HqWCusrqamAGp0oFq77g@qLYct1g4RvLyWGcOLomVKOEjM9D1jmIG82G0@6EcyDpMwESz9SRZH1Tcv49u/ikAMbBzkPGVb/xNjDIA8tM07C4TlEgWCEoXcyBW1Z8SmnQ2lzFvBR9qZezMjQlNBGcVkur6xCe60D6xubANWoubu719s/gP7h0fHJAE7Pzi8ur@D65vZueA8Pjws7i96vCp0q68I/HQa1DvAN "Haskell – 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.
[Answer]
# [Python 2](https://docs.python.org/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!](https://tio.run/##jc5LS8QwGIXhvb@iopIW00Wr420YcLzreL9ryEKw1YSYGUKF@uvr27hyIy4eevgO5WT21bxPfdl1r1Wd1GmbbbmRqzwhL4ZhFF78W5W65SIbhqr5DF4p1SqXG62slq3i63KrtfowPjXSSirYbKnU9TQkJjE@CTHan9jNgvENU0qJQkhRYgWrGAgtlVgjrWMDmxjH6w5pF3vYx0G8HpKOcIwTTOL1lHSGc1zgUmidzf05LJntfx2T/jslGeqb31NSXOE6NjekW9zhHg94jM0T6Rnz2MYCFvtndt8 "Python 2 – 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
[Answer]
# 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}}
> 
> 
> 
[Answer]
# 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!](https://tio.run/##y08uSSxL/f/fQSNRszrbNtE6W6PC1sgqNS9F11CnQtPWwDrRtii/xNIAKG@dqJGrCePp6BppauTa1uXmp2gkladkFpdoaGfrqCdnqGvqGGkC1dZWm9b@T7NNzCu25uJK04jW09PjUjc0MlbnUjcxNQOS5haW6rGaKHIQCUcnZxdXNyDD3cPTy9sHyPD18w8IDAIygkNCw8IjgIzIKEUHZRWg/v8A "Octave – Try It Online")
[Answer]
# [APL (Dyalog Unicode)](https://www.dyalog.com/), 35 [bytes](https://codegolf.meta.stackexchange.com/a/9429/43319 "When can APL characters be counted as 1 byte each?") ([SBCS](https://github.com/abrudz/SBCS ".dyalog files using a single byte character set"))
Full program. Prompts for APL matrix expression. Requires 0-based indexing.
```
⍉⌽m⊣{(b↓e↓m)←⌽⊖b↓m↓⍨e←-b←2⍴⍵}¨⍳≢m←⎕
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///qG@qp/@jtgkGXI862gv@P@rtfNSzN/dR1@JqjaRHbZNTgThXEygPFH3UNQ0klAvEj3pXAGUm6AL5E4we9W551Lu19tCKR72bH3UuygWp7pv6H2jefwUwKOB61DYRKOQV7O8HZKlHKxkaGSvpKJmYmgFJcwtLpVh1LkylEHUmpkA1ZkBFjkDaydnF1Q1Iu3t4enkDaR9fP/8A/LpBVjii6PMBMkD6AoOAjOCQ0LDwCCAjMkrRQVkFaBYA "APL (Dyalog Unicode) – 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⍴⍵` **r**eshape the index to a two-element list
 `b←` assign to `b` (for **b**eginning)
 `-` negate that
 `e←` assign to `e` (for **e**nd)
 `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
 `⌽` mirror
 `(`…`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`
`⌽` mirror
`⍉` transpose
[Answer]
# [APL (Dyalog Unicode)](https://www.dyalog.com/), 81 bytes
```
{u⊃+/{⌽[1+2|⍵]∘⍉w×1@(y/⍨∨/¨(⍵,x)∘∊¨y←,∘.,⍨(⍵-1)↓⍳x←1+|⍵-≢w)⊢0×w}¨⍳⌈.5×≢w←⍵}u←⎕UCS
```
[Try it online!](https://tio.run/##RY69TsJgFIZ3r@Izmnw0FLBUUDa0/oD/UlDROKClFUWKYC0VmTSkICUaQ3Bm6mDioI4u5U7OjdTz6eByTs77PDl5C9VySLEKZV3zoT@Q8oQqaqVO/aYB3ftgpAm97yMhGL0D5@sY7FdwOuZ4KCQDVgQcF2w34rkBZHyDY9Tueq4F7ScejzCPBmMhgYP2CzgfDSRCkL0KQWdkctAdzYyHZstzEULPDsfGQwZQQ6dlsN0f5CTZV3@jPlYC5w2cT@9dhPYzQjkj4cym0rKvodPEAxel8PiglOpVwnvuX0EuoLLZmtCISER8QYWoOBuLz80nKGZxEv/PFhalpeWV1VR6bX1jc2t7ZzcjZ3N7@wf5w8nk1DTTEyTB9OxZkVwZpdMLclLTzQpR9QY5Ny6rdaLfFGvkGnG5cGsRRdfoDw "APL (Dyalog Unicode) – 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).
## Explanation
`⎕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
`w×` multiply `w` with that (vectorizes)
`⌽[1+2|⍵]∘⍉` Rotate right if `i` is odd, otherwise left
---
Finally,
`+/` sum all the matrices (vectorizes)
`⊃` unwrap
`u` convert back to character matrix.
[Answer]
# [R](https://www.r-project.org/), 98 bytes
```
f=function(m,r=T,d=length(m)^.5){n=t(m)[d:1,]
if(r)n[]=rev(n)
if(d>2)n[e,e]=f(m[e<-3:d-1,e],!r)
n}
```
[Try it online!](https://tio.run/##jc9ZS8QwFAXg9/yLiT4kkBE6tTNOMeK@jbt1LVVqk2phkkKIG@JvrycvPgwiQ/jg5CYP97iusV67aVlp9ehaX3otu1rWr7byTWuZEU5mQsmpts/@hRn@sJTwLys9Yq7SSBSkqZnjNi@k02/M8nBXawNMtNCFrJnJ9Wo/TlU/wl30HCf2uzPSlN41H6xiNKKCDiCGZUioIHSIMIIVGMNGGG4ibME27MBuGO4h7MMBHMIkDI8QjuEETuGMcpHgPH269l1m2HK2NgoR8rtWlI5FjDPv/79rhBYkrD735mFxMrO5oOdwER4uETK4gmu4gdvwcIdwDz1YhwVYROchzv8duh8 "R – Try It Online")
**How?**  
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.
```
interlaced_rotate=
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
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 19 18 bytes
```
ŒJUC;L‘_ɗ@ṂḂʋ¦€œịṁ
```
[Try it online!](https://tio.run/##y0rNyan8///oJK9QZ2ufRw0z4k9Od3i4s@nhjqZT3YeWPWpac3Tyw93dD3c2/j/c7v7/f7SSoZGxiamZko6So5Ozi6sbkOHu4enl7QNk@Pr5BwQGARnBIaFh4RFARmSUooOyilIsAA "Jelly – Try It Online")
## Explanation
```
Œ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
```
]