# Problem Description
This is a matrix traversal problem where we need to implement a specific "snake-like" pattern traversal of a square matrix (N x N). The traversal follows a vertical zigzag pattern, moving down and up through columns while progressing from left to right. The function should return the elements in the order they are visited during this traversal.

# Visual Facts
1. The image shows a 3x3 matrix represented as nodes numbered from 1 to 9
2. The nodes are connected by purple arrows showing the traversal direction
3. The matrix elements are arranged in a grid pattern (3 rows × 3 columns)
4. The arrows show three distinct vertical paths:
   - First column: 1 → 4 → 7 (downward movement)
   - Second column: 8 → 5 → 2 (upward movement)
   - Third column: 3 → 6 → 9 (downward movement)
5. This snake pattern creates a specific traversal order: [1, 4, 7, 8, 5, 2, 3, 6, 9] for this 3x3 matrix.

# Visual Patterns
1. Column-wise Movement Pattern:
   - Odd-numbered columns (1st, 3rd, etc.): Movement is strictly downward
   - Even-numbered columns (2nd, etc.): Movement is strictly upward

2. Traversal Direction Pattern:
   - The overall progression is from left to right
   - Each vertical segment alternates between downward and upward movement
   - When reaching the bottom or top of a column, it moves to the next column

3. Sequential Rules:
   - Start from the top-left element (1)
   - The pattern ensures each element is visited exactly once

4. Boundary Pattern:
   - When reaching the bottom row in a downward movement, move right
   - When reaching the top row in an upward movement, move right
   - The pattern continues until reaching the last element


# Solution
def solution(matrix: list[list[int]]) -> list[int]:
    """
    Traverses a given matrix according to the snake pattern shown in the figure.
    
    Parameters:
        matrix (list[list[int]]): A 2D list (N x N matrix) containing integers that need to be traversed.
    
    Returns:
        list[int]: A list of integers representing the traversed elements.
    """
    result = []
    N = len(matrix)

    for col in range(N):
        if col % 2 == 0:
            for row in range(N):
                result.append(matrix[row][col])
        
        else:
            for row in range(N-1, -1, -1):
                result.append(matrix[row][col])
    
    return result


# Test Script
def test():
    test_cases = [
        ([[1, 2], [3, 4]], [1, 3, 4, 2]),
        ([[9, 9, 9], [9, 9, 9], [9, 9, 9]], [9, 9, 9, 9, 9, 9, 9, 9, 9]),
        ([[99, 102], [672, 5]], [99, 672, 5, 102]),
        ([[1, 2, 3], [4, 5, 6], [7, 8, 9]], [1, 4, 7, 8, 5, 2, 3, 6, 9]),
        ([[63, 22, 17], [98, 21, 3], [76, 33, 9]], [63, 98, 76, 33, 21, 22, 17, 3, 9]),
        ([[53, 54, 55], [56, 57, 58], [59, 60, 61]], [53, 56, 59, 60, 57, 54, 55, 58, 61]),
        ([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]], [1, 5, 9, 13, 14, 10, 6, 2, 3, 7, 11, 15, 16, 12, 8, 4]),
        ([[54, 39, 74, 11], [8, 43, 13, 27], [73, 18, 45, 9], [63, 67, 30, 40]], [54, 8, 73, 63, 67, 18, 43, 39, 74, 13, 45, 30, 40, 9, 27, 11]),
        ([[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]],
         [1, 6, 11, 16, 21, 22, 17, 12, 7, 2, 3, 8, 13, 18, 23, 24, 19, 14, 9, 4, 5, 10, 15, 20, 25]),
        ([[21, 23, 98, 76, 33], [63, 67, 30, 40, 5], [73, 18, 45, 9, 2], [8, 43, 13, 27, 1], [98, 77, 23, 11, 9]],
         [21, 63, 73, 8, 98, 77, 43, 18, 67, 23, 98, 30, 45, 13, 23, 11, 27, 9, 40, 76, 33, 5, 2, 1, 9]),
        
    ]

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

test()