# Problem Description
The problem requires implementing a matrix traversal function that follows a specific spiral pattern. Given a matrix of M x N dimensions, we need to return the elements in a specific order that follows a spiral path starting from the bottom-right corner, moving initially leftward, and then following a clockwise spiral pattern towards the inside of the matrix.

# Visual Facts
1. The image shows 4 different matrix examples:
   - 4x1 matrix (top-right)
   - 4x2 matrix (top-left)
   - 4x3 matrix (bottom-left)
   - 4x4 matrix (bottom-right)
2. Each matrix is numbered sequentially from 1 to its size (4, 8, 12, or 16)
3. Arrows indicate the direction of traversal
4. All examples start from the bottom-right corner

# Visual Patterns
1. Movement Direction Pattern:
   - Follows a consistent sequence: Left → Up → Right → Down → Left → ...
   - Arrows show the traversal direction changes at boundaries or visited cells

2. Traversal Rules:
   - First move: Always move left along the bottom row
   - Each cell is visited exactly once
   - When can't move in current direction, rotate clockwise
   - Forms a spiral pattern inward
   - Continue until all cells are visited


# Solution
from typing import List


def solution(matrix: List[List[int]]) -> List[int]:
    """
    Given an M x N 2D matrix, traverse the matrix according to the spiral pattern shown in the figure

    Parameters:
    matrix (List[List[int]]): A 2D list of integers representing the matrix.

    Returns:
    List[int]: A list of integers representing the elements of the matrix in the order as shown in the picture.
    """
    result = []
    top, bottom = 0, len(matrix) - 1
    left, right = 0, len(matrix[0]) - 1

    while bottom >= top and left <= right:
        # Traverse from right to left
        for i in range(right, left - 1, -1):
            result.append(matrix[bottom][i])
        bottom -= 1

        # Traverse from bottom to top
        for i in range(bottom, top - 1, -1):
            result.append(matrix[i][left])
        left += 1

        if bottom >= top:
            # Traverse from left to right
            for i in range(left, right + 1):
                result.append(matrix[top][i])
            top += 1

        if left <= right:
            # Traverse from top to bottom
            for i in range(top, bottom + 1):
                result.append(matrix[i][right])
            right -= 1

    return result


# Test Script
def test():
    test_cases = [
        ([[1, 2]], [2, 1]),
        ([[1, 2], [3, 4]], [4, 3, 1, 2]),
        ([[1, 2, 3], 
          [4, 5, 6], 
          [7, 8 , 9]], [9, 8, 7, 4, 1, 2, 3, 6, 5]),
        ([[1,2,3,4],
          [5,6,7,8],
          [9,10,11,12]], [12, 11, 10, 9, 5, 1, 2, 3, 4, 8, 7, 6]),
        ([[1, 3, 5, 6, 2], 
          [43, 23, 19, 22, 33], 
          [12, 11, 6, 8, 4]], [4, 8, 6, 11, 12, 43, 1, 3, 5, 6, 2, 33, 22, 19, 23]),
        ([[1, 2], 
          [3, 4], 
          [5, 6], 
          [7, 8]], [8, 7, 5, 3, 1, 2, 4, 6]),
        ([[1, 2, 3, 4, 5, 6, 7], 
          [8, 9, 10, 11, 12, 13, 14]], [14, 13, 12, 11, 10, 9, 8, 1, 2, 3, 4, 5, 6, 7]),
        ([[1, 2, 3, 4, 5, 6, 7, 8], 
          [13, 24, 32, 41, 54, 65, 76, 87], 
          [43, 2, 87, 5, 4, 66, 13, 94], 
          [0, 12, 87, 43, 56, 36, 92, 44], 
          [32, 33, 34, 55, 56, 72, 73, 77]], [77, 73, 72, 56, 55, 34, 33, 32, 0, 43, 13, 1, 2, 3, 4, 5, 6, 7, 8, 87, 94, 44, 92, 36, 56, 43, 87, 12, 2, 24, 32, 41, 54, 65, 76, 13, 66, 4, 5, 87]),
        ([[1, 3, 5], 
          [7, 9, 11], 
          [2, 4, 6], 
          [8, 10, 14]], [14, 10, 8, 2, 7, 1, 3, 5, 11, 6, 4, 9]),
        ([[1, 2, 3, 4, 5, 6], 
          [7, 8, 9, 10, 11, 17],
          [13, 15, 16, 19, 20, 91]], [91, 20, 19, 16, 15, 13, 7, 1, 2, 3, 4, 5, 6, 17, 11, 10, 9, 8]),
    ]

    for i, (matrix, expected_output) in enumerate(test_cases):
        original_matrix = [row.copy() for row in matrix]
        try:
            output = solution(matrix)
        except Exception as e:
            error_message = (
                f"An exception occurred while running the test case:\n"
                f"`matrix`: {original_matrix}\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`: {original_matrix}\n\n"
                f"Actual Output: {output}\n"
                f"Expected Output: {expected_output}"
            )
            assert False, error_message

test()