2

I’m trying to shift the elements of a 2D array to the right and down by one position without using an additional temporary array. Here’s the current implementation using a temporary array:

public static void TransformArray(int[,] matrix)
{
    int row = matrix.GetLength(0);
    int col = matrix.GetLength(1);
    
    int[,] tempMatrix = new int[row, col];
    
    for (int i = 0; i < row; ++i)
    {
        for (int j = 0; j < col; ++j)
        {
            tempMatrix[(i + 1) % row, (j + 1) % col] = matrix[i, j];
        }
    }

    for (int i = 0; i < row; ++i)
    {
        for (int j = 0; j < col; ++j)
        {
            matrix[i, j] = tempMatrix[i, j];
        }
    }
}

public static void Main(string[] args)
{
    int[,] matrix = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    TransformArray(matrix);

    // Output the transformed matrix
    for (int i = 0; i < matrix.GetLength(0); ++i)
    {
        for (int j = 0; j < matrix.GetLength(1); ++j)
        {
            Console.Write(matrix[i, j] + " ");
        }
        Console.WriteLine();
    }
}

I would like to avoid using tempMatrix and perform the transformation in-place. Is there an efficient way to do this in C#? Any suggestions or optimizations would be appreciated.

4
  • Why do you bother copying the temp back to the original? Why not just return the temp and use it? Commented Jun 17, 2024 at 12:42
  • What's the expected output? Should the data wrap around? What you ask looks like a Translation transformation in graphics, something available out of the box for 3x2 and 4x4 matrices Commented Jun 17, 2024 at 13:04
  • @flackoverstow I want to modify the original array that is passed as a parameter to the function, which is why I am copying the temporary array back to the original one and returning void. The goal is to ensure that the original array matrix reflects the changes after the function call, without needing to rely on the function’s return value. Commented Jun 17, 2024 at 13:10
  • @PanagiotisKanavos [Original] int[,] matrix = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; [Transformed] matrix = { {9, 1, 2}, {3, 4, 5}, {6, 7, 8} }; Each element is shifted to the position (i + 1) % row, (j + 1) % col, causing the elements to wrap around as described. Commented Jun 17, 2024 at 13:12

1 Answer 1

3

The operation you are doing seems to be equivalent to shifting all the rows to the right, and wrap around the values at the end, then shifting all the columns downwards, and also wrap around the values at the end.

After you break it down like this, it is easy to write a ShiftRow and a ShiftColumn helper functions, without creating new arrays. You are just shifting one row/column after all.

public static void TransformArray(int[,] matrix)
{
    int row = matrix.GetLength(0);
    int col = matrix.GetLength(1);
    
    void ShiftRow(int rowIndex) {
        var last = matrix[rowIndex, col - 1];
        for (int i = col - 1 ; i > 0 ; i--) {
            matrix[rowIndex, i] = matrix[rowIndex, i - 1]; 
        }
        matrix[rowIndex, 0] = last;
    }
    
    void ShiftColumn(int colIndex) {
        var last = matrix[row - 1, colIndex];
        for (int i = row - 1 ; i > 0 ; i--) {
            matrix[i, colIndex] = matrix[i - 1, colIndex]; 
        }
        matrix[0, colIndex] = last;
    }
    
    for (int i = 0 ; i < row ; i++) {
        ShiftRow(i);
    }
    for (int i = 0 ; i < col ; i++) {
        ShiftColumn(i);
    }
}

You don't actually need them to be inner methods. I just find this way to be more readable. Inline them if you like.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for breaking down the operation in such a clear and concise manner! Your approach of using ShiftRow and ShiftColumn helper functions to shift rows to the right and columns downward without creating new arrays is very insightful. I appreciate the suggestion and agree that this divide-and-conquer approach simplifies the problem significantly. Thanks for the valuable input!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.