# Problem Description
This is a block rearrangement problem where we need to:
- Transform a vertical stack of blocks through a series of operations
- Each operation moves a block from a specified index to the top
- The remaining blocks maintain their relative positions
- Process multiple operations sequentially based on the given operations list
- Return the final arrangement after all operations are completed

# Visual Facts
1. The image shows 3 examples of block transformations:
   - Example 1: 2 blocks (A,B) with operations=[1]
   - Example 2: 3 blocks (A,B,C) with operations=[1]
   - Example 3: 4 blocks (A,B,C,D) with operations=[3,1,3]

2. Each example shows step-by-step transformations:
   - Dotted boxes indicate the block being moved
   - Blue arrows show the movement direction
   - Index positions (Idx) are labeled on both sides (0-based)

3. Initial and final states are shown for each example:
   - Example 1: [B,A] → [A,B]
   - Example 2: [C,B,A] → [B,C,A]
   - Example 3: [D,C,B,A] → [B,D,A,C]

# Visual Patterns
1. Operation Pattern:
   - Each operation takes a block from index i (specified in operations list)
   - The selected block moves to the top position (index 0)
   - All blocks above the selected block shift down one position
   - Blocks below the selected position remain unchanged

2. Sequential Processing:
   - Operations are applied one after another
   - Each operation works on the result of the previous operation
   - Example 3 shows multiple operations (3→1→3) creating intermediate states

3. Index Handling:
   - Indices are 0-based
   - Valid indices range from 0 to (length-1) of the block list
   - The same index can appear multiple times in operations (Example 3)

4. Stack Size:
   - The total number of blocks remains constant throughout operations
   - Only the order changes, no blocks are added or removed

5. Movement Rules:
   - If selecting index 0, no change occurs (block is already at top)
   - When moving a block up, only blocks above the selected position are affected

# Solution
from typing import List

def solution(initial_blocks: List[str], operations: List[int]) -> List[str]:
    """
    return the transformed blocks after applying the operations.   

    Args:
        initial_blocks: List of strings representing the initial blocks
        operations: List of integers representing the operations to be applied

    Returns:
        List of strings representing the blocks after all operations
    """
    current_stack = initial_blocks[:]

    for op in operations:
        # Determine the range of blue blocks based on the last block's index
        k = op   # Include the block at index `op`
        
        if k > len(current_stack):
            raise ValueError(f"Operation {op} cannot be performed on the current stack: {current_stack}")

        # Split the current stack into blue blocks and remaining stack
        blue_blocks = current_stack[:k]
        remaining_stack = current_stack[k:]

        # Move the first block of the remaining stack to the top (if any)
        if remaining_stack:
            block_to_move = remaining_stack.pop(0)
            current_stack = [block_to_move] + blue_blocks + remaining_stack
        else:
            current_stack = blue_blocks

    return current_stack


# Test Script
def test():
    test_cases = [
        (
            ["A", "B", "C"],
            [],
            ["A", "B", "C"]
        ),
        
        (
            ["B1", "C"],
            [1],
            ["C", "B1"]
        ),
        
        (
            ["B1", "B2", "C", "D"],
            [2],
            ["C", "B1", "B2", "D"]
        ),
        
        (
            ["B1", "B2", "C", "D", "E"],
            [2, 2],
            ["B2", "C", "B1", "D", "E"]
        ),
        
        (
            ["B1", "B2"],
            [],
            ["B1", "B2"]
        ),
        
        (
            ["B1", "B2", "C", "D", "E"],
            [2, 2],
            ["B2", "C", "B1", "D", "E"]
        ),
        
        (
            ["B1", "B2", "C", "D", "E", "F"],
            [2, 2, 2],
            ["B1", "B2", "C", "D", "E", "F"]
        ),
        
        (
            ["C", "A", "B", "D"],
            [2, 2],
            ["A", "B", "C", "D"]
        ),
        (
            ["C","B","D","A"],
            [1,3,2],
            ['C', 'A', 'B', 'D']
        )
    ]

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

test()