# Problem Description:
The task is to determine how many particles can pass through all given energy boundaries. Each particle has an initial energy, and each boundary requires a certain amount of energy to be crossed. The energy required to cross a boundary decreases exponentially with each subsequent boundary. Specifically, the energy required to cross the nth boundary is given by the boundary energy divided by 2 raised to the power of n. The function should return the number of particles that successfully pass through all boundaries.

# Visual Facts:
1. **Particle Energies (PE):**
   - Example 1: [49, 35, 21]
   - Example 2: [59, 65, 21, 87, 92]

2. **Boundary Energies (BE):**
   - Example 1: [60, 20]
   - Example 2: [20, 80, 160]

3. **Energy Deduction Formula:**
   - For the nth boundary, the energy deducted is  BE_n / 2^n .
   - For example, a particle starts with 49 energy and the BE_1 is 60, then after crossing the first boundary it has 49-60/2^1=19. For the same reason, if the BE_2 is 20, then after crossing it, it remains 19-20/2^2=14.

4. **Remaining Particles:**
   - Example 1: 1 particle remain after crossing all boundaries.
   - Example 2: 4 particles remain after crossing all boundaries.

# Visual Patterns:
1. **Energy Deduction Calculation:**
   - For each particle, the energy required to cross the nth boundary is calculated as BE_n/2^n.
   - Example 1, Particle index 1:
     - PE1-BE1/2: 49 - 60/2^1  = 49 - 30 = 19
     - PE2-BE2/2^2: 19 -  10/2^2  = 19 - 5 = 14 (remains)
   - Example 1, Particle index 2:
     - PE1-BE1/2: 35 - 60/2^1  = 35 - 30 = 5
     - PE2-BE2/2^2: 5 - 20/2^2  < 0 (does not remain)
   - Example 1, Particle index 3:
     - PE1-BE1/2: 21 - 60/2^1  < 0 (does not remain)
   - So for example 1, only 1 particle remains after crossing all boundaries.

2. **Remaining Particles Calculation:**
   - A particle remains if its energy is greater than zero after crossing all boundaries.
   - Count the number of particles in the input array that remain after crossing all boundaries.
   - Remember, the index of the boundary starts from 1, the first boundary is BE1, it costs BE1/2^1 energy.

# Solution
from typing import List

def solution(particle_energy: List[int], energy_boundary: List[int]) -> int:
    """
    Calculates the number of particles that can pass through all energy boundaries.

    Args:
        particle_energy: A list of energy levels for each particle
        energy_boundary: A list of energy levels for each boundary

    Returns:
        The number of particles that successfully pass through all energy boundaries
    """
    sum_of_bounary = sum([energy_boundary[i] * 0.5 ** (i+1) for i in range(len(energy_boundary))])
    count = 0 
    for i in particle_energy:
        if i > sum_of_bounary:
            count += 1
    return count


# Test Script
def test():
    test_cases = [
        ([59,65,21,87,92],[20,80,160], 4),
        ([49,35,21],[60, 10], 2),
        ([76, 354, 106, 564, 905], [70, 20, 60, 90, 50, 80], 5),
        ([576, 26, 939, 480, 196, 709], [60, 30, 90, 30, 20, 40, 30, 40, 60, 30], 5),
        ([475, 507, 343, 33, 191, 14, 190, 472, 568], [40, 90, 60, 80, 30, 20], 7),
        ([543, 281, 244, 460, 750], [30, 10, 30, 100], 5),
        ([268, 345, 774, 490, 983, 125, 728, 766, 437, 901], [50, 10, 90, 100, 50, 10, 20], 10),
        ([389, 694, 197, 563, 571, 415], [30, 10, 90, 90, 60], 6),
        ([147, 246, 718, 454, 448], [70, 20, 40, 90, 50, 100, 40], 5),
        ([94, 497, 726, 395, 203, 654], [100, 40, 10, 40, 70], 6)
        
    ]

    for particle_energy, energy_boundary, expected_output in test_cases:
        try:
            output = solution(particle_energy, energy_boundary)
        except Exception as e:
            error_message = (
                f"An exception occurred while running the test case:\n"
                f"`particle_energy`: {particle_energy}\n"
                f"`energy_boundary`: {energy_boundary}\n\n"
                f"Exception: '{str(e)}'"
            )
            assert False, error_message

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

test()