# Problem Description
This is a matrix traversal problem where we need to:
- Start from the top-right corner of a given matrix
- Follow a specific spiral pattern in counter-clockwise direction
- Collect all elements in the order of traversal
- The traversal pattern should work for matrices of different sizes (MxN)

# Visual Facts
1. Four example matrices are shown with different dimensions:
   - 4x1 (top-right)
   - 4x2 (top-left)
   - 4x3 (bottom-left)
   - 4x4 (bottom-right)
2. Each matrix is numbered sequentially from 1 to maximum cells (N×M)
3. Arrows indicate the direction of traversal
4. Starting point is always at position (0, N-1) (top-right corner)
5. Initial movement is always leftward

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

2. Traversal Rules:
   - First move: Always move left along the top row
   - Each cell is visited exactly once
   - When can't move in current direction, rotate counter-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 top <= bottom and left <= right:
        # Traverse from right to left
        for i in range(right, left - 1, -1):
            result.append(matrix[top][i])
        top += 1

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

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

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

    return result


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