Kiran Sachdeva
Kiran Sachdeva

Reputation: 29

Matrix rotation in anti clockwise and clockwise

please help me to solve the below problem in java to rotate the outer ring of matrix in anticlockwise by k element and inner ring in clockwise by k element in java and the middle element remains constant. The sample input is m=5,n=6,k=1 where m is no of rows,n is no of column and k is the number of required shift and the input matrix is

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 and the expected output is

2 3 4 5 6 12 1 14 8 9 10 18 7 20 15 16 11 24 13 21 22 23 17 30 19 25 26 27 28 29

Can someone tell how to proceed for this problem as we need to do clockwise and anticlockwise both.

Upvotes: 1

Views: 482

Answers (1)

Axel Kemper
Axel Kemper

Reputation: 11322

My solution copies one ring of matrix cells at a time. The rings are traversed step by step. For every step a case number is calculated by checking row and columns against the borders of the ring:

package ak.matrixTurn;

public class Main {

    public static void main(String[] args) {
        int rows = 5;
        int cols = 6;
        int delta = 1;
        int[][] matrix = new int[rows][cols];
        int[][] turned = new int[rows][cols];

        //  fill matrix
        for (int r = 0; r < rows; r++) {
            for (int c = 0; c < cols; c++) {
                matrix[r][c] = r * cols + c + 1;
            }
        }

        //  copy 1:1 (not turned yet)
        for (int r = 0; r < rows; r++) {
            for (int c = 0; c < cols; c++) {
                turned[r][c] = matrix[r][c];
            }
        }

        ringTurn(matrix, turned, 0, delta);
        ringTurn(matrix, turned, 1, -delta);

        ShowMatrix(matrix);
        ShowMatrix(turned);

        System.out.println("Ciao!");
    }

    //  helper class represents a row/col pair
    static class RowCol {
        int row;
        int col;
        int left;
        int top;
        int right;
        int bottom;

        RowCol(int ring, int rows, int cols) {
            row = ring;
            col = ring;
            left = ring;
            top = ring;
            right = ring + cols - 1;
            bottom = ring + rows - 1;
        }

        //  one step anti-clockwise along our ring
        void Advance() {
            switch(GetCase())
            {
                case LEFT:          //  left col
                case TOP+LEFT:      //  top-left corner
                    row++; break;
                case RIGHT:         //  right col
                case BOTTOM+RIGHT:  //  bottom-right corner
                    row--; break;
                case BOTTOM:        //  bottom row
                case BOTTOM+LEFT:   //  bottom-left corner
                    col++; break;
                case TOP:           //  top row
                case TOP+RIGHT:     //  top-right corner
                    col--; break;
            }
        }

        //  cryptic but shorter version of Advance()
        void Advance2() {
            row += PlusMinus("+-   -  + ");
            col += PlusMinus("   ++  - -");
        }

        //  return -1 for "-", +1 for "+"
        //  at 1-based string position r
        int PlusMinus(String s) {
            int r = GetCase();
            char c = s.charAt(r - 1);

            return "- +".indexOf(c) - 1;
        }

        //  one step back on our ring
        void Retract() {
            switch(GetCase())
            {
                case LEFT:         //  left col
                case BOTTOM+LEFT:  //  bottom-left corner
                    row--; break;
                case RIGHT:        //  right col
                case TOP+RIGHT:    //  top-right corner
                    row++; break;
                case BOTTOM:       //  bottom row
                case BOTTOM+RIGHT: //  bottom-right corner
                    col--; break;
                case TOP:          //  top row
                case TOP+LEFT:     //  top-left corner
                    col++; break;
            }
        }

        //  cryptic but shorter version of Retract()
        void Retract2() {
            row += PlusMinus("-+  -    +");
            col += PlusMinus("   - - ++ ");
        }

        private int b2x(boolean b, int x) {
            return b ? x : 0;
        }

        static final int LEFT   = (1 << 0);
        static final int RIGHT  = (1 << 1);
        static final int BOTTOM = (1 << 2);
        static final int TOP    = (1 << 3);

        //  determine where we are on the ring
        int GetCase() {
            int r = b2x(col == left, LEFT)
                  + b2x(col == right, RIGHT)
                  + b2x(row == bottom, BOTTOM)
                  + b2x(row == top, TOP);

            //  we have to stay on our ring
            assert r != 0;

            return r;
        }
    }  //  end of class RowCol

    //  copy all cells in ring from src to dest
    //  apply delta offset (> 0 if anti-clockwise)
    static void ringTurn(int[][] src, int[][] dest, int ring, int delta) {
        int cols = src[0].length - 2 * ring;
        int rows = src.length - 2 * ring;

        //  in-place turns are forbidden
        assert dest != src;

        //  matrices have to match in their size
        assert dest[0].length == src[0].length;
        assert dest.length == src.length;

        if ((rows > 1) && (cols > 1)) {
            RowCol srcRC = new RowCol(ring, rows, cols);
            RowCol destRC = new RowCol(ring, rows, cols);

            //  position the destination location
            for (int i = 0; i < Math.abs(delta); i++) {
                if (delta > 0) {
                    destRC.Advance2();
                } else {
                    destRC.Retract2();
                }
            }

            //  perform the copy operation
            //  by moving both locations along the ring
            int steps = 2 * (rows + cols - 2);

            for (int step = 0; step < steps; step++) {
                dest[destRC.row][destRC.col] = src[srcRC.row][srcRC.col];
                destRC.Advance2();
                srcRC.Advance2();
            }
        }
    }

    static void ShowMatrix(int[][] matrix) {
        int cols = matrix[0].length;

        System.out.println();

        for (int[] ints : matrix) {
            StringBuilder s = new StringBuilder();

            for (int col = 0; col < cols; col++) {
                s.append(String.format("%3d", ints[col]));
            }

            System.out.println(s);
        }
    }
}

Output:

  1  2  3  4  5  6
  7  8  9 10 11 12
 13 14 15 16 17 18
 19 20 21 22 23 24
 25 26 27 28 29 30

  2  3  4  5  6 12
  1 14  8  9 10 18
  7 20 15 16 11 24
 13 21 22 23 17 30
 19 25 26 27 28 29

Upvotes: 1

Related Questions