1

I need to be able to rotate a 2d array of data both clockwise and counterclockwise (right and left), in 2 separated functions.

I was able to make the first function which does clockwise rotation to work well but I'm having modifying my code for the second function which should turn counterclockwise.

This is my function for clockwise rotation in Typescript:

function rotateClockwise<T>(arr: T[][]) {
  const ret: any[][] = arr.map(c => c.map(v => "")); // blank copy 
  const rows = arr.length;
  if (rows === 0) return ret;
  const cols = arr[0].length;
  if (!arr.every(l => l.length === cols)) throw new Error("Not rectangular");
  const stationaryRing = (rows % 2 !== 0) && (cols % 2 !== 0) ? (Math.min(rows, cols) - 1)/2:-1
  console.log('stationaryRingx = ', stationaryRing)
  for (let r = 0; r < rows; r++) {
    let nr = rows - 1 - r;
    for (let c = 0; c < cols; c++) {
      let nc = cols - 1 - c;
      const ring = Math.min(r, nr, c, nc);
      let [rNew, cNew] = [r, c];
      if (ring !== stationaryRing) {
        if (r === ring && nc !== ring) cNew++; // top row moves right (except for rightmost)
        else if (c === ring) rNew--; // left column moves up
        else if (nr === ring) cNew--; // bottom row moves left
        else rNew++; // right column moves down
      }
      ret[rNew][cNew] = arr[r][c];
    }
  }
  return ret;
}

for the following input table:

1 2 3
4 5 6
7 8 9

The code above produces this table:

4 1 2
7 5 3
8 9 6

I need to change the code in order for it rotate to the left so if I use the same input table above I should get:

2 3 6
1 5 9 
4 7 8

I thought that by changing the conditions as described below I would be able to make a counterclockwise rotation but it did not work:

if (ring !== stationaryRing) {
         if (r === ring && nc !== 0) rNew-- ; // top row moves left (except for leftmost)
        else if (c === ring) rNew++; // left column moves down
        else if (nr === ring) cNew++; // bottom row moves right
        else cNew--; // right column moves up
      } 

Any ideas? Thanks!

  • Does this answer your question? [How do you rotate a two dimensional array?](https://stackoverflow.com/questions/42519/how-do-you-rotate-a-two-dimensional-array) – maraca Mar 04 '23 at 13:29
  • Turn 3 times clockwise ;-) – maraca Mar 04 '23 at 13:29
  • @maraca, that is not a correct dupe reference as here the rotation is not 90° per rotation, but one cell at a time. – trincot Mar 04 '23 at 13:34
  • @trincot I don't know if we checked the same question, but they are rotating by 90°. It's just basic math and has probably at least 5 answers already. – maraca Mar 04 '23 at 13:38
  • *"they are rotating by 90°"*: indeed, that's what happens in the dupe, and that is not the question at hand here. Rotating 90° would mean that the value 1 in the example array would end up at the right. It doesn't. – trincot Mar 04 '23 at 13:48
  • @maraca, you wrote "Turn 3 times clockwise", but have you tried this with their code? You would actually need to do it 7 times, and it would need a lot more rotations to work with bigger matrices, because then the length of the multiple rings is different. – trincot Mar 04 '23 at 15:13

1 Answers1

0

Some issues:

  • nc !== 0 is certainly wrong, as you should compare with ring (for all except the outermost ring, no column will ever be 0).

  • rNew-- does not do what the comment next to it says.

  • cNew-- does not do what the comment next to it says.

A correct way to "mirror" the functioning code, is to mirror bottom and top (i.e. exchange r and nr), and up and down (i.e. exchange rNew++ and rNew--), but not left and right. So that results in this correction:

      if (ring !== stationaryRing) {
        if (nr === ring && nc !== ring) cNew++; // bottom row moves right (except for rightmost)
        else if (c === ring) rNew++; // left column moves down
        else if (r === ring) cNew--; // top row moves left
        else rNew--; // right column moves up
      }
trincot
  • 317,000
  • 35
  • 244
  • 286