15
\$\begingroup\$

The title pretty much describes it all. Given as input a \$n \times m\$ matrix and an integer \$i\$ create a complete function/program that returns the matrix \$i\$ times clockwise rotated by \$90^\circ\$.

Rules:

  • as matrix you can use any convenient representation you like e.g. a list of lists etc...
  • matrix values can be positive and/or negative integer numbers
  • \$n\$ and \$m\$ are of course always positive integers between 1 and 10
  • \$i\$ can be any valid integer which belongs in the following range: \${0...10^5}\$
  • Standard rules & winning criteria apply but no "winning" answer will be chosen.

EDIT: I had to edit the initial question because for some programming languages it takes too long to compute the result for \$i\in\{0...10^7\}\$. There is a workaround to it but since it's a code-golf just make sure that it simply runs successfully for at least \$i\in\{0...10^5\}\$.

Some test cases:

==== example 1 ====
Input:
5
[[1, 3, 2, 30,],
 [4, 9, 7, 10,],
 [6, 8, 5, 25 ]]

Expected Output:
[[ 6  4  1],
 [ 8  9  3],
 [ 5  7  2],
 [25 10 30]]

==== example 2 ====
Input:
100
[[1]]

Expected Output:
[[1]]

==== example 3 ====
Input:
15
[[150,    3,  2],
 [  4, -940,  7],
 [  6, 8000,  5]]

Expected Output:
[[   2    7    5],
 [   3 -940 8000],
 [ 150    4    6]]

==== example 4 ====
Input:
40001
[[1, 3, 9]]

Expected Output:
[[1],
 [3],
 [9]]
```
\$\endgroup\$

18 Answers 18

7
\$\begingroup\$

APL (Dyalog Unicode), 7 bytes

⌽∘⍉⍣⎕⊢⎕

Try it online!

 prompt for matrix expression from stdin

 yield that

 prompt for \$i\$ expression from stdin

 do the following that many times

 transpose

 and then

 mirror

\$\endgroup\$
  • 2
    \$\begingroup\$ Nice, I really liked that it even works for \$i\$ of \$10^7\$. I had to lower that in the requirements because for some languages tio.run wouldn't terminate... \$\endgroup\$ – game0ver Nov 27 at 23:24
  • 1
    \$\begingroup\$ @game0ver Yeah, APL is generally quite fast when it comes to munging arrays. Even \$10^8\$ only takes about 20 seconds on TIO. \$\endgroup\$ – Adám Nov 27 at 23:35
  • 2
    \$\begingroup\$ Wow, the character for transpose and mirror looks suitable \$\endgroup\$ – justhalf Nov 29 at 5:35
  • \$\begingroup\$ @justhalf Yes, APL is like that. Can you guess what flip-upside-down looks like? \$\endgroup\$ – Adám Nov 29 at 8:32
  • 1
    \$\begingroup\$ @justhalf Basically. Unicode has many homoglyphs. APL prefers the Unicode APL range, so this is \$\endgroup\$ – Adám Nov 29 at 11:50
5
\$\begingroup\$

J, 7 bytes

|:@|.^:

Try it online!

An adverb train. Right argument is the matrix, left argument is the repetition count.

How it works

|:@|.^:
     ^:  Repeat the function:
   |.      Reverse vertically
  @        and then
|:         Transpose
         Absent right argument to `^:`:
           bind to the left argument (repeat count)
\$\endgroup\$
5
\$\begingroup\$

Ruby, 39 bytes

->m,n{n.times{m=m.reverse.transpose};m}

Try it online!

\$\endgroup\$
5
\$\begingroup\$

Pyth, 7 6 bytes

uC_GQE

Try it online!

-1 Thanks to @FryAmTheEggman

Rotates the matrix by reversing the order of rows and taking the transpose. Takes and returns lists of lists.

How it works

uC_GQE
u    E - Reduce the second input
  _G   - By reversing the order of rows
 C     - And transposing
    Q  - An amount of times equal to the first input  
\$\endgroup\$
4
\$\begingroup\$

Japt -R, 2 bytes

zV

Try it

Rotate matrix by 90 degrees 2nd input times
\$\endgroup\$
  • 1
    \$\begingroup\$ OK, this one might be hard to beat. \$\endgroup\$ – Adám Nov 27 at 23:43
  • \$\begingroup\$ @Adám agreed, Japt fits this challenge very well :p \$\endgroup\$ – AZTECCO Nov 27 at 23:53
  • 1
    \$\begingroup\$ @AZTECCO really impressive!!! \$\endgroup\$ – game0ver Nov 27 at 23:54
  • \$\begingroup\$ I knew this would be the solution just from the challenge title! I also knew someone would have beaten me to it! \$\endgroup\$ – Shaggy Nov 28 at 14:20
  • 1
    \$\begingroup\$ I was there at the right time @Shaggy , couldn't miss it! \$\endgroup\$ – AZTECCO Nov 28 at 15:33
4
\$\begingroup\$

Jelly, 4 bytes

Naive implementation. There might be a shorter way I'm not aware of.

ṚZ$¡

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Nice, but the last test case fails since for both \$i=40001\$ and \$i=40000\$ it gives the same result. \$\endgroup\$ – game0ver Nov 27 at 23:51
  • 1
    \$\begingroup\$ @game0ver The output is actually different, but displayed the same way. I've added some code in the footer to format it. \$\endgroup\$ – Arnauld Nov 28 at 0:00
  • \$\begingroup\$ yep you are correct! Thanks for editing :) \$\endgroup\$ – game0ver Nov 28 at 0:08
  • 2
    \$\begingroup\$ I think this is as short as you can get at present. Matrix rotation is already on my wish list of possible new Jelly links that I may get round to suggesting at some point \$\endgroup\$ – Nick Kennedy Nov 29 at 10:08
4
\$\begingroup\$

Python 2, 44 bytes

f=lambda A,i:i%4and f(zip(*A[::-1]),i-1)or A

Try it online!

Input/output is a list of tuples. (The %4 is a workaround for Python's recursion limit; could save a byte otherwise).

\$\endgroup\$
  • \$\begingroup\$ Nice! Yep that's the workaround (%4) I'm talking about in the description. A way to skip that would be using numpy but I really like the naive implementation. Also you could save 2 bytes by placing f= into Header in TIO! \$\endgroup\$ – game0ver Nov 28 at 10:43
  • 1
    \$\begingroup\$ @game0ver They can't actually do that to save bytes since this is a recursive function - it needs to be named so they can call it. \$\endgroup\$ – FryAmTheEggman Nov 28 at 16:31
  • \$\begingroup\$ @FryAmTheEggman good catch! You are right! \$\endgroup\$ – game0ver Nov 28 at 17:04
4
\$\begingroup\$

K (oK), 6 bytes

(+|:)/

Try it online!

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

Haskell, 50 bytes

(!!).iterate(foldr(zipWith$flip(++).pure)e)
e=[]:e

Try it online!

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

05AB1E (legacy), 3 bytes

Føí

Takes \$i\$ as first input; matrix the second.

Try it online or verify all test cases.

Explanation:

F    # Loop the (implicit) input-integer amount of times:
 ø   #  Zip/transpose the matrix; swapping rows/columns
     #  (this will take the (implicit) input in the first iteration)
  í  #  Reverse each row
     # (after the loop, the resulting matrix is output implicitly)

NOTE: Uses the legacy version only because of performance. The last test case times out in the rewrite version. Both the legacy and rewrite versions would be the same, though.

\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6), 58 bytes

Takes input as (i)(matrix).

i=>g=m=>i--?g(m[0].map((_,x)=>m.map(r=>r[x]).reverse())):m

Try it online!

Note: The last test case was edited to prevent a recursion error. We can obviously use i--&3 (60 bytes) to support much larger values.

\$\endgroup\$
2
\$\begingroup\$

Octave, 17 bytes

Unfortunately rot90 rotates the input counterclockwise.

@(x,i)rot90(x,-i)

Try it online!

\$\endgroup\$
2
\$\begingroup\$

MATL, 5 3 bytes

-2 bytes thanks to @LuisMendo!

_X!

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Java 8, 141 138 131 130 bytes

(m,i)->{for(int t[][],a,b,j;i-->0;m=t)for(t=new int[b=m[0].length][a=m.length],j=a*b;j-->0;)t[j%b][j/b]=m[a-j/b-1][j%b];return m;}

-7 bytes thanks to @OlivierGrégoire.

Try it online.

Code explanation:

(m,i)->{                 // Method with int-matrix and int parameters and int-matrix return
  for(int t[][],         //  Temp int-matrix as replacement
          a,b,           //  Temp integers used for the dimensions
          j;             //  Temp integer for the inner loop
      i-->0;             //  Loop the input `i` amount of times:
      m=t)               //    After every iteration: replace the input-matrix `m` with `t`
    for(t=new int[b=m[0].length][a=m.length],
                         //   Create a new temp-matrix `t` with dimensions `b` by `a`,
                         //   where `b` & `a` are the amount of columns & rows of matrix `m`
        j=a*b;           //   Set `j` to the product of these dimensions
        j-->0;)          //   And inner loop in the range [`j`, 0):
      t                  //  Replace the value in `t` at position:
       [j%b]             //   `j%b` (let's call this row A),
            [j/b]        //   `j/b` (let's call this column B)
        =m               //  And replace it with the value in `m` at position:
          [a-j/b-1]      //   `a-j/b-1` (which is the reversed column B as row,
                         //     so it both transposes and reverses at the same time),
                   [j%b];//   `j%b` (which is row A as column)
  return m;}             //  And finally return the new int-matrix

To save bytes, the inner loop is a single loop and uses j/a and j%a as cell positions. So a loop like this:

for(r=a;r-->0;)for(c=b;c-->0;)t[c][r]=m[b-r-1][c];

Has been golfed to this:

for(j=a*b;j-->0;)t[j%b][j/b]=m[a-j/b-1][j%b];

to save 5 bytes.

\$\endgroup\$
  • 1
    \$\begingroup\$ 131 bytes \$\endgroup\$ – Olivier Grégoire Nov 29 at 9:12
  • \$\begingroup\$ Explanation of the above: I restarted it from scratch trying to use simply new int[m[0].length][m.length]. It seemed to have worked. The rest is basically your code. So in the end the golf came from moving the variable allocation where needed most. \$\endgroup\$ – Olivier Grégoire Nov 29 at 9:17
  • 1
    \$\begingroup\$ @OlivierGrégoire I was quite proud of this one, but had the feeling it could still be golfed. ;) Btw, 1 more byte can be saved by removing that temp variable s and use a-j/b-1 instead of a+~s again. \$\endgroup\$ – Kevin Cruijssen Nov 29 at 9:22
  • 1
    \$\begingroup\$ Indeed, that's a one more saved byte. I hadn't passed the code again under full review ;) But to be honest, you did the bigger job with your first answer. \$\endgroup\$ – Olivier Grégoire Nov 29 at 9:28
  • \$\begingroup\$ I've removed that general explanation, since it's now the same as the code, haha. ;) \$\endgroup\$ – Kevin Cruijssen Nov 29 at 9:35
2
\$\begingroup\$

R, 64 bytes

r=function(x,i){o=x;n=0;while(n<i){o=t(apply(o,2,rev));n=n+1};o}

Try it online!

Not really efficient...

Uses rotation approach proposed by Matthew Lundberg

\$\endgroup\$
  • \$\begingroup\$ Hi there, and welcome to R golfing! I like this approach. There are still a bunch of golfs available, e.g., this for 48 bytes. Feel free to join the R golf chatroom to ask any golfing questions you might have, and read these tips. Happy golfing! \$\endgroup\$ – Giuseppe Dec 2 at 21:12
  • \$\begingroup\$ To speed it up, you can do something like i%%4 in the stop condition. \$\endgroup\$ – Giuseppe Dec 2 at 21:13
1
\$\begingroup\$

Pari/GP, 37 bytes

f(m,n)=for(i=1,n,m=Mat(Vecrev(m~)));m

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Julia 1.0, 6 bytes

Kind of cheating, but Julia has a built in rotl90 function, that does exactly that.

rotl90

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ No, no cheat at all! It's also pretty fast with very large values of \$i\$ e.g. \$i^{11}\$ etc... \$\endgroup\$ – game0ver Nov 29 at 11:31
-1
\$\begingroup\$

Mathematica, 32 bytes

a = {{3, 4, 5}, {5, 6, 7}, {8, 9, 10}, {11, 12, 13}};

Nest[Reverse /@ Transpose[#] &, a, i] 
\$\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.