19
\$\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\$
0

21 Answers 21

9
\$\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\$
6
  • 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 '19 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 '19 at 23:35
  • 2
    \$\begingroup\$ Wow, the character for transpose and mirror looks suitable \$\endgroup\$
    – justhalf
    Nov 29 '19 at 5:35
  • 1
    \$\begingroup\$ Something like this ⦵? \$\endgroup\$
    – justhalf
    Nov 29 '19 at 9:03
  • 1
    \$\begingroup\$ @justhalf Basically. Unicode has many homoglyphs. APL prefers the Unicode APL range, so this is \$\endgroup\$
    – Adám
    Nov 29 '19 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\$

Jelly, 4 bytes

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

ṚZ$¡

Try it online!

\$\endgroup\$
4
  • \$\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 '19 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 '19 at 0:00
  • \$\begingroup\$ yep you are correct! Thanks for editing :) \$\endgroup\$
    – game0ver
    Nov 28 '19 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\$ Nov 29 '19 at 10:08
5
\$\begingroup\$

Haskell, 50 bytes

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

Try it online!

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

Ruby, 39 bytes

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

Try it online!

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

K (oK), 6 bytes

(+|:)/

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\$
0
4
\$\begingroup\$

Japt -R, 2 bytes

zV

Try it

Rotate matrix by 90 degrees 2nd input times
\$\endgroup\$
5
  • 1
    \$\begingroup\$ OK, this one might be hard to beat. \$\endgroup\$
    – Adám
    Nov 27 '19 at 23:43
  • \$\begingroup\$ @Adám agreed, Japt fits this challenge very well :p \$\endgroup\$
    – AZTECCO
    Nov 27 '19 at 23:53
  • 1
    \$\begingroup\$ @AZTECCO really impressive!!! \$\endgroup\$
    – game0ver
    Nov 27 '19 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 '19 at 14:20
  • 1
    \$\begingroup\$ I was there at the right time @Shaggy , couldn't miss it! \$\endgroup\$
    – AZTECCO
    Nov 28 '19 at 15:33
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\$
3
  • \$\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 '19 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\$ Nov 28 '19 at 16:31
  • \$\begingroup\$ @FryAmTheEggman good catch! You are right! \$\endgroup\$
    – game0ver
    Nov 28 '19 at 17:04
4
\$\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\$
3
\$\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
  • 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 '19 at 11:31
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\$
0
2
\$\begingroup\$

MATL, 5 3 bytes

-2 bytes thanks to @LuisMendo!

_X!

Try it online!

\$\endgroup\$
0
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\$
5
  • 1
    \$\begingroup\$ 131 bytes \$\endgroup\$ Nov 29 '19 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\$ Nov 29 '19 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\$ Nov 29 '19 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\$ Nov 29 '19 at 9:28
  • \$\begingroup\$ I've removed that general explanation, since it's now the same as the code, haha. ;) \$\endgroup\$ Nov 29 '19 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\$
2
  • \$\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 '19 at 21:12
  • \$\begingroup\$ To speed it up, you can do something like i%%4 in the stop condition. \$\endgroup\$
    – Giuseppe
    Dec 2 '19 at 21:13
2
\$\begingroup\$

Husk, 7 bytes

~!→¡oT↔

Try it online! I've always found it odd that the only real way to iterate a function a set number of times in Husk is to index into the infinite list of that function's iterates.

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

Pari/GP, 37 bytes

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

Try it online!

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

GolfScript, 10 bytes

~{-1%zip}*

Try it online!

~{      }*   # Repeat i times
  -1%        # Reverse the array
     zip     # Zip

When the program finishes, only the elements of the matrix are displayed. To see how it actually was outputted, use this.

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

Arn, 8 7 bytes

Ç├Úe↑Î(

Try it!

Explained

Unpacked: &.{.@@.< ELABORATE HERE

&. Mutate N times
  { Block, key of `_`
        _ Implied variable
      .@ Transposed
    @ Binded map
      .< Reverse
  } End block; implied

Input is two lines, the first being an array and the second a number. &. supports both 2 separate inputs and one as an array, and as _ is automatically the STDIN separated on newlines and parsed, this code is valid.

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