# Problem Description
This is a matrix transformation problem where we need to implement a gravity-like shifting mechanism for binary values (0s) in a matrix. Given a matrix of 0s and 1s and a sequence of directional commands (U, R, D, L), we need to shift all 0s in the specified direction until they can't move further, either hitting the boundary or another 0, while maintaining their relative order within each row or column.

# Visual Facts
1. The input is a 3×3 binary matrix
2. The image shows four different transformations:
   - Move "U": Shifts 0s upward
   - Move "D": Shifts 0s downward
   - Move "L": Shifts 0s leftward
   - Move "R": Shifts 0s rightward
3. Each transformation shows:
   - Initial state (matrix representation)
   - Intermediate state (blue squares visualization)
   - Final state (matrix representation)
4. Blue squares represent 0s in the visualization
5. Empty squares represent 1s

# Visual Patterns
1. Movement Rules:
   - All 0s move simultaneously in the specified direction
   - 0s stack against the target edge or against other 0s
     - for example, [0, 1, 1] after applying "R" is [1, 1, 0]
   - The relative order of 0s within each line of movement is preserved
   - No merging or combining of 0s occurs

2. Conservation Properties:
   - The total number of 0s remains constant throughout transformations
   - No new 0s are created or destroyed

3. Stacking Behavior:
   - For vertical movements (U/D):
   * Movement occurs within each column independently
   * 0s stack from the target edge (top for U, bottom for D)
   
   - For horizontal movements (L/R):
   * Movement occurs within each row independently
   * 0s stack from the target edge (left for L, right for R)

4. Empty Space Handling:
   - Spaces vacated by moved 0s are filled with 1s
   - 1s are displaced to the opposite side of the movement direction

# Solution
from typing import List

def solution(matrix: List[List[int]], operations: List[str]) -> List[List[int]]:
    """
    Transforms a matrix by applying a sequence of directional operations.

    Args:
        matrix: A 2D integer matrix (size M*N) represented as a list of lists.
        operations: A list of operations encoded as strings ("L", "R", "U", "D").

    Returns:
        The transformed matrix after applying all operations in sequence.
    """
    rows = len(matrix)
    cols = len(matrix[0])
    
    def move_up(mat):
        """Move all 0s up."""
        for col in range(cols):
            stack = [mat[row][col] for row in range(rows) if mat[row][col] == 0]  # Collect 0s
            for row in range(rows):
                mat[row][col] = 0 if row < len(stack) else 1  # Fill 0s from the top
        return mat

    def move_down(mat):
        """Move all 0s down."""
        for col in range(cols):
            stack = [mat[row][col] for row in range(rows) if mat[row][col] == 0]  # Collect 0s
            for row in range(rows):
                mat[row][col] = 0 if row >= rows - len(stack) else 1  # Fill 0s from the bottom
        return mat

    def move_left(mat):
        """Move all 0s left."""
        for row in range(rows):
            stack = [mat[row][col] for col in range(cols) if mat[row][col] == 0]  # Collect 0s
            for col in range(cols):
                mat[row][col] = 0 if col < len(stack) else 1  # Fill 0s from the left
        return mat

    def move_right(mat):
        """Move all 0s right."""
        for row in range(rows):
            stack = [mat[row][col] for col in range(cols) if mat[row][col] == 0]  # Collect 0s
            for col in range(cols):
                mat[row][col] = 0 if col >= cols - len(stack) else 1  # Fill 0s from the right
        return mat

    # Apply each operation in sequence
    for op in operations:
        if op == "U":
            matrix = move_up(matrix)
        elif op == "D":
            matrix = move_down(matrix)
        elif op == "L":
            matrix = move_left(matrix)
        elif op == "R":
            matrix = move_right(matrix)
    
    return matrix


# Test Script
def test():
    test_cases = [
        {
            "matrix": [
                [1, 0, 0],
                [1, 0, 1],
                [1, 1, 1]
            ],
            "operations": ["U"],
            "expected": [[1, 0, 0], [1, 0, 1], [1, 1, 1]]
        },
        {
            "matrix": [
                [1, 0, 0],
                [0, 1, 0],
                [1, 1, 1]
            ],
            "operations": ["R"],
            "expected":  [[1, 0, 0], [1, 0, 0], [1, 1, 1]]
        },
        {
            "matrix": [
                [1, 0, 0],
                [0, 1, 0],
                [1, 1, 1]
            ],
            "operations": ["D", "L"],
            "expected": [[1, 1, 1], [0, 1, 1], [0, 0, 0]]
        },
        {
            "matrix": [
                [1, 0, 0],
                [1, 0, 1],
                [1, 1, 1]
            ],
            "operations": ["U","L","D","R"],
            "expected": [[1, 1, 1], [1, 1, 0], [1, 0, 0]]
        },
        {
            "matrix": [
                [1, 1, 1],
                [0, 1, 1],
                [0, 0, 1]
            ],
            "operations": ["D","L"],
            "expected": [[1, 1, 1], [0, 1, 1], [0, 0, 1]]
        },
        {
            "matrix": [
                [1, 1, 1],
                [0, 1, 1],
                [0, 0, 1]
            ],
            "operations": ["D","L","R","U"],
            "expected": [[1, 0, 0], [1, 1, 0], [1, 1, 1]]
        },
        {
            "matrix": [
                [1, 1, 1],
                [0, 0, 1],
                [1, 0, 1]
            ],
            "operations": ["D","R"],
            "expected":  [[1, 1, 1], [1, 1, 0], [1, 0, 0]]
        },
        {
            "matrix": [
                [1, 1, 1, 1, 0],
                [0, 0, 1, 0, 0],
                [1, 0, 1, 1, 1],
                [1, 0, 0, 1, 1]
            ],
            "operations": ["D","R","U"],
            "expected": [[0, 0, 0, 0, 0], [1, 1, 1, 0, 0], [1, 1, 1, 1, 0], [1, 1, 1, 1, 1]]
        },
                {
            "matrix": [
                [1, 1, 1, 1, 0],
                [0, 0, 1, 0, 0],
                [1, 0, 1, 1, 1],
                [1, 0, 0, 1, 1]
            ],
            "operations": ["D","R","U","L"],
            "expected": [[0, 0, 0, 0, 0], [0, 0, 1, 1, 1], [0, 1, 1, 1, 1], [1, 1, 1, 1, 1]]
        },
                {
            "matrix": [
                [1, 1, 1, 1, 0],
                [0, 0, 1, 0, 0],
                [1, 0, 1, 1, 1],
                [1, 0, 0, 1, 1]
            ],
            "operations": ["D","D","R","U"],
            "expected": [[0, 0, 0, 0, 0], [1, 1, 1, 0, 0], [1, 1, 1, 1, 0], [1, 1, 1, 1, 1]]
        },
    ]

    for i, test_case in enumerate(test_cases, start=1):
        matrix = test_case["matrix"]
        operations = test_case["operations"] 
        expected_output = test_case["expected"]
        
        try:
            output = solution(matrix, operations)
        except Exception as e:
            error_message = (
                f"An exception occurred while running the test case:\n"
                f"`matrix`: {matrix}\n"
                f"`operations`: {operations}\n\n"
                f"Exception: '{str(e)}'"
            )
            assert False, error_message

        if output != expected_output:
            error_message = (
                f"The following Test Case failed:\n"
                f"`matrix`: {matrix}\n"
                f"`operations`: {operations}\n\n"
                f"Actual Output: {output}\n"
                f"Expected Output: {expected_output}"
            )
            assert False, error_message

test()