Sort by

recency

|

764 Discussions

|

  • + 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"))
    }
    
  • + 0 comments

    C#

    static void matrixRotation(List<List<int>> matrix, int r)
    {
        int rowsC = matrix.Count;
        int colsC = matrix[0].Count;
    
    
        int rm = 0;
        int rM = rowsC - 1;
    
        int cm = 0;
        int cM = colsC - 1;
    
        int length = (cM - cm + 1) * 2 + (rM - rm + 1) * 2 - 4;
       
        int[] a = new int[length];
    
        // Check if there is something to shift
        while (cm < cM && rm < rM)
        {
            int shifts = r % length;
    
            // Fill array from matrix part given by min/max row/column
            for (int i = cm; i <= cM; i++)
            {
                a[i - cm] = matrix[rm][i];
                a[cM - cm + rM - rm + i - cm] = matrix[rM][cM - i + cm];
            }
    
            for (int j = rm + 1; j <= rM - 1; j++)
            {
                a[cM - cm + j - (rm + 1) + 1] = matrix[j][cM];
                a[cM - cm + rM - rm + cM - cm + j - rm] = matrix[rM - 1 + rm + 1 - j][cm];
            }
    
            // Shift array
            for (int i = 0; i < length / 2; i++)
            {
                (a[i], a[length - 1 - i]) = (a[length - 1 - i], a[i]);
            }
    
            for (int i = 0; i < (length - shifts) / 2; i++)
            {
                (a[i], a[length - shifts - 1 - i]) = (a[length - shifts - 1 - i], a[i]);
            }
    
            for (int i = 0; i < shifts / 2; i++)
            {
                (a[length - shifts + i], a[length - 1 - i]) = (a[length - 1 - i], a[length - shifts + i]);
            }
    
            // Update matrix part given by min/max row/column from shifted array
            for (int i = cm; i <= cM; i++)
            {
                matrix[rm][i] = a[i - cm];
                matrix[rM][cM - i + cm] = a[cM - cm + rM - rm + i - cm];
            }
    
            for (int j = rm + 1; j <= rM - 1; j++)
            {
                matrix[j][cM] = a[cM - cm + j - (rm + 1) + 1];
                matrix[rM - 1 + rm + 1 - j][cm] = a[cM - cm + rM - rm + cM - cm + j - rm];
            }
    
            // Switch matrix part given by min/max row/column to the next level
            rm += 1;
            rM -= 1;
            cm += 1;
            cM -= 1;
    
            length -= 8;
        }
    
        foreach (var t in matrix)
        {
            foreach (var t1 in t) Console.Write($"{t1} ");
            Console.WriteLine();
        }
    }
    
  • + 0 comments

    C#

    public static void matrixRotation(List<List<int>> matrix, int r)
    {
        var col = matrix.First().Count;
        var row = matrix.Count;
        var layers = Math.Min(col, row) / 2;
    
        var layerLines = new List<List<int>>();
    
        // Iterate through layers to get them as a list of numbers.
        for (int layer = 0; layer < layers; layer++)
        {
            var line = new List<int>();
    
            // get left values of the layer
            for (int i = layer; i < row - 1 - layer; i++)
            {
                line.Add(matrix[i][layer]);
            }
    
            // get bottom values of the layer
            for (int i = layer; i < col - 1 - layer; i++)
            {
                line.Add(matrix[row - 1 - layer][i]);
            }
    
            // get right values of the layer
            for (int i = row - 1 - layer; i > layer; i--)
            {
                line.Add(matrix[i][col - 1 - layer]);
            }
    
            // get top values of the layer
            for (int i = col - 1 - layer; i > layer; i--)
            {
                line.Add(matrix[layer][i]);
            }
    
            layerLines.Add(line);
        }
    
        // Iterate through lines and rotate anti-clockwise
        foreach (var line in layerLines)
        {
            // Once rotated by line count result will be the same
            // By using % we can optimize and get the real count.
            var rotations = r % line.Count;
    
            for (int i = 0; i < rotations; i++)
            {
                var last = line.Last();
                line.RemoveAt(line.Count - 1);
                line.Insert(0, last);
            }
        }
    
        // Replace the lines in layers.
        for (int layer = 0; layer < layers; layer++)
        {
            var line = layerLines[layer];
            var index = 0;
    
            // left layer values
            for (int i = layer; i < row - 1 - layer; i++)
            {
                matrix[i][layer] = line[index++];
            }
    
            // bottom layer values
            for (int i = layer; i < col - 1 - layer; i++)
            {
                matrix[row - 1 - layer][i] = line[index++];
            }
    
            // right layer values
            for (int i = row - 1 - layer; i > layer; i--)
            {
                matrix[i][col - 1 - layer] = line[index++];
            }
    
            // top layer values
            for (int i = col - 1 - layer; i > layer; i--)
            {
                matrix[layer][i] = line[index++];
            }
    
            layerLines.Add(line);
        }
    
        // Print output
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                Console.Write(matrix[i][j] + " ");
            }
            Console.WriteLine();
        }
    }