Sort by

recency

|

766 Discussions

|

  • + 0 comments

    C++

    void matrixRotation(vector<vector<int>> matrix, int r) {
        int mr = matrix.size();
        int mc = matrix[0].size();
        int dirx[4] = {0, 1, 0, -1}; // x, y
        int diry[4] = {1, 0, -1, 0};
        vector<vector<int>>ring; // drul
        int num_ring = min(ceil(mr / 2), ceil(mc / 2));
        for(int i = 0; i < num_ring; i++){
            int sx = i, sy = i;
            int dir = 0, current_ring_num = 2 * mc + 2 * mr - 8 * i - 4;
            vector<int> tmp;
            for(int j = 0; j < current_ring_num; j++){
                if(sx + dirx[dir] >= mc - i || sy + diry[dir] >= mr - i || sy + diry[dir] < i){
                    dir++;
                }
                tmp.push_back(matrix[sy][sx]);
                sx += dirx[dir];
                sy += diry[dir];
            }
            rotate(tmp.begin(), tmp.end() - r % current_ring_num, tmp.end());
            ring.push_back(tmp);
        }
        for(int i = 0; i < ring.size(); i++){
            int sx = i, sy = i;
            int dir = 0, current_ring_num = 2 * mc + 2 * mr - 8 * i - 4;
            for(int j = 0; j < current_ring_num; j++){
                if(sx + dirx[dir] >= mc - i || sy + diry[dir] >= mr - i || sy + diry[dir] < i){
                    dir++;
                }
                matrix[sy][sx] = ring[i][j];
                sx += dirx[dir];
                sy += diry[dir];
            }
        }
        for(int i = 0; i < matrix.size(); i++){
            for(int j = 0; j < matrix[i].size(); j++)
                cout<<matrix[i][j]<<" ";
            cout<<endl;
        }
    }
    
  • + 1 comment

    My solution using C++. It's not the best or the most efficient take so i'll try to look for a better approach.

    void matrixRotation(std::vector<std::vector<int>> matrix, int r)
    {
        std::vector<std::vector<int>> res = matrix;
        /* Max number of iterations needed to rotate every layer in the 2d vector */
        uint16_t maxIterations = std::min(matrix.size(), matrix[0].size()) / 2;
        for (int iteration = 0; iteration < maxIterations; iteration++) {
            /* Limit of looping through each layer */
            int32_t row = matrix.size() - 2 * iteration, rowIterator = iteration;
            int32_t col = matrix[0].size() - 2 * iteration, colIterator = iteration;
            int perimeter = (2 * (row + col) - 4), tempRot = r;
            r = r % perimeter; // Removing redundant rotations
            int loopAround = 0;
            /* Top side of the current layer */
            while (loopAround < r && colIterator < col + iteration) {
                loopAround++, colIterator++;
            }
            if (colIterator - iteration >= col) {
                loopAround--, colIterator--;
            }
            /* Right side of the current layer */
            while (loopAround < r && rowIterator < row + iteration) {
                loopAround++, rowIterator++;
            }
            if (rowIterator - iteration >= row) {
                loopAround--, rowIterator--;
            }
            /* Bottom side of the current layer */
            while (loopAround < r && colIterator >= iteration) {
                loopAround++, colIterator--;
            }
            if (colIterator < iteration) {
                loopAround--, colIterator++;
            }
            /* Left side of the current layer */
            while (loopAround < r && rowIterator >= iteration) {
                loopAround++, rowIterator--;
            }
            if (rowIterator < iteration) {
                loopAround--, rowIterator++;
            }
            /* Now we have the location of the element to start the rotation from at matrix[rowIterator][colIterator] */
            /* Top side of the current layer except last element */
            for (int layerCol = iteration; layerCol < col + iteration - 1; layerCol++) {
                res[iteration][layerCol] = matrix[rowIterator][colIterator];
                if (rowIterator == iteration && colIterator < col + iteration - 1 && colIterator >= iteration) {
                    colIterator++;
                } else if (colIterator == col + iteration - 1 && rowIterator < row + iteration - 1 && rowIterator >= iteration) {
                    rowIterator++;
                } else if (rowIterator == row + iteration - 1 && colIterator <= col + iteration - 1 && colIterator > iteration) {
                    colIterator--;
                } else if (colIterator == iteration && rowIterator <= row + iteration - 1 && rowIterator > iteration) {
                    rowIterator--;
                }
            }
            /* Right side of the current layer except last element */
            for (int layerRow = iteration; layerRow < row + iteration - 1; layerRow++) {
                res[layerRow][col + iteration - 1] = matrix[rowIterator][colIterator];
                if (rowIterator == iteration && colIterator < col + iteration - 1 && colIterator >= iteration) {
                    colIterator++;
                } else if (colIterator == col + iteration - 1 && rowIterator < row + iteration - 1 && rowIterator >= iteration) {
                    rowIterator++;
                } else if (rowIterator == row + iteration - 1 && colIterator <= col + iteration - 1 && colIterator > iteration) {
                    colIterator--;
                } else if (colIterator == iteration && rowIterator <= row + iteration - 1 && rowIterator > iteration) {
                    rowIterator--;
                }
            }
            /* Bottom side of the current layer except last element */
            for (int layerCol = col + iteration - 1; layerCol > iteration; layerCol--) {
                res[row + iteration - 1][layerCol] = matrix[rowIterator][colIterator];
                if (rowIterator == iteration && colIterator < col + iteration - 1 && colIterator >= iteration) {
                    colIterator++;
                } else if (colIterator == col + iteration - 1 && rowIterator < row + iteration - 1 && rowIterator >= iteration) {
                    rowIterator++;
                } else if (rowIterator == row + iteration - 1 && colIterator <= col + iteration - 1 && colIterator > iteration) {
                    colIterator--;
                } else if (colIterator == iteration && rowIterator <= row + iteration - 1 && rowIterator > iteration) {
                    rowIterator--;
                }
            }
            /* Left side of the current layer except last element */
            for (int layerRow = row + iteration - 1; layerRow > iteration; layerRow--) {
                res[layerRow][iteration] = matrix[rowIterator][colIterator];
                if (rowIterator == iteration && colIterator < col + iteration - 1 && colIterator >= iteration) {
                    colIterator++;
                } else if (colIterator == col + iteration - 1 && rowIterator < row + iteration - 1 && rowIterator >= iteration) {
                    rowIterator++;
                } else if (rowIterator == row + iteration - 1 && colIterator <= col + iteration - 1 && colIterator > iteration) {
                    colIterator--;
                } else if (colIterator == iteration && rowIterator <= row + iteration - 1 && rowIterator > iteration) {
                    rowIterator--;
                }
            }
            r = tempRot;
        }
    
        for (int i = 0; i < matrix.size(); i++) {
            for (int j = 0; j < matrix[0].size(); j++) {
                std::cout << matrix[i][j] << " ";
            }
            std::cout << std::endl;
        }
        std::cout << std::endl;
        for (int i = 0; i < res.size(); i++) {
            for (int j = 0; j < res[0].size(); j++) {
                std::cout << res[i][j] << " ";
            }
            std::cout << std::endl;
        }
    }
    
  • + 0 comments

    My anser in Typescript, explain includes

    const matrixPrinter = (matrix: number[][]): void => {
        matrix.forEach(row => console.log(row.join(' ')));
    }
    function matrixRotation(matrix: number[][], r: number): void {
        /**
         * the size of the maxtrix at circle 1
         */
        const bound_y = matrix.length
        const bound_x = matrix[0].length
    
        /**
         * read matrix and bind it to [hmap] to easy calculate/reposition after
         */
        let hmap: { [cordinate: string]: number } = {}
        matrix.forEach((row, y) => row.forEach((cell, x) => {
            // counting [c], the circle indexed, start from 1
            let c = 1
            while (true) {
                if (y + 1 == c || y + 1 == bound_y - c + 1) break
                if (x + 1 == c || x + 1 == bound_x - c + 1) break
                c++
            }
    
            hmap[`${x + 1}:${y + 1}:${c}`] = cell;
        }))
    
        /**
         * calculate/reposition each number in [hmap]
         * 
         * + [hmap_temp] create to holding reposition number, avoid to override value
         * + [x],[y] is cordinate of number
         * + [v] is the number
         * + [c] is the circle index where the number is in (from outside to inside, start from 1)
         * + [rc] is the remaining rotations of the circle [c]
         * 
         * Q: why each number have [c] and [rc]?
         * A: cause each number can be on different circle, different circle will need different 
         *    number of [r] to complete fully rotation
         * 
         * Q: why [rc] look so complicated?
         * A: the hour hand at 10AM today and 10AM tomorow is the same. we dont need to calculate 
         *    the between. save resources and time.
         *      
         *      EG: with input [r]=20 and matrix [5x4], we have 2 circle to calculate
         *        
         *      circle 1 
         *      moves to complete fully circe: (5 - 1) * 2 + (4 - 1) * 2 = 14
         *      moves we need to real calculate: 20 % 14 = 6
         * 
         *      circle 2 (the size reduce from 5x4 to 3x2, -2 from each side)
         *      moves to complete fully circe: (3 - 1) * 2 + (2 - 1) * 2 = 6
         *      moves we need to real calculate: 20 % 6 = 2
         */
        let hmap_temp: typeof hmap = {}
        Object.keys(hmap).forEach(key => {
            let x = Number(key.split(':')[0]);
            let y = Number(key.split(':')[1]);
            let c = Number(key.split(':')[2]);
            let v = Number(hmap[key]);
    
            let c_size = { x: bound_x - (c - 1) * 2, y: bound_y - (c - 1) * 2 }
            let c_rotations = r % ((c_size.x - 1) * 2 + (c_size.y - 1) * 2)
    
            while (c_rotations > 0) {
                let direction: 'up' | 'down' | 'left' | 'right'
    
                // calculate move direction (for number on the edge) ...
                if (x == c) direction = 'down'
                if (x == bound_x - c + 1) direction = 'up'
                if (y == c) direction = 'left'
                if (y == bound_y - c + 1) direction = 'right'
    
                // calculate move direction (for number on the corner) ...
                if (x == c && y == c) direction = 'down'
                if (x == c && y == bound_y - c + 1) direction = 'right'
                if (x == bound_x - c + 1 && y == bound_y - c + 1) direction = 'up'
                if (x == bound_x - c + 1 && y == c) direction = 'left'
    
                // this is why using [hmap] is easyer, just change [x] and [y] to move the number
                switch (direction) {
                    case 'up': y--; break
                    case 'down': y++; break
                    case 'left': x--; break
                    case 'right': x++; break
                }
    
                c_rotations--
            }
    
            // store number and it new cordinate to new [hmap]
            hmap_temp[`${x}:${y}`] = v
        })
    
        // now we got new [hmap] stored rotated matrix info, print it
        matrixPrinter(
            new Array(bound_y).fill(0).map((row, y) =>
                new Array(bound_x).fill(0).map((_, x) =>
                    hmap_temp[`${x + 1}:${y + 1}`]
                )
            )
        );
    }
    
  • + 0 comments

    Best I could think of

    def matrixRotation(matrix, r):
        n = len(matrix)
        m = len(matrix[0])
        lowerit = math.floor(min(n, m)/2)
        
        n -= 1
        m -= 1
        for i in range(lowerit):
            arr = []
            endl = n - i
            endr = m - i
            for j in range(i, endl+1):
                arr.append(matrix[j][i])
            for j in range(i + 1, endr+1):
                arr.append(matrix[endl][j])
            for j in range(endl-1, i-1, -1):
                arr.append(matrix[j][endr])
            for j in range(endr-1, i, -1):
                arr.append(matrix[i][j])
                
            bigrcheck =  r % len(arr)
            
            nwarr = arr[len(arr)-bigrcheck:] + arr[:len(arr)-bigrcheck] 
            
            counter = 0
            for j in range(i, endl+1):
                matrix[j][i] = nwarr[counter]
                counter += 1
            for j in range(i + 1, endr+1):
                matrix[endl][j] = nwarr[counter]
                counter += 1
            for j in range(endl-1, i-1, -1):
                matrix[j][endr] = nwarr[counter]
                counter += 1
            for j in range(endr-1, i, -1):
                matrix[i][j] = nwarr[counter]
                counter += 1
        for line in matrix:
            print(*line)
    
  • + 0 comments

    swift

    func matrixRotation(matrix: [[Int]], r: Int) -> Void {
        // Write your code here
        let xCount: Int = matrix.count - 1
        let yCount: Int = matrix.first!.count - 1
    
        var coor: [[Int]] = [[Int]]()
        var flatMatrix: [Int] = [Int]()
        var newMatrix: [[Int]] = [[Int]](repeating: [Int](repeating: 0, count: yCount + 1), count: xCount + 1)
        var x: Int = 0
        var y: Int = -1
        var totalYRunSet: Int = 0
        var cycle: Int = 0
        var isIncrease: Bool = true
        var isYRun: Bool = true {
            didSet {
                totalYRunSet += 1
                if totalYRunSet % 4 == 0 { totalYRunSet = 0 }
                if totalYRunSet == 3 { cycle += 1 }
            }
        }
    
        while(true) {
            if isYRun {
                if isIncrease {
                    y += 1
                    if y == yCount - cycle { isYRun = false }
                }
                else {
                    y -= 1
                    if y == cycle { isYRun = false }
                }
            } else {
                if isIncrease {
                    x += 1
                    if x == xCount - cycle {
                        isYRun = true
                        isIncrease = false
                    }
                }
                else {
                    x -= 1
                    if x == cycle {
                        isYRun = true
                        isIncrease = true
                    }
                }
            }
            
            if newMatrix[x][y] == 1 { break }
      
            coor.append([x, y])
            newMatrix[x][y] = 1
        }
    
        for xy in coor { flatMatrix.append(matrix[xy[0]][xy[1]]) }
    
        var xyCount: [Int] = [xCount + 1, yCount + 1 ]
        var startIndex: Int = 0
        var newFlatMatrix: [Int] = [Int]()
    
        while(xyCount.min()! >= 2) {
            let total: Int = ((xyCount[0] * 2) + (xyCount[1] * 2)) - 4
            let slicedMatrix: [Int] = Array(flatMatrix[startIndex ... startIndex + total - 1])
            var index: Int = r % total
        
            if index == 0 { newFlatMatrix.append(contentsOf: slicedMatrix) }
            else {
                newFlatMatrix.append(slicedMatrix[index])
            
                while (index != (r % slicedMatrix.count) - 1) {
                    index += 1
                    if index == slicedMatrix.count { index = 0 }
                    newFlatMatrix.append(slicedMatrix[index])
                }
            }
            startIndex += total
            xyCount[0] -= 2
            xyCount[1] -= 2
        }
    
        for (mtrx, xy) in zip(newFlatMatrix, coor) { newMatrix[xy[0]][xy[1]] = mtrx }
    
        print(newMatrix.map{ $0.map{ String($0) }.joined(separator: " ") }.joined(separator: "\n"))
    }