# Problem Description
This is a water flow simulation problem in a pyramid-like cup structure. Water is poured continuously from the top, and when a cup is full, it overflows equally to the two cups below it. The task is to calculate how many layers of cups are completely filled at a given time point.

# Visual Facts
1. Cup Arrangement:
   - Cups are arranged in a pyramid structure
   - Each layer has more cups than the one above it
   - Each cup can overflow into two cups below it

2. Time Snapshots:
   - t=0: Initial state, 0 full cups
   - t=8: 1 cup full (top layer cup)
   - t=24: 3 cups full (top cup + 2 second-layer cups)
   - t=56: 6 cups full (top cup + 2 second-layer cups + 3 third-layer cups)

# Visual Patterns
1. Flow Pattern:
   - Water starts from the top cup
   - When a cup is full, it splits water equally to cups below
   - Cups fill gradually and maintain their filled state

2. Mathematical Patterns:
   - Fill rate appears to be constant (8 time units for filling one cup)
   - Each layer takes progressively longer to fill (8, 16, 32, ...)
   - The time consumed on each layer follows the formula: time = 8 * 2 ** （layer_idx - 1）, where layer_idx is the index of the layer (starting from 1).

# Solution
def solution(end_time: int) -> int:
    """
    Calculate how many layers of cups have been full-filled by the given end time.

    Input:
    - end_time: the given end time.

    Output:
    - the total numbers of full-filled layers.
    """
    layers_filled = 0
    total_time = 0
    while True:
        time_for_next_layer = 8 * 2 ** layers_filled
        total_time += time_for_next_layer
        if total_time > end_time:
            break
        layers_filled += 1
    return layers_filled


# Test Script
def test():
    test_cases = [
        (1*8, 1),
        (2*8, 1),
        (3*8, 2),
        (4*8, 2),
        (5*8, 2),
        (7*8, 3),
        (9*8, 3),
        (25*8, 4),
        (30*8, 4),
        (50*8, 5),
        (70*8, 6),
        (100*8, 6),
    ]
    for i, (end_time, expected_output) in enumerate(test_cases):
        try:
            output = solution(end_time)
        except Exception as e:
            error_message = (
                f"An exception occurred while running the test case:\n"
                f"`end_time`: {end_time}\n\n"
                f"Exception: '{str(e)}'"
            )
            assert False, error_message

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

test()