25
\$\begingroup\$

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

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

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(:)`foldr`repeat[]

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

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

\$\endgroup\$
  • \$\begingroup\$ returning rotations recursively. \$\endgroup\$ – tuskiomi Jun 21 '17 at 20:10
  • \$\begingroup\$ @tuskiomi hmm?? \$\endgroup\$ – Rod Jun 21 '17 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 '17 at 12:28
4
\$\begingroup\$

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

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

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!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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