在javascript中将矩阵旋转45度

nat*_*ft1 2 javascript rotation matrix

给定一个像这样的矩阵:

1 2 3
4 5 6
7 8 9
Run Code Online (Sandbox Code Playgroud)

可以表示为一个二维数组:

arr = [[1,2,3], [4,5,6], [7,8,9]];
Run Code Online (Sandbox Code Playgroud)

旋转数组,以便以 45 度角对角读取并打印出以下内容:

1
4 2
7 5 3
8 6
9
Run Code Online (Sandbox Code Playgroud)

我花了一段时间想出了一个我什至不能完全直观地理解的解决方案,但它确实有效,至少对于 3x3 和 4x4 矩阵来说是这样。我希望看到更多逻辑和干净的实现。

这是我的解决方案:

arr = [[1,2,3,0],[4,5,6,0],[7,8,9,0], [0,0,0,0]];
// arr[i][j];

transform(arr);

function transform(ar) {
    // the number of lines in our diagonal matrix will always be rows + columns - 1
    var lines = ar.length + ar[0].length - 1;
    // the length of the longest line...
    var maxLen = ~~(ar.length + ar[0].length)/2;
    var start = 1;
    var lengths = [];
    // this for loop creates an array of the lengths of each line, [1,2,3,2,1] in our case
    for (i=0;i<lines; i++) {
        lengths.push(start);
        if (i+1 < maxLen) {
            start++;
        } else {
            start--;
        }
    }
    // after we make each line, we're going to append it to str
    var str = "";
    // for every line
        for(j=0; j<lengths.length; j++) {
            // make a new line
            var line = "";
            // i tried to do it all in one for loop but wasn't able to (idk if it's possible) so here we use a particular for loop while lengths of the lines are increasing
            if (j < maxLen) {
                // lengths[j] is equal to the elements in this line, so the for loop will run that many times and create that many elements
                for(c=0; c<lengths[j]; c++) {
                    // if ar[r][c], the pattern here is that r increases along rows (as we add new lines), and decreases along columns. c stays the same as we add rows, and increases across columns 
                    line += ar[lengths[j]-1-c][c] + " ";
                    // when we've added all the elements we need for this line, add it to str with a line break
                    if (c == lengths[j]-1) { 
                        line += "\n"; str += line; 
                    }

                }
            } else {
                // when we're headed down or decreasing the length of each line
                for (r=0; r<lengths[j]; r++) {
                    // the pattern here tripped me up, and I had to introduce another changing variable j-maxLen (or the distance from the center).  r stays the same as rows increase and decreases across columns.  c increases along rows and decreases across columns
                    line += ar[lengths[j]-r+j-maxLen][j-maxLen+r +1] + " ";
                    // that's all our elements, add the line to str;
                    if (r == lengths[j] -1) {
                        line += "\n"; str += line; 
                    }
                }
            }
        }
        console.log(str);

}
Run Code Online (Sandbox Code Playgroud)

Mat*_*att 5

(i,j)主要思想是根据 来划分索引为 的原始矩阵i+j

这在下面的代码片段中得到了表达rotated[i+j].push(arr[i][j])

arr = [[1,2,3], [4,5,6], [7,8,9]];

var summax = arr.length + arr[0].length - 1; // max index of diagonal matrix
var rotated = []; // initialize to an empty matrix of the right size
for( var i=0 ; i<summax ; ++i ) rotated.push([]);
// Fill it up by partitioning the original matrix.
for( var j=0 ; j<arr[0].length ; ++j )
    for( var i=0 ; i<arr.length ; ++i ) rotated[i+j].push(arr[i][j]);
// Print it out.
for( var i=0 ; i<summax ; ++i ) console.log(rotated[i].join(' '))
Run Code Online (Sandbox Code Playgroud)

输出:

1
4 2
7 5 3
8 6
9
Run Code Online (Sandbox Code Playgroud)

在红宝石中

产生相同的输出:

puts arr.transpose.flatten.group_by.with_index { |_,k|
    k.divmod(arr.size).inject(:+) }.values.map { |a| a.join ' ' }
Run Code Online (Sandbox Code Playgroud)