简体   繁体   中英

Rotating an encoded 3x3 matrix/list

Let's say there is an encoded 3x3 plane:

1 2 3   
4 5 6  
7 8 9  

After a clockwise rotation, it becomes:

7 4 1
8 5 2
9 6 3

To convert the former to the latter, an obvious approach would be doing something like this:

 switch (num) {
     case 1: return 7; break;
     case 2: return 4; break;
     ...
 }

For example, [1, 5, 6, 9] gives [7, 5, 2, 3] .

Is there anyway to do this without hard-coding it?

The function to transform the value to the new value, that would arrive at the same position, you can use the function as defined (in JavaScript) below:

 function rotated(num) { num--; // convert to zero-based number return 1 + (2 - num % 3) * 3 + Math.floor(num / 3); } // demo: print original and new value next to each other: for (let num = 1; num <= 9; num++) { console.log(num, rotated(num)); }

Follow-up

In comments you asked how I came up with this solution.

There are several ways to get there, but here is how I think it went:

I wondered: if I were to know the row and column where the given number appears, what would be the row and column where to get the new value from?

For instance, 3 appears in row 0 and column 2 (in zero-based index numbering). The value I need sits in row 0 and column 0. By playing with row and column, you find that all entries in row 0 will get their new value from column 0. Similarly those in row 1 will get their new value from column 1.

With the column number there is also a relationship: all entries in column 0 get their new value from row 2. Those column 1 get them from row 1, and those in column 2 get them from row 0. So here we have an inverse relationship.

So the steps to take, given a number, are:

  1. Derive from the given number in which row and column it appears
  2. Derive from these row and column indexes the other row and column indexes, where the new value is sitting (following the above principle)
  3. Derive from that other row and column which value sits there and return it.

I had focussed on the details of step 2 until now. The first step should be easy. The column index where a given num appears is (num-1) % 3 (modulo operator). The row index is (num-1)/3 (integer division).

Step 3 should do the inverse: multiply the row index by 3 and add the column index. That gives a zero-based value, so 1 should be added to it.

All this leads to the following code:

 function rotated(num) { num--; // convert to zero-based number // Step 1: derive row and column let col = num % 3; let row = Math.floor(num / 3); // Step 2: derive other row and column let valueCol = row; let valueRow = 2 - col; // opposite direction // Step 3: which value sits there? let value = valueRow * 3 + valueCol + 1; // Return that return value; } // demo: print original and new value next to each other: for (let num = 1; num <= 9; num++) { console.log(num, rotated(num)); }

Then the last step was to reduce the number of variables used in that program... which led to the first snippet above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM