Interlaced Rotations

25

3

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

HyperNeutrino

Posted 2017-06-21T18:15:16.063

Reputation: 26 575

Related – rahnema1 – 2017-06-21T18:20:15.680

@rahnema1 Right, I remember that post. This post is mostly inspired by that one; I will credit. Thanks! – HyperNeutrino – 2017-06-21T18:21:15.477

@Mr.Xcoder Whoops. You are right, thanks. – HyperNeutrino – 2017-06-21T18:21:22.883

@HyperNeutrino can we take the dimension of the matrix as a part of input? – Uriel – 2017-06-21T19:20:46.470

All characters in your examples are unique. Will this always be the case? – Dennis – 2017-06-21T19:27:35.490

@Uriel No, I will say that your submission must figure that out itself. Sorry if that renders it impossible in your chosen language. – HyperNeutrino – 2017-06-21T22:26:48.437

@Dennis I will not guarantee that. I will specify, thanks. – HyperNeutrino – 2017-06-21T22:27:06.777

@HyperNeutrino I actually asked for C – Uriel – 2017-06-21T23:11:43.777

Answers

9

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.

Ørjan Johansen

Posted 2017-06-21T18:15:16.063

Reputation: 6 914

6

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

Rod

Posted 2017-06-21T18:15:16.063

Reputation: 17 588

returning rotations recursively. – tuskiomi – 2017-06-21T20:10:29.660

@tuskiomi hmm?? – Rod – 2017-06-21T21:35:45.797

@tuskiomi I tried a recursive approach in ES6. It was about twice as long as a simple port of this answer... – Neil – 2017-06-22T12:28:26.580

4

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

J42161217

Posted 2017-06-21T18:15:16.063

Reputation: 15 931

3

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!

rahnema1

Posted 2017-06-21T18:15:16.063

Reputation: 5 435