[Question]
  [
The matrix tornado is just like any other tornado: it consists of things rotating around a center. In this case, elements of the matrix instead of air.
Here is an example of a matrix tornado:
[![Matrix tornado in action](https://i.stack.imgur.com/e7ymY.jpg)](https://i.stack.imgur.com/e7ymY.jpg)
First we start by sectioning the matrix into square rings, each section consists of elements that are farther away from the border by the same distance. These sections will be rotated clockwise around the center. In real tornadoes, the severity increases towards the center, and so does the rotation step in a matrix tornado: the outermost section (the red one) is rotated by 1 step, the next (the yellow) one is rotated by 2, and so on. A rotation step is a 90° rotation around the center.
### Task:
Your task, should you accept it, is to write a function or program that takes as input a square matrix, apply the tornado effect to it and then output the resulting matrix.
### Input:
The input should be a square matrix of order `n` where `n >= 1`. No assumption is to be made about the elements of the matrix, they could be anything.
### Output:
A square matrix of the same order which would be the result of applying the tronado effect to the input matrix.
### Examples:
A matrix of order `n = 1`:
```
[['Hello']]               ===>    [['Hello']]
```
A matrix of order `n = 2`:
```
[[1 , 2],                 ===>    [[5 , 1],
 [5 , 0]]                          [0 , 2]]
```
A matrix of order `n = 5`:
```
[[A , B , C , D , E],             [[+ , 6 , 1 , F , A],
 [F , G , H , I , J],              [- , 9 , 8 , 7 , B],
 [1 , 2 , 3 , 4 , 5],     ===>     [/ , 4 , 3 , 2 , C],
 [6 , 7 , 8 , 9 , 0],              [* , I , H , G , D],
 [+ , - , / , * , %]]              [% , 0 , 5 , J , E]]
```
  
[Answer]
# [Python 3](https://docs.python.org/3/), ~~100~~ ~~97~~ 96 bytes
-3 bytes thanks to [Graipher](https://codegolf.stackexchange.com/users/55479/graipher) by changing `rot90(a,axes=(1,0))` to `rot90(a,1,(1,0))`  
-1 byte thanks to [Kevin Cruijssen](https://codegolf.stackexchange.com/users/52210/kevin-cruijssen) by removing a space
```
import numpy
def f(a):
 if len(a):a=numpy.rot90(a,1,(1,0));a[1:-1,1:-1]=f(a[1:-1,1:-1]);return a
```
[Try it online!](https://tio.run/##jY9LU4MwFIX3@RXZOCGaKrRWLZ0ufNf3@8mwQAsWCwEj6PTX47ltFl246OL75t455M6hnFbjQneaJs3LwlRc13k5ZaM44YkTSZ/xNOFZrGmOBrNw3RRVz3Ui5SnHU66U/Sjw/JanSOEAzxZW2TdxVRvNoyYpDM94qnE4CMQwzrJChKH0S5Pqyskkmw@SsYUvWRB4irdDxXjQVdxd5oHYFYqLPdI@6YB0KGY3xBEtx6Qh6YR0ajOPljapQ9okdW22Rcs2aYfUI7k2W6OlRdogrZJWxLJVqSkVpZ6oqagiGs5PoyR1REUlzsA5uACXNr/CfA1uwC24A/fgweaPmJ/AM3gBryACbzZ/xzwCMUjABxiD1OafmCcgAznQoAClzb8wG/ANKlCDH/D77@83fw "Python 3 – Try It Online")
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 44 bytes
```
≔ＥθＳθＷθ«≔Ｅθ⮌⭆θ§§θνλθθＭ¹⁻¹Ｌθ≔Ｅ✂θ¹±¹¦¹✂κ¹±¹¦¹θ
```
[Try it online!](https://tio.run/##ZU/JbsIwED3jr/DRlsKBc08pa0pCgbDf3GRwXFxnsROQEN8eHBYJ1MNoRm/VRAkropTJuna1FlyRgGUkd7CnstKEphCKE0odnNMPdEyEBExyis@o9S6fQwWFBnJ3PEDXeCqGE3luCykbJSl9JramVm7I7QzSCkjHwYFQpW4OHxQ3iSVpQ7/0hVJE0KRZ0QQ4M9ZnA5u5U4f/1KPwYv/87Pb6gyEaeV9jP5ig7@lsHi6WaLXebHfsB0Ux7Hki0O9B/qk0Q3mhTVkd63Ylrw "Charcoal – Try It Online") Link is to verbose version of code. Only works on character squares because Charcoal's default I/O doesn't do normal arrays justice. Explanation:
```
≔ＥθＳθ
```
Read the character square.
```
Ｗθ«
```
Loop until it's empty.
```
≔Ｅθ⮌⭆θ§§θνλθ
```
Rotate it.
```
θＭ¹⁻¹Ｌθ
```
Print it, but then move the cursor to one square diagonally in from the original corner.
```
≔Ｅ✂θ¹±¹¦¹✂κ¹±¹¦¹θ
```
Trim the outside from the array.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 27 bytes
```
J«þ`UṚ«Ɗ‘ịZU$LÐ¡ŒĖḢŒHEƊƇṁµG
```
[Try it online!](https://tio.run/##y0rNyan8/9/r0OrD@xJCH@6cdWj1sa5HDTMe7u6OClXxOTzh0MKjk45Me7hj0dFJHq7Huo61P9zZeGir@////5UcnZxdXJV0lNzcPTy9gLShkbGJKZA2M7ewNADS2rr6WqpKAA "Jelly – Try It Online")
I think this could be far shorter.
```
           Input: n×n matrix A.
J          Get [1..n].
 «þ`       Table of min(x, y).
    UṚ«Ɗ   min with its 180° rotation.
Now we have a matrix like: 1 1 1 1 1
                           1 2 2 2 1
                           1 2 3 2 1
                           1 2 2 2 1
                           1 1 1 1 1
‘ị          Increment all, and use as indices into...
     LÐ¡    List of [A, f(A), f(f(A)), …, f^n(A)]
  ZU$       where f = rotate 90°
Now we have a 4D array (a 2D array of 2D arrays).
We wish to extract the [i,j]th element from the [i,j]th array.
ŒĖ     Multidimensional enumerate
This gives us: [[[1,1,1,1],X],
                [[1,1,1,2],Y],
                ...,
                [[n,n,n,n],Z]]
ḢŒHEƊƇ     Keep elements whose Ḣead (the index) split into equal halves (ŒH)
           has the halves Equal to one another. i.e. indices of form [i,j,i,j]
           (Also, the head is POPPED from each pair, so now only [X] [Y] etc remain.)
ṁµG        Shape this like the input and format it in a grid.
```
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), ~~78 73~~ 72 bytes
*Thanks to nwellnhof for -5 bytes!*
```
$!={my@a;{(@a=[RZ] rotor @_: sqrt @_)[1..*-2;1..@a-2].=$!}if @_;@a[*;*]}
```
[Try it online!](https://tio.run/##Tc7JCsIwFAXQfb8ihUrSmMY2WqdQiPOwdGkpkoWCoKjVjUi/vYZLBTfn5XLD492P5aVf14Gffa5vY/WHGZvlu31BytvrVhJzGJPno3y5R5gnUvJIaTeMjVQhs8CvzidXaWNzrnlRuUUsEUqkIg4lNjAVyqu9My6f9h1qz8nccP/ohBJB6BTO4BwuqPAIIXSJtIJruIHbpk@QFOzCHkybvo80gEM4gnHTt5Ei2IEctujv9vT/9voL "Perl 6 – Try It Online")
Recursive code block that takes a flattened 2D array and returns a similarly flattened array.
### Explanation:
```
$!={      # Assign code block to pre-declared variable $!
    my@a; # Create local array variable a
   {
     (@a=[RZ]  # Transpose:
             rotor @_: sqrt @_;  # The input array converted to a square matrix
     )[1..*-2;1..@a-2].=$!  # And recursively call the function on the inside of the array
   }if @_;    # But only do all this if the input matrix is not empty
   @a[*;*]  # Return the flattened array
}
```
[Answer]
# [Octave](https://www.gnu.org/software/octave/),  ~~86~~ 81 bytes
```
f(f=@(g)@(M,v=length(M))rot90({@(){M(z,z)=g(g)(M(z=2:v-1,z)),M}{2},M}{1+~v}(),3))
```
[Try it online!](https://tio.run/##FY5BCoMwFET3PcUs/6ep@H@0akPAC@QEpYtS1C5KxSIuFHv1NN0Mw2MezPiY70sXJ59lWeyp9y0N3FIwi39172F@UmD@jHOT09YSb4FWs7If0opS93pZTpIIm7Bvuv9Tjt9lJzaWOQZ/FSgsCpTujAo1GkjuRCAKsZACUjo5QypIDWmgudPkKNRCC2h5O0zpRPwB "Octave – Try It Online")
I'm aware that recursive anonymous functions are not the shortest method to do things in Octave, but they're the most *fun* method by far. This is the shortest anonymous function I could come up with, but I'd love to be outgolfed.
### Explanation
The recursive function is defined according to [this](https://codegolf.stackexchange.com/a/164483/32352) [tips](/questions/tagged/tips "show questions tagged 'tips'") answer by ceilingcat. `q=f(f=@(g)@(M) ... g(g)(M) ...` is the basic structure of such an anonymous function, with `g(g)(M)` the recursive call. Since this would recurse indefinitely, we wrap the recursive call in a conditional cell array: `{@()g(g)(M),M}{condition}()`. The anonymous function with empty argument list delays evaluation to after the condition has been selected (although later, we see that we can use that argument list to define `z`). So far it has just been basic bookkeeping.
Now for the actual work. We want the function to return `rot90(P,-1)` with P a matrix on which `g(g)` has been recursively called on the central part of M. We start by setting `z=2:end-1` which we can hide in the indexing of M. This way, `M(z,z)` selects the central part of the matrix that needs to be tornadoed further by a recursive call. The `,3` part ensures that the rotations are clockwise. If you live on the southern hemisphere, you may remove this bit for -2 bytes.
We then do `M(z,z)=g(g)M(z,z)`. However, the result value of this operation is only the modified central part rather than the entire `P` matrix. Hence, we do `{M(z,z)=g(g)M(z,z),M}{2}` which is basically stolen from [this](https://codegolf.stackexchange.com/a/163110/32352) [tips](/questions/tagged/tips "show questions tagged 'tips'") answer by Stewie Griffin.
Finally, the `condition` is just that the recursion stops when the input is empty.
[Answer]
# [Python 2](https://docs.python.org/2/), 98 bytes
```
def f(a):
 if a:a=zip(*a[::-1]);b=zip(*a[1:-1]);b[-2:0:-1]=f(b[-2:0:-1]);a[1:-1]=zip(*b)
 return a
```
[Try it online!](https://tio.run/##hY/LTsMwEEX3/orZIMdpIpJAC3GVBe/SL6hkeeGKGFxFTmSFBfx84BZDqYTE5mjOzLU9Ht7Gl95X0/TUWrKJEZKRs2Skad7dkKRGSZmXWiy3315GV3klC9SNTQ4iljHxFd8KRqEdX4MnM9k@UEfOf76jFF@1XddzrYUcgvMjdYztC3YUKzOqdMZIzTMq/gvzK54RvwZugFvgju/P83vIA7ACHoF1nJWQCjgDzoF5nC0gF8AlUANFnM0gOXAKpMDJX39im0YpN9ulNWFjh42D8c9tUguNzu6o8/tbm5/Lpg8 "Python 2 – Try It Online")
[Answer]
# [R](https://www.r-project.org/), 87 bytes
```
function(m,n=nrow(m)){for(i in seq(l=n%/%2))m[j,j]=t(apply(m[j<-i:(n-i+1),j],2,rev));m}
```
[Try it online!](https://tio.run/##jdDLTsMwEAXQvb/CEoo8Qx3aBMo7C94F5Q@ARXCTypVjF9cEEOLbQzo8lOyYxZF8fW1Z9m2VtdWLVUE7C7W0mfXuFWrEj8p50Fxbvi6fwWQ2GkcpYn2/lMvHLECxWpl36JansT4GG@tRgt2OTKUvG8ST@rPd4r838@C4crYpfeBGrwN3FW9KFZxfb7bqInj9xhbZ30tynLsdVRgD/knbucyRMZZnm7OgQMxKY5xAZBUsui4yVQQQ8c88WIG9dsIlT1Ey/j0Kpl0w@edhcSa6tjgnL8hL8kr0rxTXFN6QM/KWvBvWEgpTcpfcI6fD2j6FB@QheUROhrURhTE5JrfJqP81LdvMFw "R – Try It Online")
* credits to this [StackOverFlow answer](https://stackoverflow.com/a/16497058/316644) for the rotation code
[Answer]
# [MATL](https://github.com/lmendo/MATL),  ~~25 24 23~~ 22
```
t"tX@Jyq-ht3$)3X!7Mt&(
```
[Try it online!](https://tio.run/##DcuxCsJAEEXRX7mKSCyEvJndbMI2qQP2AbGwS5EUwjR@/erpz/GOvbU4xzov3899C7/cfD2VR1y71p7CcBK5DhRGJtRXCRlylFCuGlBBI5qwvtr/GOZYwvLrBw "MATL – Try It Online")
Indexing in MATL is never easy, but with some golfing it actually beats the current best Jelly answer...
```
t                       % Take input implicitly, duplicate.  
 "                      % Loop over the columns of the input*
   X@                   % Push iteration index, starting with 0. Indicates the start of the indexing range.
     Jyq-               % Push 1i-k+1 with k the iteration index. Indicates the end of the indexing range
         t              % Duplicate for 2-dimensional indexing.
  t       3$)           % Index into a copy of the matrix. In each loop, the indexing range gets smaller
             3X!        % Rotate by 270 degrees anti-clockwise
                7Mt&(   % Paste the result back into the original matrix. 
```
\*For an `n x n` matrix, this program does `n` iterations, while you really only need `n/2` rotations. However, the indexing in MATL(AB) is sufficiently flexible that indexing impossible ranges is just a no-op. This way, there's no need to waste bytes on getting the number of iterations just right.
[Answer]
# [K (ngn/k)](https://gitlab.com/n9n/k), ~~41~~ ~~39~~ 38 bytes
```
{s#(+,/'4(+|:)\x)@'4!1+i&|i:&/!s:2##x}
```
[Try it online!](https://tio.run/##PY/ZjoIwAEXf/YoKo4JooIgbvIwb4L7vY@KKIggKqBh1fp1RS@ap9@S2zT1a3NganqfwdxsnqBgd4QjqwZM/Lvkd4YKQUsMPlQ/TQZtncdx9eg5//5refi1eAa4wNzWBmCsLVRdc4SZY5OwZcKYElssXiiVRwgIAAEwuV6q1egNBs9XudHt9BIPhaDxZLBGs1htlu1MR7DX9YJhHBCfLds6XK0a@iMBO@9WgKedQZZnGQdfyCOxdd7JdFxA4i85YGRYRnHvt0aZVQnCp16qVsojgelSX/YaEkbPX8FgMkze6br6r//wuCAjY9/UkYD4jkgC@kQHs550vjH4UpZcwipBNcEkUU@lMlkGRitPRkC9DpaDoq8SzmbQvQnMJ1teIlmXJlwgxyUoJDYUQQIinBf@ceX8 "K (ngn/k) – Try It Online")
`{` `}` function with argument `x`
`#x` length of `x` - the height of the matrix
`2##x` two copies - height and width (assumed to be the same)
`s:` assign to `s` for "shape"
`!s` all indices of a matrix with shape `s`, e.g. `!5 5` is
```
(0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4
 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4)
```
This is a 2-row matrix (list of lists) and its columns correspond to the indices in a 5x5 matrix.
`&/` minimum over the two rows:
```
0 0 0 0 0 0 1 1 1 1 0 1 2 2 2 0 1 2 3 3 0 1 2 3 4
```
`i&|i:` assign to `i`, reverse (`|`), and take minima (`&`) with `i`
```
0 0 0 0 0 0 1 1 1 0 0 1 2 1 0 0 1 1 1 0 0 0 0 0 0
```
These are the flattened ring numbers of a 5x5 matrix:
`4!1+` add 1 and take remainders modulo 4
`(+|:)` is a function that rotates by reversing (`|` - we need the `:` to force it to be monadic) and then transposing (`+` - since it's not the rightmost verb in the "train", we don't need a `:`)
`4(+|:)\x` apply it 4 times on `x`, preserving intermediate results
`,/'` flatten each
`+` transpose
`(` `)@'` index each value on the left with each value on the right
`s#` reshape to `s`
[Answer]
# JavaScript (ES6), 99 bytes
```
f=(a,k=m=~-a.length/2)=>~k?f(a.map((r,y)=>r.map(v=>y-m>k|m-y>k|--x*x>k*k?v:a[m+x][y],x=m+1)),k-1):a
```
[Try it online!](https://tio.run/##ddHZboJAGAXge55ibsywzIiouDVg3NFXmHAxsWhbNqPGQNL46nhAbWhsJ/lIgHP4J8OXvMjT9vh5OPMkfQ@KYueokoVO7Fy5bEZBsj9/mG3Nca/heKfKZiwPqnpkOZ4cq5uL4@Y8dsPvmOe4cp7pmRvq4fgykiI2Ml/kPsuc2LA0jYXc0kay2KbJKY2CZpTu1Z2qECIE9YIoSqnvk9/LNOsvFU17U/5oW4y0fUZeFtp4axNGLJ8hSYTNSOtlyCNJRIuUH/p3DJ1QRqcwgzksaDW12qSBbq@cBEuYPCbSJYIr8GANm58SERzBIQygD9NnyUKwDR3ogl0rmQh2oVPuFmbPUg/BPgxgCK1aSUdwDR6sYP4sGQhyMEGHxv0nVKUGguWZlCe4gcX9bIob "JavaScript (Node.js) – Try It Online")
### How?
Given a square matrix of width \$W\$, we define:
$$m=\frac{W-1}{2}\\
t\_{x,y}=\max(|y-m|,|x-m|)$$
Example output of \$t\_{x,y}\$ for a 5x5 matrix (\$W=5\$, \$m=2\$):
$$\begin{pmatrix}
2 & 2 & 2 & 2 & 2 \\
2 & 1 & 1 & 1 & 2 \\
2 & 1 & 0 & 1 & 2 \\
2 & 1 & 1 & 1 & 2 \\
2 & 2 & 2 & 2 & 2
\end{pmatrix}$$
We start with \$k=m\$ and perform a 90° clockwise rotation of all cells \$(x,y)\$ satisfying:
$$t\_{x,y}\le k$$
while the other ones are left unchanged.
This is equivalent to say that a cell is ***not*** rotated if we have:
$$(y-m>k) \text{ OR } (m-y>k) \text{ OR } (X^2>k^2)\text{ with }X=m-x$$
which is the test used in the code:
```
a.map((r, y) =>
  r.map(v =>
    y - m > k | m - y > k | --x * x > k * k ?
      v
    :
      a[m + x][y],
    x = m + 1
  )
)
```
Then we decrement \$k\$ and start again, until \$k=-1\$ or \$k=-3/2\$ (depending on the parity of \$W\$). Either way, it triggers our halting condition:
```
~k === 0
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 24 bytes
```
ṙ⁹ṙ€
ḊṖ$⁺€ßḷ""ç1$ç-ZUµḊ¡
```
[Try it online!](https://tio.run/##y0rNyan8///hzpmPGneCyKY1XA93dD3cOU3lUeMuIO/w/Ic7tispHV5uqHJ4uW5U6KGtQOlDC/8fbnf//z9a3dHJ2cVVXUdB3c3dw9MLxDA0MjYxBTHMzC0sDUAMbV19LVX1WAA "Jelly – Try It Online")
> 
> I think this could be far shorter.
> 
> 
> 
*– [Lynn](https://codegolf.stackexchange.com/a/169682/41024)*
[Answer]
# [Haskell](https://www.haskell.org/), 108 bytes
```
e=[]:e
r=foldl(flip$zipWith(:))e
g!(h:t)=h:g(init t)++[last t]
f[x,y]=r[x,y]
f[x]=[x]
f x=r$(r.r.r.(f!).r)!x
```
[Try it online!](https://tio.run/##fY5LT8MwEITv/hWbKEg2KQUKtBDJB14thfIsUCDKIRA7MXWd4Dg08OeDW3quVqtv9jAzm8XllEnZNIyGUcCQpjyXicRcisL7FcVEmAwHhDCUOjgLDKFZkGKhhAFDfD@UcWlVhHhYt34iqpdYXBG1izjUVHtYtxeDuUPamjh1M4uFAgpJjgCKyoyNHinwoFJSKFZaxSF0j09Oz87dltsfXAwvLXc7e/sHlt3e4dGOpb@1vbnhRusjVgnLgG5v5Vtv82Ce66SE/wf6A7D1V6PrG7i9u38YPz7B8@Tl9S1@h4@E8TQT8DmVM5UX8KVLU33P3eYP "Haskell – Try It Online")
I used [Laikoni's transpose](https://codegolf.stackexchange.com/a/111362/3852) and modified it a little, to rotate an array 90°:
```
  e=[]:e;foldr(zipWith(:))e.reverse
≡ e=[]:e;foldl(flip$zipWith(:))e
```
# Explanation
`r` rotates an array by 90°.
`(!)` is a higher-level function: “apply to center”. `g![1,2,3,4,5]` is `[1] ++ g[2,3,4] ++ [5]`.
`f` is the tornado function: the base cases are size 1 and 2 (somehow 0 doesn't work).
The last line is where the magic happens: we apply `r.r.r.(f!).r` on the middle rows of `x` and then rotate the result. Let's call those middle rows **M**. We want to recurse on the middle *columns* of **M**, and to get at those, we can rotate **M** and then use `(f!)`. Then we use `r.r.r` to rotate **M** back into its original orientation.
[Answer]
# [J](http://jsoftware.com/), 37 bytes
```
<./~@g`(|:@|.^:(1<@+>./@g=.#\.<.#\))}
```
[Try it online!](https://tio.run/##JYnBCoJAFEX3fsW1FqOUz9wkThpDRato0boiy1Enwgm1QrB@3aQW95wD99oFJvcOU5MHjBkDYikiDoYxJuD9HMJyt1l3IbkfkZ2slouWjtzyQjGakyuyiIZ7CnvY9ruzje2CsFLV/RY3MkGlEolz8/dL1TkehVPrsogT3d9PWVZKF4a85BqWIh@@jRlS/LL7Ag "J – Try It Online")
Independently solved, but this approach is very similar to Lynn's.
It is also one of the most perfect problems for J's little used "composite item" `}` (in gerund form) that I have come across.
[Answer]
# Java 10, ~~198~~ ~~192~~ ~~181~~ ~~174~~ 173 bytes
```
m->{int d=m.length,b=-1,i,j;var r=new Object[d][d];for(;b<d/2;){for(i=b++;++i<d-b;)for(j=b;j<d-b;)r[j][d+~i]=m[i][j++];for(i=d;i-->0;)m[i]=r[i].clone();}return r;}
```
-25 bytes thanks to *@ceilingcat*
[Try it online.](https://tio.run/##ndRrb5swFAbg7/sVR5WmwLg0ydbdXCp167bu0nRbdo/ywYCTmoLJjJOuithfz14ClVIJpKkSD5I5HNsc@ZDwFfeS@HITpbwo6IxLtb5HJJUResYjQaNqSHQeJiIyk@lkSpG1M8hshngJuArDjYxoRIoC2mTe0RrzUBxkfirU3Fy4YeANXOkmbMU16UCJq5uJ4ykuNsu1xcLDeH/I7HU1kEHoOMxx5GHshcyuHiVByJJ6qCcJ0py/chpkEzmdJI5TzyGDmEnPO@ozuwoEGjc/SnMlLJuVWpilVqRZuWH1xhfLMMXGm/2vchlThkpYY6OlmuMzuV2XwYjCWDvbRgnqANHu03XvuOf2XsBLOIFX8Bre9Eq3NeEUwbfwDt7DBziDUVfCOYIf4RN8hjF8ga9dCd8Q/A4/4Cf8Ag5hV0KEYAwCZjCHC5BdCQmCl5BCBgpyWHQl/EZQQwEGlrCCq165fb/cnq7/L/veqUjTfO9uyQN32L7NA7d/txlbTkFHIeqj4e6cgvYXiQYu0RAewiM46HrxMYJP4Ck8g37H0g6W82AfHsD9W7W/3dnbzth@/e4vgKNL/jQNUnXfTYw/V35kNWG7WXx8XRiR@fnS@As0l0mVleAf5C@NTP1jrfl14Zu8bjyL203FW7Ka7ZWbfw)
**Explanation:**
```
m->{                      // Method with Object-matrix as both parameter & return-type
  int d=m.length,         //  Dimensions of the matrix
      b=-1,               //  Boundaries-integer, starting at -1
      i,j;                //  Index-integers
  var r=new Object[d][d]; //  Result-matrix of size `d` by `d`
  for(;b<d/2;){           //  Loop `b` in the range (-1,`d/2`]:
    for(i=b++;++i<d-b;)   //   Inner loop `i` in the range [`b`,`d-b`):
      for(j=b;j<d-b;)     //    Inner loop `j` in the range [`b`,`d-b`):
        r[j][d+~i]=       //     Set the `j,d-i-1`'th result-cell to:
          m[i][j++];      //      The `i,j`'th cell-value of the input-matrix
    for(i=d;i-->0;)       //   Inner loop `i` in the range (`d`,0]:
      m[i]                //    Change the `i`'th row of the input-matrix
        =r[i].clone();}   //     to a copy of the `i`'th row of the result-matrix
  return r;}              //  Return the result-matrix
```
`b` is basically used to indicate which ring we're at. And it will then rotate this ring (including everything inside it) once clockwise during every iteration.
The replacement of the input-matrix is done because Java is pass-by-reference, so simply setting `r=m` would mean both matrices are modified when copying from cells, causing incorrect results. We therefore instead have to copy the values in every cell one row at a time, without copying their reference (by using `.clone()`).
[Answer]
# MATLAB, 93 bytes
```
function m=t(m),for i=0:nnz(m),m(1+i:end-i,1+i:end-i)=(rot90(m(1+i:end-i,1+i:end-i),3));end;end
```
I'm sure this can be golfed some more somehow.
**Explanation**
```
function m=t(m),                                                                          end % Function definition
                for i=0:nnz(m),                                                       end;    % Loop from 0 to n^2 (too large a number but matlab indexing doesn't care)
                                                            m(1+i:end-i,1+i:end-i)            % Take the whole matrix to start, and then smaller matrices on each iteration
                                                      rot90(                      ,3)         % Rotate 90deg clockwise (anti-clockwise 3 times)
                               m(1+i:end-i,1+i:end-i)=                                        % Replace the old section of the matrix with the rotated one
```
[Answer]
# [C (gcc)](https://gcc.gnu.org/), 128 118 115 bytes
-15 bytes from @ceilingcat
```
j,i;f(a,b,w,s)int*a,*b;{for(j=s;j<w-s;j++)for(i=s;i<w-s;)b[~i++-~j*w]=a[i*w+j];wmemcpy(a,b,w*w);++s<w&&f(a,b,w,s);}
```
[Try it online!](https://tio.run/##dVLbrpswEHyGr7CQesRlI@Hl0lYkX0J5wLRpQUoahVQkQpxfT8eGgzm9SN5E3p3ZmXHS7L43zfPZUVsc/ZoUDdQH7fkW1hSqYjz@vPrdoS@6/bDDZxQFutOi05pOoMrXNop2r104VIe6bMMh6qpiOH07NZfHvDAcgiKK@v3w8mIliul5wWVVK5of9TXsC3d0ncsVraPvfegPX86eBruOkT3fxEMcRFzgay@GQkTRI3AdUNb5fZ7f3@Z3zA3AbuWvwiMR@nX0gNt7oNc7E@ry69b7nqfvuNrb5Lqnuj37gTanRWpZygoHWuMopJgmUBBHkiSvlmaDxqkFp/3rqdKAmOLAwM3NUwa@7OWSK5xlLwkWE2nvo0hIpKsOE0OHrc7Cm3WYlAZYHQNXvNFJy7TCmXW0kGAUNLQICdcRWlNkaOSoj6hPxsrc/0xCxigQJdu@xAKZosCT@eo2pRRuU@t2UZ/dpqQ0wLo1cJVu3GZlVuH8yy0q2zpe3dLicuPOuKWNy80MPAmeBE@Cxxse698BPAaPwePMJDPRMsoQLbPRFqtztIyUBthoBq6yTbS8zCuc/0XT7z/HM@neJXv3/n8//1sgOza56I8865jBYrAYLIYIA57E9v8HVgJWAlYCkQTwxP7GOeV4iNw@xBJsfoiclAbYhzBwZeDT8zc "C (gcc) – Try It Online")
[Answer]
# Haskell, 274 bytes
`w` is the main function, which has the type `[[a]] -> [[a]]` that you would expect.
I'm sure a more experienced Haskell golfer could improve on this.
```
w m|t m==1=m|0<1=let m'=p m in(\a b->[h a]++x(\(o,i)->[h o]++i++[f o])(zip(tail a)b)++[f a])m'(w(g m'))
p m|t m==1=m|0<1=z(:)(f m)(z(\l->(l++).(:[]))(r(x h(i m)):(p(g m))++[r(x f(i m))])(h m))
t[]=1
t[[_]]=1
t _=0
h=head
f=last
x=map
i=tail.init
g=x i.i
z=zipWith
r=reverse
```
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), 93 bytes
```
f=(a,k=0,L=a.length+~k)=>L?f(a.map((b,x)=>b.map((c,y)=>x<k|y<k|x>L|y>L?c:a[k+L-y][x])),k+1):a
```
[Try it online!](https://tio.run/##ddHbboIwHAbwe56iN6YgRUDF04aL50N4g6YXlaHbYGCmWSAxe3X2AbK4uJH8Lkq/j39T3uSnPPkfr8ezESfPQZ7vXVWy0LWY58pWFMSH84v@FWru2Hvaq7L1Lo@qumMpXuyqhc8yLNLH8JJBOvYuGbL@SPJQ94xM8FRoGgt1WxvJ3E/iUxIFrSg5qHtVIYRzug6iKKFCkN@Pad5uKpr2oPzRthlpC0buHrSx6xBGbMGQJNxhxLobck0SbpHiQ/@OoRPK6BRmMIcFLaeWh9TR7RWTYAmT60S6RHAFa9jA9qdEuIHgEAbQh2ldshFsQwe64NyUTAS70ClOC7O61EOwDwMYgnVTaiK4gTWsYF6XdAQNMKEJjeonlKUGgsWdFDe4hUV1N/k3 "JavaScript (Node.js) – Try It Online")
```
f=(
  a,             // Input
  k=0,           // Range Left
  L=a.length+~k  // Range Right
)=>L?            // More than enough
  f(
    a.map((b,x)=>b.map((c,y)=>x<k|y<k|x>L|y>L?c:
      a[k+L-y][x]// k+L=a.length-1
  )),k+1)
:a
```
[Answer]
# [Haskell](https://www.haskell.org/), 144 bytes
```
import Data.List
k=transpose
v=init.tail
t[[o]]=[[o]]
t m=k.reverse.(head m:).(++[last m]).
 k.((v.head$k m):).(++[v.last$k m]).
 k.t.map(v).v$m
```
[Try it online!](https://tio.run/##LcpJTsQwEIXhvU9RamXhqKU6AJIXQDM3MzRDlEVBDDEesQv38QNBvXmL938jFaudmybjU8wMK2LCtSksrOJMoaRYtKjKBMPIZJzgrot9r/5XMHhlMeuqc9EoR00D@L0W5XLZOSp/uW9RgEUpK861seDbHag4k/nZIUZPSdYWa@MnTyaolE3ghpttzENZ7B8cro6OT@D07PxifXkF1ze3d/cPj7B5en55pTd4H/TH52jgyzofYoLvXPinbhfTLw "Haskell – Try It Online")
`v` cuts out center (rows). `map v` cuts out center columns.
`t` recurses into the tornado. `k` exposes columns as rows.
`(++[v.last$k m])` appends center of last column.
`((v.head$k m):)` prepends center of first column.
`k` flips rows out again.
`(++[last m])` appends last row unprocessed.
`(head m:)` prepends last row unprocessed.
`k.reverse` rotates matrix.
[Answer]
# [Uiua](https://uiua.org) [SBCS](https://tinyurl.com/Uiua-SBCS-Jan-14), 25 bytes
```
∧(⍜(↘⊙↻|≡⇌⍉)×¯2.⊟.)⇡⌈÷2⧻.
```
[Try it!](https://uiua.org/pad?src=0_9_0__ZiDihpAg4oinKOKNnCjihpjiipnihrt84omh4oeM4o2JKcOXwq8yLuKKny4p4oeh4oyIw7cy4qe7LgoKZiBbWzFdXQoKZiBbWzEgMl0KICAgWzUgMF1dCgpmIFsiQUJDREUiCiAgICJGR0hJSiIKICAgIjEyMzQ1IgogICAiNjc4OTAiCiAgICIrLS8qJSJdCg==)
Fun problem.
```
∧(⍜(↘⊙↻|≡⇌⍉)×¯2.⊟.)⇡⌈÷2⧻.
                   ⇡⌈÷2⧻.  # create range for each ring
∧(                )        # fold over range and matrix, using matrix as accumulator
                ⊟.         # create pair indicating how much to rotate matrix on each axis
            ×¯2.           # and another pair indicating how much to drop from each axis
  ⍜(   |   )               # call the left part, then the right, then the inverse of left
        ≡⇌⍉                # rotate matrix clockwise
    ↘⊙↻                    # but only the interior
```
]