import numpy as np

"""
Problem 1: Write a function that takes two lists as input and returns a list of booleans that indicate whether each element in the first list is in the second list. For example, if the input lists are [1, 2, 3, 4, 5, 6] and [1, 6, 10, 11], the output should be [True, False, False, False, False, True].
"""
def list_is_in(list1, list2):
    # Convert list2 into a set for O(1) lookups
    set2 = set(list2)
    
    # Use list comprehension to check membership efficiently
    return [item in set2 for item in list1]


"""
Problem 2: Write a function that takes a 2D NumPy array as input and returns a 1D NumPy array containing the mean of each column. For example, if the input array is [[1, 5, 10], [-1, 6, 12], [0, 8, 16]], the output should be [0., 6.33333333, 12.6666667].
"""

def column_mean(arr):
    # Use NumPy's mean function along axis=0 to compute column means
    return np.mean(arr, axis=0)

"""
Problem 3:  Write a function that takes a 2D NumPy array as input and returns a 2D NumPy array where each column is mean-normalized. Mean normalization involves subtracting the mean of each column from each element in that column, and then dividing by the standard deviation of that column. If the standard deviation of a column is 0, the column should be left unchanged. For example, if the input array is [[-0.47752694, 2.10771366, 0.59367963], [-0.99518782, 0.56534531, 0.01539558], [0.44353958, 1.31930398, 2.42232459]], the output should be [[ 0.        ,  0.        , -0.70710678], [-1.        , -1.        , -1.41421356], [ 1.        ,  1.        ,  2.12132034]].
"""

def mean_normalize(arr):
    # Compute column-wise mean and std deviation
    mean = np.mean(arr, axis=0)
    std = np.std(arr, axis=0)
    
    # Normalize each column (avoid division by zero)
    normalized = (arr - mean) / np.where(std != 0, std, 1)
    
    return normalized