def has_close_elements(numbers: List[float], threshold: float) -> bool:
    """Check if in given list of numbers, are any two numbers closer to each other than
    given threshold.
    >>> has_close_elements([1.0, 2.0, 3.0], 0.5)
    False
    >>> has_close_elements([1.0, 2.8, 3.0, 4.0, 5.0, 2.0], 0.3)
    True
    """
    for (idx, elem) in enumerate(numbers):
        for (idx2, elem2) in enumerate(numbers):
            if idx != idx2:
                distance = abs(elem - elem2)
                if distance < threshold:
                    return True
    return False

def has_close_elements_in_array(array: List[List[float]], threshold: float) -> bool:
    """Check if in given array, are any two numbers closer to each other than given threshold.
    >>> has_close_elements_in_array([[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], 0.5)
    True
    >>> has_close_elements_in_array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], 0.3)
    False
    """
    return has_close_elements([item for sublist in array for item in sublist], threshold)


def separate_paren_groups(paren_string: str) -> List[str]:
    """Input to this function is a string containing multiple groups of nested parentheses. Your goal is to
    separate those group into separate strings and return the list of those.
    Separate groups are balanced (each open brace is properly closed) and not nested within each other
    Ignore any spaces in the input string.
    >>> separate_paren_groups('( ) (( )) (( )( ))')
    ['()', '(())', '(()())']
    """
    result = []
    current_string = []
    current_depth = 0
    for c in paren_string:
        if c == '(':
            current_depth += 1
            current_string.append(c)
        elif c == ')':
            current_depth -= 1
            current_string.append(c)
            if current_depth == 0:
                result.append(''.join(current_string))
                current_string.clear()
    return result

def nested_separate_paren_groups(paren_string: str) -> Any:
    """Input to this function is a string containing multiple groups of nested parentheses. Your goal is to
    separate those group into separate strings and return the list of those.
    Different from separate_paren_groups, you have to recursively separate a group into subgroups if it is nested.
    Separate groups are balanced (each open brace is properly closed) and nested within each other
    Ignore any spaces in the input string.
    >>> nested_separate_paren_groups('( ) (( )) (( )( ))')
    ['()', ['()'], ['()', '()']]
    """
    print(paren_string)
    groups = separate_paren_groups(paren_string)
    for idx in range(len(groups)):
        if groups[idx] == '()':
            continue
        else:
            groups[idx] = nested_separate_paren_groups(groups[idx][1:-1])
    return groups


def truncate_number(number: float) -> float:
    """Given a positive floating point number, it can be decomposed into
    and integer part (largest integer smaller than given number) and decimals
    (leftover part always smaller than 1).

    Return the decimal part of the number.
    >>> truncate_number(3.5)
    0.5
    """
    return number % 1.0

def is_number_rounded_up(number: float) -> bool:
    """Given a positive floating point number, return True if the number is
    rounded up, False otherwise.
    >>> is_number_rounded_up(3.5)
    True
    >>> is_number_rounded_up(3.4)
    False
    """
    return truncate_number(number) >= 0.5

def check(candidate):
    assert candidate(4.2) is False
    assert candidate(3.141592) is False
    assert candidate(19.865) is True
    assert candidate(1.501) is True

def test_check():
    check(is_number_rounded_up)

test_check()


def below_zero(operations: List[int]) -> bool:
    """You're given a list of deposit and withdrawal operations on a bank account that starts with
    zero balance. Your task is to detect if at any point the balance of account fallls below zero, and
    at that point function should return True. Otherwise it should return False.
    >>> below_zero([1, 2, 3])
    False
    >>> below_zero([1, 2, -4, 5])
    True
    """
    balance = 0
    for op in operations:
        balance += op
        if balance < 0:
            return True
    return False

def below_zero_with_initial_value(operations: List[int], initial: int) -> bool:
    """You're given a list of deposit and withdrawal operations on a bank account that starts with
    non-negative initial balance. Your task is to detect if at any point the balance of account fallls
    below zero, and at that point function should return True. Otherwise it should return False.
    >>> below_zero_with_initial_value([1, 2, 3], 0)
    False
    >>> below_zero_with_initial_value([1, 2, -4, 5], 3)
    False
    """
    return below_zero([initial] + operations)

def check(candidate):
    assert candidate([3, -15, 4, 2, 1], 14) is False
    assert candidate([-2, -3, -4, -5], 14) is False
    assert candidate([2, -4, 3], 1) is True
    assert candidate([1, 2, -4, 5], 0) is True

def test_check():
    check(below_zero_with_initial_value)

test_check()


def mean_absolute_deviation(numbers: List[float]) -> float:
    """For a given list of input numbers, calculate Mean Absolute Deviation
    around the mean of this dataset.
    Mean Absolute Deviation is the average absolute difference between each
    element and a centerpoint (mean in this case):
    MAD = average | x - x_mean |
    >>> mean_absolute_deviation([1.0, 2.0, 3.0, 4.0])
    1.0
    """
    mean = sum(numbers) / len(numbers)
    return sum((abs(x - mean) for x in numbers)) / len(numbers)

def find_outlier(numbers: List[float]) -> List[float]:
    """For a given list of input numbers, find the outlier.
    Outliers are defined as data whose distance from the mean is greater than
    the mean absolute deviation.
    The order of the outliers in the output list should be the same as in the input list.
    >>> find_outlier([1.0, 2.0, 3.0, 4.0])
    [1.0, 4.0]
    """
    mean = sum(numbers) / len(numbers)
    mae = mean_absolute_deviation(numbers)
    return [number for number in numbers if abs(number - mean) > mae]

def check(candidate):
    assert candidate([3.0, 2.0, 1.0, 4.0]) == [1.0, 4.0]
    assert candidate([1.0, 5.0]) == []
    assert candidate([-5.0, 1.0, 0.0, 1.0]) == [-5.0]
    assert candidate([1, 2, -4, 5]) == [-4, 5]

def test_check():
    check(find_outlier)

test_check()


def intersperse(numbers: List[int], delimeter: int) -> List[int]:
    """Insert a number 'delimeter' between every two consecutive elements of input list `numbers'
    >>> intersperse([], 4)
    []
    >>> intersperse([1, 2, 3], 4)
    [1, 4, 2, 4, 3]
    """
    if not numbers:
        return []
    result = []
    for n in numbers[:-1]:
        result.append(n)
        result.append(delimeter)
    result.append(numbers[-1])
    return result

def intersperse_with_start_end(numbers: List[int], delimeter: int) -> List[int]:
    """Insert a number 'delimeter' between every two consecutive elements of input list `numbers'
    and also add 'delimeter' at the beginning and end of the list.
    >>> intersperse_with_start_end([], 4)
    [4, 4]
    >>> intersperse_with_start_end([1, 2, 3], 4)
    [4, 1, 4, 2, 4, 3, 4]
    """
    return [delimeter] + intersperse(numbers, delimeter) + [delimeter]


def parse_nested_parens(paren_string: str) -> List[int]:
    """Input to this function is a string represented multiple groups for nested parentheses separated by spaces.
    For each of the group, output the deepest level of nesting of parentheses.
    E.g. (()()) has maximum two levels of nesting while ((())) has three.

    >>> parse_nested_parens('(()()) ((())) () ((())()())')
    [2, 3, 1, 3]
    """

    def parse_paren_group(s):
        depth = 0
        max_depth = 0
        for c in s:
            if c == '(':
                depth += 1
                max_depth = max(depth, max_depth)
            else:
                depth -= 1
        return max_depth
    return [parse_paren_group(x) for x in paren_string.split(' ') if x]

def remove_nested_parens(paren_string: str) -> str:
    """Input to this function is a string represented multiple groups for nested parentheses separated by spaces.
    Filter out the group whose deepest level of nesting of parentheses is greater than 2.
    E.g. (()()) has maximum two levels of nesting while ((())) has three.

    >>> remove_nested_parens('(()()) ((())) () ((())()())')
    '(()()) ()'
    """
    depths = parse_nested_parens(paren_string)
    return ' '.join((group for (group, depth) in zip(paren_string.split(), depths) if depth <= 2))


def filter_by_substring(strings: List[str], substring: str) -> List[str]:
    """Filter an input list of strings only for ones that contain given substring
    >>> filter_by_substring([], 'a')
    []
    >>> filter_by_substring(['abc', 'bacd', 'cde', 'array'], 'a')
    ['abc', 'bacd', 'array']
    """
    return [x for x in strings if substring in x]

def filter_by_substrings(strings: List[str], substrings: List[str]) -> List[str]:
    """Filter an input list of strings only for ones that contain all of given substrings
    >>> filter_by_substrings([], ['a', 'b'])
    []
    >>> filter_by_substrings(['abc', 'bacd', 'cde', 'array'], ['a', 'b'])
    ['abc', 'bacd']
    """
    for substring in substrings:
        strings = filter_by_substring(strings, substring)
    return strings

def check(candidate):
    assert candidate(['prefix', 'suffix', 'infix'], ['fix', 'pre']) == ['prefix']
    assert candidate(['prefix', 'suffix', 'infix'], ['fix', 'pre', 'in']) == []
    assert candidate(['hot', 'cold', 'warm'], ['o']) == ['hot', 'cold']
    assert candidate(['abcdef', 'aboekxdeji', 'abekfj'], ['ab', 'de']) == ['abcdef', 'aboekxdeji']

def test_check():
    check(filter_by_substrings)

test_check()


def sum_product(numbers: List[int]) -> Tuple[int, int]:
    """For a given list of integers, return a tuple consisting of a sum and a product of all the integers in a list.
    Empty sum should be equal to 0 and empty product should be equal to 1.
    >>> sum_product([])
    (0, 1)
    >>> sum_product([1, 2, 3, 4])
    (10, 24)
    """
    sum_value = 0
    prod_value = 1
    for n in numbers:
        sum_value += n
        prod_value *= n
    return (sum_value, prod_value)

def product_sum(numbers: List[int]) -> Tuple[int, int]:
    """For a given list of integers, return a tuple consisting of a product and a sum of all the integers in a list.
    Empty sum should be equal to 0 and empty product should be equal to 1.
    >>> product_sum([])
    (1, 0)
    >>> product_sum([1, 2, 3, 4])
    (24, 10)
    """
    (s, p) = sum_product(numbers)
    return (p, s)

def check(candidate):
    assert candidate([]) == (1, 0)
    assert candidate([4, 3, 0, 8]) == (0, 15)
    assert candidate([9, 2]) == (18, 11)
    assert candidate([100, 101, 102]) == (1030200, 303)

def test_check():
    check(product_sum)

test_check()


def rolling_max(numbers: List[int]) -> List[int]:
    """From a given list of integers, generate a list of rolling maximum element found until given moment
    in the sequence.
    >>> rolling_max([1, 2, 3, 2, 3, 4, 2])
    [1, 2, 3, 3, 3, 4, 4]
    """
    running_max = None
    result = []
    for n in numbers:
        if running_max is None:
            running_max = n
        else:
            running_max = max(running_max, n)
        result.append(running_max)
    return result

def rolling_max_with_initial_value(numbers: List[int], initial: int) -> List[int]:
    """From a given list of integers, generate a list of rolling maximum element found until given moment
    in the sequence. Additionally, the maximum value starts with `initial`.
    >>> rolling_max_with_initial_value([1, 2, 3, 2, 3, 4, 2], 3)
    [3, 3, 3, 3, 3, 4, 4]
    """
    return rolling_max([initial] + numbers)[1:]


def make_palindrome(string: str) -> str:
    """Find the shortest palindrome that begins with a supplied string.
    Algorithm idea is simple:
    - Find the longest postfix of supplied string that is a palindrome.
    - Append to the end of the string reverse of a string prefix that comes before the palindromic suffix.
    >>> make_palindrome('')
    ''
    >>> make_palindrome('cat')
    'catac'
    >>> make_palindrome('cata')
    'catac'
    """

    def is_palindrome(string: str) -> bool:
        return string == string[::-1]
    if not string:
        return ''
    beginning_of_suffix = 0
    while not is_palindrome(string[beginning_of_suffix:]):
        beginning_of_suffix += 1
    return string + string[:beginning_of_suffix][::-1]

def find_shortest_palindrome_prefix(string: str) -> str:
    """Find the shortest prefix that generates the same shortest palindrome that
    begins with the supplied string.
    >>> find_shortest_palindrome_prefix('')
    ''
    >>> find_shortest_palindrome_prefix('cat')
    'cat'
    >>> find_shortest_palindrome_prefix('cata')
    'cat'
    """
    if len(string) == 0 or len(string) == 1:
        return string
    p = make_palindrome(string)
    for idx in range(len(string) - 1, 0, -1):
        if p != make_palindrome(string[:idx]):
            return string[:idx + 1]

def check(candidate):
    assert candidate('owienfh') == 'owienfh'
    assert candidate('abcdedcb') == 'abcde'
    assert candidate('abababa') == 'ababab'

def test_check():
    check(find_shortest_palindrome_prefix)

test_check()


def string_xor(a: str, b: str) -> str:
    """Input are two strings a and b consisting only of 1s and 0s.
    Perform binary XOR on these inputs and return result also as a string.
    >>> string_xor('010', '110')
    '100'
    """

    def xor(i, j):
        if i == j:
            return '0'
        else:
            return '1'
    return ''.join((xor(x, y) for (x, y) in zip(a, b)))

def string_xor_three(a: str, b: str, c: str) -> str:
    """Input are three strings a, b, and c consisting only of 1s and 0s.
    Perform binary XOR on these inputs and return result also as a string.
    >>> string_xor('010', '110', '001')
    '101'
    """
    return string_xor(string_xor(a, b), c)

def check(candidate):
    assert candidate('000', '101', '110') == '011'
    assert candidate('1100', '1011', '1111') == '1000'
    assert candidate('010', '110', '100') == '000'

def test_check():
    check(string_xor_three)

test_check()


def longest(strings: List[str]) -> Optional[str]:
    """Out of list of strings, return the longest one. Return the first one in case of multiple
    strings of the same length. Return None in case the input list is empty.
    >>> longest([])

    >>> longest(['a', 'b', 'c'])
    'a'
    >>> longest(['a', 'bb', 'ccc'])
    'ccc'
    """
    if not strings:
        return None
    maxlen = max((len(x) for x in strings))
    for s in strings:
        if len(s) == maxlen:
            return s

def second_longest(strings: List[str]) -> Optional[str]:
    """Out of list of strings, return the second longest one. Return the first one in case of multiple
    strings of the same length. Return None in case the input list doesn't have the second longest elements.
    >>> second_longest([])
    None
    >>> second_longest(['a', 'b', 'c'])
    None
    >>> second_longest(['a', 'bb', 'ccc'])
    'bb'
    """
    longest_string = longest(strings)
    if longest_string is None:
        return None
    strings = [string for string in strings if len(string) < len(longest_string)]
    return longest(strings)

def check(candidate):
    assert candidate([]) is None
    assert candidate(['albha', 'iehwknsj', 'lwi', 'wihml']) == 'albha'
    assert candidate(['apple', 'banana', 'kiwiiiiiii', 'xxxxxx', 'appledish']) == 'appledish'
    assert candidate(['what', 'is', 'this']) == 'is'

def test_check():
    check(second_longest)

test_check()


def greatest_common_divisor(a: int, b: int) -> int:
    """Return a greatest common divisor of two integers a and b
    >>> greatest_common_divisor(3, 5)
    1
    >>> greatest_common_divisor(25, 15)
    5
    """
    while b:
        (a, b) = (b, a % b)
    return a

def reduce_fraction(nominator: int, denominator: int) -> Tuple[int, int]:
    """Given nominator and denominator, reduce them to the simplest form.
    Reducing fractions means simplifying a fraction, wherein we divide the numerator and denominator by a common divisor until the common factor becomes 1.
    >>> reduce_fraction(3, 5)
    (3, 5)
    >>> reduce_fraction(25, 15)
    (5, 3)
    """
    gcd = greatest_common_divisor(nominator, denominator)
    return (nominator // gcd, denominator // gcd)

def check(candidate):
    assert candidate(51, 34) == (3, 2)
    assert candidate(81, 9) == (9, 1)
    assert candidate(39, 52) == (3, 4)

def test_check():
    check(reduce_fraction)

test_check()

    while b:
        (a, b) = (b, a % b)
    return a


def all_prefixes(string: str) -> List[str]:
    """Return list of all prefixes from shortest to longest of the input string
    >>> all_prefixes('abc')
    ['a', 'ab', 'abc']
    """
    result = []
    for i in range(len(string)):
        result.append(string[:i + 1])
    return result

def all_suffixes_prefixes(string: str) -> List[str]:
    """Return list of suffixes which are also a prefix from shortest to
    longest of the input string
    >>> all_suffixes('abc')
    ['abc']
    """
    prefixes = all_prefixes(string)
    suffixes = [x[::-1] for x in all_prefixes(string[::-1])]
    return [x for x in suffixes if x in prefixes]

def check(candidate):
    assert candidate('abcabc') == ['abc', 'abcabc']
    assert candidate('ababab') == ['ab', 'abab', 'ababab']
    assert candidate('dxewfoird') == ['d', 'dxewfoird']

def test_check():
    check(all_suffixes_prefixes)

test_check()


def string_sequence(n: int) -> str:
    """Return a string containing space-delimited numbers starting from 0 upto n inclusive.
    >>> string_sequence(0)
    '0'
    >>> string_sequence(5)
    '0 1 2 3 4 5'
    """
    return ' '.join([str(x) for x in range(n + 1)])

def digit_sum(n: int) -> str:
    """Return the sum of all digits from 0 upto n inclusive.
    >>> digit_sum(0)
    0
    >>> digit_sum(5)
    15
    """
    sequence = string_sequence(n)
    return sum((int(x) for x in sequence if x != ' '))

def check(candidate):
    assert candidate(14) == 60
    assert candidate(21) == 105
    assert candidate(104) == 915

def test_check():
    check(digit_sum)

test_check()


def count_distinct_characters(string: str) -> int:
    """Given a string, find out how many distinct characters (regardless of case) does it consist of
    >>> count_distinct_characters('xyzXYZ')
    3
    >>> count_distinct_characters('Jerry')
    4
    """
    return len(set(string.lower()))

def count_words_with_distinct_characters(strings: List[str]) -> int:
    """Given a list of strings, count the number of words made up of all different letters (regardless of case)
    >>> count_words_with_distinct_characters(['xyz', 'Jerry'])
    1
    >>> count_words_with_distinct_characters(['apple', 'bear', 'Take'])
    2
    """
    return len([string for string in strings if count_distinct_characters(string) == len(string)])

def check(candidate):
    assert candidate(['valid', 'heart', 'orientation', 'class']) == 2
    assert candidate(['hunter', 'frog']) == 2
    assert candidate(['scratch']) == 0

def test_check():
    check(count_words_with_distinct_characters)

test_check()


def parse_music(music_string: str) -> List[int]:
    """Input to this function is a string representing musical notes in a special ASCII format.
    Your task is to parse this string and return list of integers corresponding to how many beats does each
    not last.

    Here is a legend:
    'o' - whole note, lasts four beats
    'o|' - half note, lasts two beats
    '.|' - quater note, lasts one beat

    >>> parse_music('o o| .| o| o| .| .| .| .| o o')
    [4, 2, 1, 2, 2, 1, 1, 1, 1, 4, 4]
    """
    note_map = {'o': 4, 'o|': 2, '.|': 1}
    return [note_map[x] for x in music_string.split(' ') if x]

def count_beats(music_string: str) -> int:
    """Input to this function is a string representing musical notes in a special ASCII format.
    Your task is to parse this string and return the total number of beats in the song.

    Here is a legend:
    'o' - whole note, lasts four beats
    'o|' - half note, lasts two beats
    '.|' - quater note, lasts one beat

    >>> count_beats('o o| .| o| o| .| .| .| .| o o')
    24
    """
    return sum(parse_music(music_string))

def check(candidate):
    assert candidate('o o| .|') == 7
    assert candidate('o| o| o|') == 6
    assert candidate('o .| o| o o| .| o|') == 16

def test_check():
    check(count_beats)

test_check()


def how_many_times(string: str, substring: str) -> int:
    """Find how many times a given substring can be found in the original string. Count overlaping cases.
    >>> how_many_times('', 'a')
    0
    >>> how_many_times('aaa', 'a')
    3
    >>> how_many_times('aaaa', 'aa')
    3
    """
    times = 0
    for i in range(len(string) - len(substring) + 1):
        if string[i:i + len(substring)] == substring:
            times += 1
    return times

def match_cancer_pattern(dna: str, cancer_pattern: str) -> int:
    """Find how many times a given cancer pattern can be found in the given DNA. Count overlaping cases.
    >>> match_cancer_pattern('ATGCGATACGCTTGA', 'CG')
    3
    >>> match_cancer_pattern('ATGCGATACGCTTGA', 'CGC')
    1
    """
    return how_many_times(dna, cancer_pattern)

def check(candidate):
    assert candidate('ATATATAT', 'ATA') == 3
    assert candidate('ATGCATGCATGCATGC', 'ATGCATGC') == 3
    assert candidate('AGCTCTGATCGAT', 'GAT') == 2

def test_check():
    check(match_cancer_pattern)

test_check()


def sort_numbers(numbers: str) -> str:
    """Input is a space-delimited string of numberals from 'zero' to 'nine'.
    Valid choices are 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight' and 'nine'.
    Return the string with numbers sorted from smallest to largest
    >>> sort_numbers('three one five')
    'one three five'
    """
    value_map = {'zero': 0, 'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6, 'seven': 7, 'eight': 8, 'nine': 9}
    return ' '.join(sorted([x for x in numbers.split(' ') if x], key=lambda x: value_map[x]))

def sort_numbers_descending(numbers: str) -> str:
    """Input is a space-delimited string of numberals from 'zero' to 'nine'.
    Valid choices are 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight' and 'nine'.
    Return the string with numbers sorted from largest to smallest
    >>> sort_numbers_descending('three one five')
    'five three one'
    """
    return ' '.join((x for x in reversed(sort_numbers(numbers).split(' '))))

def check(candidate):
    assert candidate('two three four') == 'four three two'
    assert candidate('nine zero six seven') == 'nine seven six zero'
    assert candidate('five one three eight') == 'eight five three one'

def test_check():
    check(sort_numbers_descending)

test_check()


def find_closest_elements(numbers: List[float]) -> Tuple[float, float]:
    """From a supplied list of numbers (of length at least two) select and return two that are the closest to each
    other and return them in order (smaller number, larger number).
    >>> find_closest_elements([1.0, 2.0, 3.0, 4.0, 5.0, 2.2])
    (2.0, 2.2)
    >>> find_closest_elements([1.0, 2.0, 3.0, 4.0, 5.0, 2.0])
    (2.0, 2.0)
    """
    closest_pair = None
    distance = None
    for (idx, elem) in enumerate(numbers):
        for (idx2, elem2) in enumerate(numbers):
            if idx != idx2:
                if distance is None:
                    distance = abs(elem - elem2)
                    closest_pair = tuple(sorted([elem, elem2]))
                else:
                    new_distance = abs(elem - elem2)
                    if new_distance < distance:
                        distance = new_distance
                        closest_pair = tuple(sorted([elem, elem2]))
    return closest_pair

def find_closest_distance(numbers: List[float]) -> float:
    """From a supplied list of numbers (of length at least two) select and return the distance between two that are
    the closest to each other.
    >>> find_closest_distance([1.0, 2.0, 3.0, 4.0, 5.0, 2.2])
    0.2
    >>> find_closest_distance([1.0, 2.0, 3.0, 4.0, 5.0, 2.0])
    0.0
    """
    (x, y) = find_closest_elements(numbers)
    return y - x

def check(candidate):
    assert round(candidate([1.7, 0.5, 3.1, 1.2, 2.1]), 2) == 0.4
    assert round(candidate([3.0, 4.0, 5.0, 4.0, 3.9]), 2) == 0.0
    assert round(candidate([1.0, 2.0, 3.0, 10.0]), 2) == 1.0

def test_check():
    check(find_closest_distance)

test_check()


def rescale_to_unit(numbers: List[float]) -> List[float]:
    """Given list of numbers (of at least two elements), apply a linear transform to that list,
    such that the smallest number will become 0 and the largest will become 1
    >>> rescale_to_unit([1.0, 2.0, 3.0, 4.0, 5.0])
    [0.0, 0.25, 0.5, 0.75, 1.0]
    """
    min_number = min(numbers)
    max_number = max(numbers)
    return [(x - min_number) / (max_number - min_number) for x in numbers]

def rescale_to_percentile(numbers: List[float]) -> List[float]:
    """Given list of numbers (of at least two elements), apply a linear transform to that list,
    such that the smallest number will become 0 and the largest will become 100
    >>> rescale_to_percentile([1.0, 2.0, 3.0, 4.0, 5.0])
    [0.0, 25.0, 50.0, 75.0, 100.0]
    """
    return [x * 100 for x in rescale_to_unit(numbers)]


def filter_integers(values: List[Any]) -> List[int]:
    """Filter given list of any python values only for integers
    >>> filter_integers(['a', 3.14, 5])
    [5]
    >>> filter_integers([1, 2, 3, 'abc', {  }, []])
    [1, 2, 3]
    """
    return [x for x in values if isinstance(x, int)]

def get_second_integer(values: List[Any]) -> List[int]:
    """Return the second integer element in the list
    If there is no second integer element, return None
    >>> get_second_observed_integer(['a', 3.14, 5])
    None
    >>> get_second_observed_integer([1, 2, 3, 'abc', {}, []])
    2
    """
    integers = filter_integers(values)
    if len(integers) < 2:
        return None
    return filter_integers(values)[1]

def check(candidate):
    assert candidate([75, '75', 'scv', 7.3]) is None
    assert candidate(['wwkdjf', 'three', 97, 'wild', 3]) == 3
    assert candidate([85, 92, 77, 94, 77]) == 92

def test_check():
    check(get_second_integer)

test_check()


def strlen(string: str) -> int:
    """Return length of given string
    >>> strlen('')
    0
    >>> strlen('abc')
    3
    """
    return len(string)

def is_string_length_odd(string: str) -> str:
    """Return 'odd' if length of given string is odd, otherwise 'even'
    >>> is_string_length_odd('')
    'even'
    >>> is_string_length_odd('abc')
    'odd'
    """
    return 'odd' if strlen(string) % 2 else 'even'

def check(candidate):
    assert candidate('apple') == 'odd'
    assert candidate('working') == 'odd'
    assert candidate('book') == 'even'

def test_check():
    check(is_string_length_odd)

test_check()


def largest_divisor(n: int) -> int:
    """For a given number n, find the largest number that divides n evenly, smaller than n
    >>> largest_divisor(15)
    5
    """
    for i in reversed(range(n)):
        if n % i == 0:
            return i

def get_smallest_chunk_num(n: int) -> bool:
    """Given n, find the smallest k such that a number n can be made from k chunks of the same size.
    Chunk size must be smaller than n.
    >>> get_smallest_chunk_num(15)
    3
    """
    return n // largest_divisor(n)

def check(candidate):
    assert candidate(370) == 2
    assert candidate(23) == 23
    assert candidate(77) == 7

def test_check():
    check(get_smallest_chunk_num)

test_check()


def factorize(n: int) -> List[int]:
    """Return list of prime factors of given integer in the order from smallest to largest.
    Each of the factors should be listed number of times corresponding to how many times it appeares in factorization.
    Input number should be equal to the product of all factors
    >>> factorize(8)
    [2, 2, 2]
    >>> factorize(25)
    [5, 5]
    >>> factorize(70)
    [2, 5, 7]
    """
    import math
    fact = []
    i = 2
    while i <= int(math.sqrt(n) + 1):
        if n % i == 0:
            fact.append(i)
            n //= i
        else:
            i += 1
    if n > 1:
        fact.append(n)
    return fact

def count_unique_prime_factors(n: int) -> int:
    """Return the number of unique prime factors of given integer
    >>> count_unique_prime_factors(8)
    1
    >>> count_unique_prime_factors(25)
    1
    >>> count_unique_prime_factors(70)
    3
    """
    return len(set(factorize(n)))

def check(candidate):
    assert candidate(910) == 4
    assert candidate(256) == 1
    assert candidate(936) == 3

def test_check():
    check(count_unique_prime_factors)

test_check()


def remove_duplicates(numbers: List[int]) -> List[int]:
    """From a list of integers, remove all elements that occur more than once.
    Keep order of elements left the same as in the input.
    >>> remove_duplicates([1, 2, 3, 2, 4])
    [1, 3, 4]
    """
    import collections
    c = collections.Counter(numbers)
    return [n for n in numbers if c[n] <= 1]

def count_duplicates(numbers: List[int]) -> int:
    """From a list of integers, count how many elements occur more than once.
    >>> count_duplicates([1, 2, 3, 2, 4])
    2
    >>> count_duplicates([2, 2, 3, 2, 3])
    5
    """
    return len(numbers) - len(remove_duplicates(numbers))

def check(candidate):
    assert candidate([9, 4, 3, 3, 3]) == 3
    assert candidate([1, 2, 3, 4, 5, 6, 7, 8, 6, 4, 2]) == 6
    assert candidate([96, 33, 27, 96, 2, 11]) == 2

def test_check():
    check(count_duplicates)

test_check()


def flip_case(string: str) -> str:
    """For a given string, flip lowercase characters to uppercase and uppercase to lowercase.
    >>> flip_case('Hello')
    'hELLO'
    """
    return string.swapcase()

def get_more_uppercase_word(string: str) -> str:
    """Return string if string has more or equal number of uppercase characters than
    the number of lowercase characters. Otherwise, return string whose characters
    are flipped by their case.
    >>> flip_alternative_words('Hello')
    'hELLO'
    >>> flip_alternative_words('SotA')
    'SotA'
    """
    if sum((1 for c in string if c.isupper())) >= sum((1 for c in string if c.islower())):
        return string
    else:
        return flip_case(string)

def check(candidate):
    assert candidate('What') == 'wHAT'
    assert candidate('APpLe') == 'APpLe'
    assert candidate('noTeBooK') == 'NOtEbOOk'

def test_check():
    check(get_more_uppercase_word)

test_check()


def concatenate(strings: List[str]) -> str:
    """Concatenate list of strings into a single string
    >>> concatenate([])
    ''
    >>> concatenate(['a', 'b', 'c'])
    'abc'
    """
    return ''.join(strings)

def create_multiline_string(strings: List[str]) -> str:
    """Create a multiline string from a list of strings. Note that last line should also end with a newline. If string is empty, return empty string.
    >>> create_multiline_string([])
    ''
    >>> create_multiline_string(['a', 'b', 'c'])
    'a\\nb\\nc
'
    """
    return concatenate([s + '\n' for s in strings])

def check(candidate):
    assert candidate(['return scroll', 'might be', ' .']) == 'return scroll\nmight be\n .\n'
    assert candidate(["I don't know"]) == "I don't know\n"
    assert candidate([]) == ''

def test_check():
    check(create_multiline_string)

test_check()

Create a multiline string from a list of strings. Note that last line should also end with a newline. If string is empty, return empty string.
    >>> create_multiline_string([])
    ''
    >>> create_multiline_string(['a', 'b', 'c'])
    'a\nb\nc
'


def filter_by_prefix(strings: List[str], prefix: str) -> List[str]:
    """Filter an input list of strings only for ones that start with a given prefix.
    >>> filter_by_prefix([], 'a')
    []
    >>> filter_by_prefix(['abc', 'bcd', 'cde', 'array'], 'a')
    ['abc', 'array']
    """
    return [x for x in strings if x.startswith(prefix)]

def create_autocomplete_options(input: str, options: List[str]) -> List[str]:
    """Create autocomplete options for a given input string from a list of options.
    Options should be sorted alphabetically.
    >>> create_autocomplete_options('a', [])
    []
    >>> create_autocomplete_options('a', ['abc', 'bcd', 'cde', 'array'])
    ['abc', 'array']
    """
    return sorted(filter_by_prefix(options, input))

def check(candidate):
    assert candidate('mac', ['machanic', 'machine', 'mad', 'sort']) == ['machanic', 'machine']
    assert candidate('le', ['learning', 'lora', 'lecun', 'lemon']) == ['learning', 'lecun', 'lemon']
    assert candidate('program', ['array', 'bolt', 'programming', 'program']) == ['program', 'programming']

def test_check():
    check(create_autocomplete_options)

test_check()


def get_positive(l: List[int]) -> List[int]:
    """Return only positive numbers in the list.
    >>> get_positive([-1, 2, -4, 5, 6])
    [2, 5, 6]
    >>> get_positive([5, 3, -5, 2, -3, 3, 9, 0, 123, 1, -10])
    [5, 3, 2, 3, 9, 123, 1]
    """
    return [e for e in l if e > 0]

def sum_positive(l: list) -> int:
    """Return the sum of all positive numbers in the list.
    >>> sum_positive([-1, 2, -4, 5, 6])
    13
    >>> sum_positive([5, 3, -5, 2, -3, 3, 9, 0, 123, 1, -10])
    146
    """
    return sum(get_positive(l))

def check(candidate):
    assert candidate([40, 0, 4]) == 44
    assert candidate([-1, -2, -3, -4]) == 0
    assert candidate([7, -6, 10, -22, -1, 0]) == 17

def test_check():
    check(sum_positive)

test_check()


def is_prime(n: int) -> bool:
    """Return true if a given number is prime, and false otherwise.
    >>> is_prime(6)
    False
    >>> is_prime(101)
    True
    >>> is_prime(11)
    True
    >>> is_prime(13441)
    True
    >>> is_prime(61)
    True
    >>> is_prime(4)
    False
    >>> is_prime(1)
    False
    """
    if n < 2:
        return False
    for k in range(2, n - 1):
        if n % k == 0:
            return False
    return True

def get_prime_times_prime(n: int) -> bool:
    """Returns a sorted list of numbers less than n that are
    the product of two distinct primes.
    >>> get_number(6)
    []
    >>> get_number(20)
    [6, 10, 14, 15]
    """
    primes = [i for i in range(2, n) if is_prime(i)]
    results = []
    for i in range(len(primes)):
        for j in range(i + 1, len(primes)):
            if primes[i] * primes[j] < n:
                results.append(primes[i] * primes[j])
    return sorted(results)


def sort_third(l: List[int]) -> List[int]:
    """This function takes a list l and returns a list l' such that
    l' is identical to l in the indicies that are not divisible by three, while its values at the indicies that are divisible by three are equal
    to the values of the corresponding indicies of l, but sorted.
    >>> sort_third([1, 2, 3])
    [1, 2, 3]
    >>> sort_third([5, 6, 3, 4, 8, 9, 2])
    [2, 6, 3, 4, 8, 9, 5]
    """
    l = list(l)
    l[::3] = sorted(l[::3])
    return l

def sort_first_column(l: List[List[int]]):
    """This function takes an array of n by 3.
    It returns an array of N x 3 such that the elements in the first column are sorted.
    >>> sort_last_column([[1, 2, 3], [9, 6, 4], [5, 3, 2]])
    [[1, 2, 3], [5, 6, 4], [9, 3, 2]]
    >>> sort_last_column([[8, 9, 8], [6, 6, 6], [2, 9, 1]])
    [[2, 9, 8], [6, 6, 6], [8, 9, 1]]
    """
    l = [y for x in l for y in x]
    l = sort_third(l)
    return [[l[3 * i], l[3 * i + 1], l[3 * i + 2]] for i in range(len(l) // 3)]


def max_element(l: List[int]) -> int:
    """Return maximum element in the list.
    >>> max_element([1, 2, 3])
    3
    >>> max_element([5, 3, -5, 2, -3, 3, 9, 0, 123, 1, -10])
    123
    """
    m = l[0]
    for e in l:
        if e > m:
            m = e
    return m

def max_element_nested_list(l: list):
    """Return maximum element in a nested list.
    l could be nested by any depth.
    >>> max_element_nested_list([1, 2, 3])
    3
    >>> max_element_nested_list([[5, 3], [[-5], [2, -3, 3], [[9, 0], [123]], 1], -10])
    123
    """
    return max_element([max_element_nested_list(e) if isinstance(e, list) else e for e in l])

def check(candidate):
    assert candidate([[1, 2], [3], [[4], [5, 6]]]) == 6
    assert candidate([[[[6]], [5, 4, 3, 2], [1]], 0]) == 6
    assert candidate([53, [23, [34, 23], [22, 15, 52]]]) == 53

def test_check():
    check(max_element_nested_list)

test_check()


def fizz_buzz(n: int) -> int:
    """Return the number of times the digit 7 appears in integers less than n which are divisible by 11 or 13.
    >>> fizz_buzz(50)
    0
    >>> fizz_buzz(78)
    2
    >>> fizz_buzz(79)
    3
    """
    ns = []
    for i in range(n):
        if i % 11 == 0 or i % 13 == 0:
            ns.append(i)
    s = ''.join(list(map(str, ns)))
    ans = 0
    for c in s:
        ans += c == '7'
    return ans

def lucky_number(k: int) -> int:
    """Return the smallest non-negative number n that the digit 7 appears at
    least k times in integers less than n which are divisible by 11 or 13.
    >>> lucky_number(3)
    79
    >>> lucky_number(0)
    0
    """
    n = 0
    while fizz_buzz(n) < k:
        n += 1
    return n

def check(candidate):
    assert candidate(1) == 78
    assert candidate(2) == 78
    assert candidate(4) == 118

def test_check():
    check(lucky_number)

test_check()


def sort_even(l: list[int]) -> list[int]:
    """This function takes a list l and returns a list l' such that
    l' is identical to l in the odd indicies, while its values at the
    even indicies are equal to the values of the even indicies of l,
    but sorted.
    >>> sort_even([1, 2, 3])
    [1, 2, 3]
    >>> sort_even([5, 6, 3, 4])
    [3, 6, 5, 4]
    """
    evens = l[::2]
    odds = l[1::2]
    evens.sort()
    ans = []
    for (e, o) in zip(evens, odds):
        ans.extend([e, o])
    if len(evens) > len(odds):
        ans.append(evens[-1])
    return ans

def paired_sort(l: list[int]) -> list[int]:
    """This function takes a list l and returns a list l' such that
    l' is sorted to l in the odd indicies, also its values at the
    even indicies are equal to the values of the even indicies of l,
    but sorted.
    >>> sort_even([1, 2, 3])
    [1, 2, 3]
    >>> sort_even([5, 6, 3, 4])
    [3, 4, 5, 6]
    """
    l = [l[0]] + sort_even(l[1:])
    l = sort_even(l)
    return l


def prime_fib(n: int) -> int:
    """
    prime_fib returns n-th number that is a Fibonacci number and it's also prime.
    >>> prime_fib(1)
    2
    >>> prime_fib(2)
    3
    >>> prime_fib(3)
    5
    >>> prime_fib(4)
    13
    >>> prime_fib(5)
    89
    """
    import math

    def is_prime(p):
        if p < 2:
            return False
        for k in range(2, min(int(math.sqrt(p)) + 1, p - 1)):
            if p % k == 0:
                return False
        return True
    f = [0, 1]
    while True:
        f.append(f[-1] + f[-2])
        if is_prime(f[-1]):
            n -= 1
        if n == 0:
            return f[-1]

def prime_fib_diff(n: int):
    """Return the difference between the n-th number that is a Fibonacci number and
    it's also prime and the (n+1)-th number that is a Fibonacci number and it's also prime.
    >>> prime_fib_dif(1)
    1
    >>> prime_fib_dif(2)
    2
    >>> prime_fib_dif(3)
    8
    >>> prime_fib_dif(4)
    76
    """
    return prime_fib(n + 1) - prime_fib(n)

def check(candidate):
    assert candidate(8) == 485572
    assert candidate(3) == 8
    assert candidate(10) == 2537720636

def test_check():
    check(prime_fib_diff)

test_check()


def triples_sum_to_zero(l: list[int]) -> bool:
    """
    triples_sum_to_zero takes a list of integers as an input.
    it returns True if there are three distinct elements in the list that
    sum to zero, and False otherwise.

    >>> triples_sum_to_zero([1, 3, 5, 0])
    False
    >>> triples_sum_to_zero([1, 3, -2, 1])
    True
    >>> triples_sum_to_zero([1, 2, 3, 7])
    False
    >>> triples_sum_to_zero([2, 4, -5, 3, 9, 7])
    True
    >>> triples_sum_to_zero([1])
    False
    """
    for i in range(len(l)):
        for j in range(i + 1, len(l)):
            for k in range(j + 1, len(l)):
                if l[i] + l[j] + l[k] == 0:
                    return True
    return False

def get_shortest_prefix_triples_sum_to_zero(l: list) -> list:
    """
    get_shortest_prefix_triples_sum_to_zero takes a list of integers as an input.
    it returns the shortest prefix of the list such that there are three distinct elements in the prefix that
    sum to zero, and an empty list if no such prefix exists.

    >>> get_shortest_prefix_triples_sum_to_zero([1, 3, 5, 0])
    []
    >>> get_shortest_prefix_triples_sum_to_zero([1, 3, -2, 1])
    [1, 3, -2]
    >>> get_shortest_prefix_triples_sum_to_zero([1, 2, 3, 7])
    []
    >>> get_shortest_prefix_triples_sum_to_zero([2, 4, -5, 3, 9, 7])
    [2, 4, -5, 3]
    >>> get_shortest_prefix_triples_sum_to_zero([1])
    []
    """
    for i in range(1, len(l) + 1):
        if triples_sum_to_zero(l[:i]):
            return l[:i]
    return []

def check(candidate):
    assert candidate([4, 8, 8, -16, 3]) == [4, 8, 8, -16]
    assert candidate([-5, 2, 2, 1, 0]) == []
    assert candidate([3, 2, -9, -8, 6, 7]) == [3, 2, -9, -8, 6]

def test_check():
    check(get_shortest_prefix_triples_sum_to_zero)

test_check()


def car_race_collision(n: int) -> int:
    """
    Imagine a road that's a perfectly straight infinitely long line.
    n cars are driving left to right;  simultaneously, a different set of n cars
    are driving right to left.   The two sets of cars start out being very far from
    each other.  All cars move in the same speed.  Two cars are said to collide
    when a car that's moving left to right hits a car that's moving right to left.
    However, the cars are infinitely sturdy and strong; as a result, they continue moving
    in their trajectory as if they did not collide.

    This function outputs the number of such collisions.
    """
    return n ** 2

def ball_collision(n: int):
    """Imagine a road that's a perfectly straight infinitely long line.
    n balls are rolling left to right; simultaneously, a different set of n balls
    are rolling right to left. The two sets of balls start out being very far from
    each other.  All balls move in the same speed.  Two balls are said to collide
    when a ball that's moving left to right hits a ball that's moving right to left.
    However, the balls are infinitely sturdy and strong; as a result, they continue moving
    in their trajectory as if they did not collide.

    This function outputs the number of such collisions.
    """
    return car_race_collision(n)

def check(candidate):
    assert candidate(15) == 225
    assert candidate(4) == 16
    assert candidate(9) == 81

def test_check():
    check(ball_collision)

test_check()


def incr_sublist(l: list, start: int, end: int):
    """Return list that the element in the sublist from
    `start` (inclusive) to `end` (exclusive) incremented by 1.
    >>> incr_until_10([1, 2, 3], 0, 2)
    [2, 3, 3]
    >>> incr_until_10([5, 3, 5, 2, 3, 3, 9, 0, 123], 3, 7)
    [5, 3, 5, 3, 4, 4, 10, 0, 123]
    """
    return l[:start] + incr_list(l[start:end]) + l[end:]


def pairs_sum_to_zero(l: List[int]) -> bool:
    """
    pairs_sum_to_zero takes a list of integers as an input.
    it returns True if there are two distinct elements in the list that
    sum to zero, and False otherwise.
    >>> pairs_sum_to_zero([1, 3, 5, 0])
    False
    >>> pairs_sum_to_zero([1, 3, -2, 1])
    False
    >>> pairs_sum_to_zero([1, 2, 3, 7])
    False
    >>> pairs_sum_to_zero([2, 4, -5, 3, 5, 7])
    True
    >>> pairs_sum_to_zero([1])
    False
    """
    for (i, l1) in enumerate(l):
        for j in range(i + 1, len(l)):
            if l1 + l[j] == 0:
                return True
    return False

def triple_sum_to_zero_with_zero(l):
    """triple_sum_to_zero_with_zero takes a list of integers as an input.
    it returns True if there are three distinct elements in the list that
    sum to zero and one of elements must be zero, and False otherwise.
    >>> triple_sum_to_zero_with_zero([1, 3, -1, 0])
    True
    >>> triple_sum_to_zero_with_zero([1, 3, -2, 1])
    False
    >>> triple_sum_to_zero_with_zero([1, 2, 3, 7])
    False
    >>> triple_sum_to_zero_with_zero([2, 4, -5, 0, 3, 5, 7])
    True
    >>> triple_sum_to_zero_with_zero([1])
    False
    """
    if 0 not in l:
        return False
    else:
        l.remove(0)
        return pairs_sum_to_zero(l)

def check(candidate):
    assert candidate([3, 6, 32, 6, 8, 8]) == False
    assert candidate([-8, 1, 0, -5, 2, 7, -89, 9, 5, -4]) == True
    assert candidate([1, 0, 56, -5, -24, 9, -45, 6, 34]) == False

def test_check():
    check(triple_sum_to_zero_with_zero)

test_check()


def change_base(x: int, base: int) -> str:
    """Change numerical base of input number x to base.
    return string representation after the conversion.
    base numbers are less than 10.
    >>> change_base(8, 3)
    '22'
    >>> change_base(8, 2)
    '1000'
    >>> change_base(7, 2)
    '111'
    """
    ret = ''
    while x > 0:
        ret = str(x % base) + ret
        x //= base
    return ret

def change_base_extension(n: str, base_from: int, base_to: int) -> str:
    """Change numerical base of input number n represented as string from base_from to base_to.
    return string representation after the conversion.
    base numbers are less than 10.
    >>> change_base_extension('22', 3, 2)
    '1000'
    >>> change_base_extension('1000', 2, 3)
    '22'
    >>> change_base_extension('111', 2, 10)
    '7'
    """
    return change_base(int(n, base_from), base_to)

def check(candidate):
    assert candidate('43', 7, 2) == '11111'
    assert candidate('101101', 2, 4) == '231'
    assert candidate('3128', 10, 5) == '100003'

def test_check():
    check(change_base_extension)

test_check()


def triangle_area(a: int, h: int) -> float:
    """Given length of a side and high return area for a triangle.
    >>> triangle_area(5, 3)
    7.5
    """
    return a * h / 2.0

def equilaternal_triangle_area(a):
    """Given length of a side return area for an equilaternal triangle.
    >>> round(equilaternal_triangle_area(5), 2)
    10.83
    """
    return triangle_area(a, a * math.sqrt(3) / 2.0)

def check(candidate):
    assert round(candidate(3.5), 2) == 5.3
    assert round(candidate(10), 2) == 43.3
    assert round(candidate(7.8), 2) == 26.34

def test_check():
    check(equilaternal_triangle_area)

test_check()


def fib4(n: int) -> int:
    """The Fib4 number sequence is a sequence similar to the Fibbonacci sequnece that's defined as follows:
    fib4(0) -> 0
    fib4(1) -> 0
    fib4(2) -> 2
    fib4(3) -> 0
    fib4(n) -> fib4(n-1) + fib4(n-2) + fib4(n-3) + fib4(n-4).
    Please write a function to efficiently compute the n-th element of the fib4 number sequence.  Do not use recursion.
    >>> fib4(5)
    4
    >>> fib4(6)
    8
    >>> fib4(7)
    14
    """
    results = [0, 0, 2, 0]
    if n < 4:
        return results[n]
    for _ in range(4, n + 1):
        results.append(results[-1] + results[-2] + results[-3] + results[-4])
        results.pop(0)
    return results[-1]

def fib2_to_4(n: int):
    """Return the n-th value of sequence defined by the following recurrence relation.
    fib2_to_4(0) -> 0
    fib2_to_4(1) -> 1
    fib2_to_4(n) -> fib4(n) if n is even
    fib2_to_4(n) -> fib2_to_4(n-1) + fib2_to_4(n-2) if n is odd
    >>> fib2_to_4(5)
    8
    >>> fib2_to_4(0)
    0
    >>> get_smallest_fib4_number(10)
    14
    """
    if n < 2:
        return n
    if n % 2 == 0:
        return fib4(n)
    else:
        return fib2_to_4(n - 1) + fib2_to_4(n - 2)

def check(candidate):
    assert candidate(4) == 2
    assert candidate(8) == 28
    assert candidate(11) == 145

def test_check():
    check(fib2_to_4)

test_check()


def median(l: List[int]) -> float:
    """Return median of elements in the list l.
    >>> median([3, 1, 2, 4, 5])
    3
    >>> median([-10, 4, 6, 1000, 10, 20])
    15.0
    """
    l = sorted(l)
    if len(l) % 2 == 1:
        return l[len(l) // 2]
    else:
        return (l[len(l) // 2 - 1] + l[len(l) // 2]) / 2.0

def is_skewed(l: list):
    """Return "positive" if the list l is positive skewed, "negative" if the list l is negative skewed.
    Otherwise, return "neutral".
    A distribution with negative skew can have its mean greater than the median.
    A distribution with positive skew can have its mean less than the median.
    >>> is_skewed([1, 2, 3, 4, 5])
    "neutral"
    >>> is_skewed([-10, 4, 6, 1000, 10, 20])
    "positive"
    """
    median_val = median(l)
    mean_val = sum(l) / len(l)
    if mean_val > median_val:
        return 'positive'
    elif mean_val < median_val:
        return 'negative'
    else:
        return 'neutral'

def check(candidate):
    assert candidate([1, 1, 1, 1, 1]) == 'neutral'
    assert candidate([3, 4, 8, 9, 10]) == 'negative'
    assert candidate([8, 3, 6, 2, 3, 4, 5, 7]) == 'positive'

def test_check():
    check(is_skewed)

test_check()


def is_palindrome(text: str) -> bool:
    """
    Checks if given string is a palindrome
    >>> is_palindrome('')
    True
    >>> is_palindrome('aba')
    True
    >>> is_palindrome('aaaaa')
    True
    >>> is_palindrome('zbcd')
    False
    """
    for i in range(len(text)):
        if text[i] != text[len(text) - 1 - i]:
            return False
    return True

def is_even_palidrome(s: str) -> bool:
    """
    Checks if the chacters located in the even indices in the
    given string is a palindrome.
    >>> is_palindrome('')
    True
    >>> is_palindrome('aba')
    True
    >>> is_palindrome('acaaa')
    True
    >>> is_palindrome('zbcd')
    False
    """
    return is_palindrome(s[::2])

def check(candidate):
    assert candidate('afbwccdhcebwa') == True
    assert candidate('dabbrctdscfbeaa') == False
    assert candidate('aabbcccybua') == True

def test_check():
    check(is_even_palidrome)

test_check()


def modp(n: int, p: int) -> int:
    """Return 2^n modulo p (be aware of numerics).
    >>> modp(3, 5)
    3
    >>> modp(1101, 101)
    2
    >>> modp(0, 101)
    1
    >>> modp(3, 11)
    8
    >>> modp(100, 101)
    1
    """
    ret = 1
    for i in range(n):
        ret = 2 * ret % p
    return ret

def modp4(n: int, p: int) -> int:
    """Return 4^n modulo p (be aware of numerics).
    >>> modp4(3, 5)
    4
    >>> modp4(1101, 101)
    """
    return modp(2 * n, p)

def check(candidate):
    assert candidate(403, 22) == 20
    assert candidate(441, 2) == 0
    assert candidate(9, 9) == 1

def test_check():
    check(modp4)

test_check()


def remove_vowels(text: str) -> str:
    """
    remove_vowels is a function that takes string and returns string without vowels.
    >>> remove_vowels('')
    ''
    >>> remove_vowels('abcdef')
    'bcdf'
    >>> remove_vowels('aaaaa')
    ''
    >>> remove_vowels('aaBAA')
    'B'
    >>> remove_vowels('zbcd')
    'zbcd'
    """
    return ''.join([s for s in text if s.lower() not in ['a', 'e', 'i', 'o', 'u']])

def equal(text1: str, text2: str) -> bool:
    """
    check if the non-vowel characters in text1 and the non-vowel characters in texts is equal or not.
    >>> count_vowels('apple', 'pple')
    True
    >>> count_vowels("pear", "par")
    True
    >>> count_vowels("test", "text")
    False
    """
    return remove_vowels(text1) == remove_vowels(text2)

def check(candidate):
    assert candidate('coke', 'cake') == True
    assert candidate('desk', 'dust') == False
    assert candidate('pandas', 'aeponeedosi') == True

def test_check():
    check(equal)

test_check()


def below_threshold(l: List[int], t: int) -> bool:
    """Return True if all numbers in the list l are below threshold t.
    >>> below_threshold([1, 2, 4, 10], 100)
    True
    >>> below_threshold([1, 20, 4, 10], 5)
    False
    """
    for e in l:
        if e >= t:
            return False
    return True

def detect_high_blood_sugar(blood_sugar_graph: list) -> bool:
    """Return True if the symptom of high blood sugar is detected in the blood sugar graph.
    High blood sugar rate means that the blood sugar level is above 100.
    High blood sugar is detected even if only one high blood sugar level is present.
    >>> blood_sugar_graph([65, 66, 70, 84, 81])
    False
    >>> blood_sugar_graph([65, 76, 81, 95, 101])
    True
    """
    return not below_threshold(blood_sugar_graph, 100)

def check(candidate):
    assert round(candidate([77, 79, 75, 81, 82, 81, 84])) == False
    assert round(candidate([101, 102, 99, 95, 93, 90])) == True
    assert round(candidate([91, 95, 98, 101, 99])) == True

def test_check():
    check(detect_high_blood_sugar)

test_check()


def fib(n: int) -> int:
    """Return n-th Fibonacci number.
    >>> fib(10)
    55
    >>> fib(1)
    1
    >>> fib(8)
    21
    """
    if n == 0:
        return 0
    if n == 1:
        return 1
    return fib(n - 1) + fib(n - 2)

def sum_fib(n: int):
    """Return sum of first n Fibonacci numbers.
    You can use this property: sum_{i=1}^{n} F_i = F_{n+2} - 1
    >>> sum_fib(8)
    54
    >>> sum_fib(1)
    1
    >>> sum_fib(6)
    20
    """
    return fib(n + 2) - 1

def check(candidate):
    assert candidate(3) == 4
    assert candidate(10) == 143
    assert candidate(7) == 33

def test_check():
    check(sum_fib)

test_check()


def correct_bracketing(brackets: str) -> bool:
    """brackets is a string of "<" and ">".
    return True if every opening bracket has a corresponding closing bracket.

    >>> correct_bracketing('<')
    False
    >>> correct_bracketing('<>')
    True
    >>> correct_bracketing('<<><>>')
    True
    >>> correct_bracketing('><<>')
    False
    """
    depth = 0
    for b in brackets:
        if b == '<':
            depth += 1
        else:
            depth -= 1
        if depth < 0:
            return False
    return depth == 0

def extended_correct_bracketing(brackets: str) -> bool:
    """brackets is a string of "<", "(", ">" and ")".
    There is opening bracket "<" and "(" and closing bracket ">", ")".
    return True if every opening bracket has a corresponding closing bracket.
    Note that it is ok not to match the shape between opening bracket and closing bracket.
    For example, "<)" is also true.
    >>> extended_correct_bracketing("(>")
    True
    >>> extended_correct_bracketing("(<)<<)>)")
    True
    >>> extended_correct_bracketing("><)(<>)")
    False
    """
    return correct_bracketing(brackets.replace('(', '<').replace(')', '>'))

def check(candidate):
    assert candidate('(<(>)>') == True
    assert candidate('<<>)<()<>>') == True
    assert candidate('<<(<))<>))<>>') == False

def test_check():
    check(extended_correct_bracketing)

test_check()


def monotonic(l: list[int]) -> bool:
    """Return True is list elements are monotonically increasing or decreasing.
    >>> monotonic([1, 2, 4, 20])
    True
    >>> monotonic([1, 20, 4, 10])
    False
    >>> monotonic([4, 1, 0, -10])
    True
    """
    if l == sorted(l) or l == sorted(l, reverse=True):
        return True
    return False

def monotonic_2d(arr: list[list[int]]) -> bool:
    """Check if all rows and columns in the given array is monotonimally
    increasing or decreasing.
    Assume that the given array is rectangular.
    >>> monotonic_2d([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
    True
    >>> monotonic_2d([[3, 5, 8], [2, 6, 9], [4, 7, 10]])
    False
    """
    for i in range(len(arr)):
        if not monotonic(arr[i]):
            return False
    for j in range(len(arr[0])):
        if not monotonic([arr[i][j] for i in range(len(arr))]):
            return False
    return True

def check(candidate):
    assert candidate([[4, 9, 13], [24, 19, 15], [25, 26, 27]]) == True
    assert candidate([[100, 0], [0, 100]]) == True
    assert candidate([[8, 6, 4], [8, 6, 4], [7, 8, 5]]) == False

def test_check():
    check(monotonic_2d)

test_check()


def largest_prime_factor(n: int) -> int:
    """Return the largest prime factor of n. Assume n > 1 and is not a prime.
    >>> largest_prime_factor(13195)
    29
    >>> largest_prime_factor(2048)
    2
    """

    def is_prime(k):
        if k < 2:
            return False
        for i in range(2, k - 1):
            if k % i == 0:
                return False
        return True
    largest = 1
    for j in range(2, n + 1):
        if n % j == 0 and is_prime(j):
            largest = max(largest, j)
    return largest

def get_exponent_of_largest_prime_factor(n: int):
    """Return the exponent of largest prime factor after factorizing n. Assume n > 1 and is not a prime.
    >>> get_exponent_of_largest_prime_factor(13195)  # 13195 = 5 * 7 * 13 * 29
    1
    >>> get_exponent_of_largest_prime_factor(2048)  # 2048 = 2^11
    11
    """
    largest = largest_prime_factor(n)
    ans = 1
    while largest_prime_factor(n // largest) == largest:
        ans += 1
        n = n // largest
    return ans

def check(candidate):
    assert candidate(162) == 4
    assert candidate(506250) == 5
    assert candidate(1071875) == 3

def test_check():
    check(get_exponent_of_largest_prime_factor)

test_check()


def derivative(xs: list[int]) -> list[int]:
    """xs represent coefficients of a polynomial.
    xs[0] + xs[1] * x + xs[2] * x^2 + ....
     Return derivative of this polynomial in the same form.
    >>> derivative([3, 1, 2, 4, 5])
    [1, 4, 12, 20]
    >>> derivative([1, 2, 3])
    [2, 6]
    """
    return [i * x for (i, x) in enumerate(xs)][1:]

def second_derivative(xs: list[int]) -> list[int]:
    """xs represent coefficients of a polynomial.
    xs[0] + xs[1] * x + xs[2] * x^2 + ....
    Return second derivative of this polynomial in the same form.
    >>> derivative([3, 1, 2, 4, 5])
    [4, 24, 60]
    >>> derivative([1, 2, 3])
    [6]
    """
    return derivative(derivative(xs))

def check(candidate):
    assert candidate([4, 9, 5, 2]) == [10, 12]
    assert candidate([9, 8, 2, 5, 3]) == [4, 30, 36]
    assert candidate([10, 8, 43, 4, 23, 4]) == [86, 24, 276, 80]

def test_check():
    check(second_derivative)

test_check()


def vowels_count(s: str) -> int:
    """Write a function vowels_count which takes a string representing
    a word as input and returns the number of vowels in the string.
    Vowels in this case are 'a', 'e', 'i', 'o', 'u'. Here, 'y' is also a
    vowel, but only when it is at the end of the given word.

    Example:
    >>> vowels_count('abcde')
    2
    >>> vowels_count('ACEDY')
    3
    """
    vowels = 'aeiouAEIOU'
    n_vowels = sum((c in vowels for c in s))
    if s[-1] == 'y' or s[-1] == 'Y':
        n_vowels += 1
    return n_vowels

def is_vowel_enough(s: str) -> bool:
    """Check if the given string contains at least 30% of vowels.
    >>> is_vowel_enough("abcde")
    True
    >>> is_vowel_enough("abc")
    False
    """
    return vowels_count(s) / len(s) >= 0.3

def check(candidate):
    assert candidate('Eulogia') == True
    assert candidate('Drain') == True
    assert candidate('hardship') == False

def test_check():
    check(is_vowel_enough)

test_check()


def circular_shift(x: int, shift: int) -> str:
    """Circular shift the digits of the integer x, shift the digits right by shift
    and return the result as a string.
    If shift > number of digits, return digits reversed.
    >>> circular_shift(12, 1)
    '21'
    >>> circular_shift(12, 2)
    '12'
    """
    s = str(x)
    if shift > len(s):
        return s[::-1]
    else:
        return s[len(s) - shift:] + s[:len(s) - shift]

def is_circular_same(x: int, y: int) -> bool:
    """Return True if x and y are circularly same, False otherwise.
    Circulary same means that any of circular shift of x is equal
    to any of circular shift of y.

    >>> is_circular_same(12, 21)
    True
    >>> is_circular_same(354, 453)
    False
    """
    xs = set((circular_shift(x, i) for i in range(len(str(x)))))
    ys = set((circular_shift(y, i) for i in range(len(str(y)))))
    return len(xs.intersection(ys)) > 0

def check(candidate):
    assert candidate(40273, 73402) is True
    assert candidate(33, 23) is False
    assert candidate(9447, 4794) is True

def test_check():
    check(is_circular_same)

test_check()


def digitSum(s: str) -> int:
    """Task
    Write a function that takes a string as input and returns the sum of the upper characters only'
    ASCII codes.

    Examples:
    >>> digitSum('')
    0
    >>> digitSum('abAB')
    131
    >>> digitSum('abcCd')
    67
    >>> digitSum('helloE')
    69
    >>> digitSum('woArBld')
    131
    >>> digitSum('aAaaaXa')
    153
    """
    if s == '':
        return 0
    return sum((ord(char) if char.isupper() else 0 for char in s))

def sort_by_sum_upper_character_ascii(s: List[str]) -> List[str]:
    """Sort string based on the custom key defined as the sum of the upper
    characters only' ASCII codes. The order of string should be preserved in
    case of a tie.

    Examples:
        sort_by_digitsum(["", "abAB", "abcCd", "helloE"]) => ["", "abcCd", "helloE", "abAB"]
    """
    return sorted(s, key=digitSum)

def check(candidate):
    assert candidate(['abAB', 'ABab']) == ['abAB', 'ABab']
    assert candidate(['AAAAAAAA', 'zzzzzzzzz', 'B']) == ['zzzzzzzzz', 'B', 'AAAAAAAA']
    assert candidate(['My', 'Name', 'Is', 'Hulk']) == ['Hulk', 'Is', 'My', 'Name']

def test_check():
    check(sort_by_sum_upper_character_ascii)

test_check()


def fruit_distribution(s: str, n: int) -> int:
    """
    In this task, you will be given a string that represents a number of apples and oranges
    that are distributed in a basket of fruit this basket contains
    apples, oranges, and mango fruits. Given the string that represents the total number of
    the oranges and apples and an integer that represent the total number of the fruits
    in the basket return the number of the mango fruits in the basket.
    for examble:
    >>> fruit_distribution('5 apples and 6 oranges', 19)
    8
    >>> fruit_distribution('0 apples and 1 oranges', 3)
    2
    >>> fruit_distribution('2 apples and 3 oranges', 100)
    95
    >>> fruit_distribution('100 apples and 1 oranges', 120)
    19
    """
    lis = list()
    for i in s.split(' '):
        if i.isdigit():
            lis.append(int(i))
    return n - sum(lis)

def happy_fruit_distribution(s: str, n: int) -> int:
    """
    In this task, you will be given a string that represents a number of apples and oranges
    that are distributed in a basket of fruit this basket contains
    apples, oranges, and mango fruits. Given the string that represents the total number of
    the oranges and apples and an integer that represent the total number of the fruits
    in the basket, your task is to check the fruit distribution is happy or not.
    The fruit distribution is happy when the number of the mango fruits is more than the
    total number of remainders.
    for example:
    >>> happy_fruit_distribution('5 apples and 6 oranges', 19)
    'not happy'
    >>> fruit_distribution('0 apples and 1 oranges', 3)
    'happy'
    >>> fruit_distribution('2 apples and 3 oranges', 100)
    'happy'
    >>> fruit_distribution('100 apples and 1 oranges', 120)
    'not happy'
    """
    return 'happy' if fruit_distribution(s, n) > n // 2 else 'not happy'

def check(candidate):
    assert candidate('3 apples and 3 oranges', 9) == 'not happy'
    assert candidate('9 apples and 1 oranges', 21) == 'happy'
    assert candidate('0 apples and 0 oranges', 1) == 'happy'

def test_check():
    check(happy_fruit_distribution)

test_check()


def pluck(arr: List[int]) -> List[int]:
    """
    "Given an array representing a branch of a tree that has non-negative integer nodes
    your task is to pluck one of the nodes and return it.
    The plucked node should be the node with the smallest even value.
    If multiple nodes with the same smallest even value are found return the node that has smallest index.

    The plucked node should be returned in a list, [ smalest_value, its index ],
    If there are no even values or the given array is empty, return [].

    Example 1:
    >>> pluck([4, 2, 3])
    [2, 1]
    Explanation: 2 has the smallest even value, and 2 has the smallest index.

    Example 2:
    >>> pluck([1, 2, 3])
    [2, 1]
    Explanation: 2 has the smallest even value, and 2 has the smallest index.

    Example 3:
    >>> pluck([])
    []

    Example 4:
    >>> pluck([5, 0, 3, 0, 4, 2])
    [0, 1]
    Explanation: 0 is the smallest value, but  there are two zeros,
                 so we will choose the first zero, which has the smallest index.

    Constraints:
        * 1 <= nodes.length <= 10000
        * 0 <= node.value
    """
    if len(arr) == 0:
        return []
    evens = list(filter(lambda x: x % 2 == 0, arr))
    if evens == []:
        return []
    return [min(evens), arr.index(min(evens))]

def pluck_and_select_larger_branch(arr: List[int]) -> List[int]:
    """
    Given a branch represented as a list of non-negative integers,
    plucking (and then cutting) a node will result in the branch
    being split into two (or fewer) seperate branches.

    Among the divided branches,
    return the one with a larger sum of the nodes that compose it.

    If the sum of nodes in the divided branches is the same,
    return the branch with the smaller index.

    Assuming the sum of nodes in an empty branch is -1,
    return `[]` if there are only empty branches remaining after plucking.

    Examples:
    >>> pluck_and_select_larger_branch([1, 3, 2, 4, 5])
    [4, 5]
    >>> pluck_and_select_larger_branch([1, 3, 2, 3, 1])
    [1, 3]
    >>> pluck_and_select_larger_branch([2, 1, 2, 1])
    [1, 2, 1]
    >>> pluck_and_select_larger_branch([2])
    []
    >>> pluck_and_select_larger_branch([1, 3, 5, 7, 9])
    [1, 3, 5, 7, 9]
    """
    plucked_node = pluck(arr)
    if plucked_node == []:
        return arr
    (_, index) = plucked_node
    left_branch = arr[:index]
    right_branch = arr[index + 1:]
    left_branch_value = sum(left_branch) if left_branch != [] else -1
    right_branch_value = sum(right_branch) if right_branch != [] else -1
    return left_branch if left_branch_value >= right_branch_value else right_branch

def check(candidate):
    assert candidate([33, 12, 10, 10, 1, 3, 1]) == [33, 12]
    assert candidate([1, 7, 12, 5, 3]) == [1, 7]
    assert candidate([12, 9, 7, 8]) == [12, 9, 7]
    assert candidate([100]) == []
    assert candidate([11, 21, 31, 41, 51]) == [11, 21, 31, 41, 51]
    assert candidate([]) == []

def test_check():
    check(pluck_and_select_larger_branch)

test_check()


def search(lst: List[int]) -> int:
    """
    You are given a non-empty list of positive integers. Return the greatest integer that is greater than
    zero, and has a frequency greater than or equal to the value of the integer itself.
    The frequency of an integer is the number of times it appears in the list.
    If no such a value exist, return -1.
    Examples:
    >>> search([4, 1, 2, 2, 3, 1])
    2
    >>> search([1, 2, 2, 3, 3, 3, 4, 4, 4])
    3
    >>> search([5, 5, 4, 4, 4])
    -1
    """
    frq = [0] * (max(lst) + 1)
    for i in lst:
        frq[i] += 1
    ans = -1
    for i in range(1, len(frq)):
        if frq[i] >= i:
            ans = i
    return ans

def remove_integers_with_higher_frequency(lst: List[int]) -> List[int]:
    """
    Return a list obtained from the given non-empty list of positive integers
    by removing all integers whose frequency is greater than or equal to the integer itself.

    Ensure that the order of elements between them is preserverd.

    Examples:
    >>> remove_integers_with_higher_frequency([2, 3, 3, 3, 3, 3, 4, 4])
    [2, 4, 4]
    >>> remove_integers_with_higher_frequency([3, 2, 4, 5, 1, 4, 3, 2])
    [3, 4, 5, 4, 3]
    >>> remove_integers_with_higher_frequency([2, 3, 3, 4, 4, 4])
    [2, 3, 3, 4, 4, 4]
    """
    integer = search(lst)
    while integer != -1:
        lst = [i for i in lst if i != integer]
        integer = search(lst)
    return lst


def strange_sort_list(lst: list[int]) -> list[int]:
    """
    Given list of integers, return list in strange order.
    Strange sorting, is when you start with the minimum value,
    then maximum of the remaining integers, then minimum and so on.

    Examples:
    >>> strange_sort_list([1, 2, 3, 4])
    [1, 4, 3, 2]
    >>> strange_sort_list([5, 5, 5, 5])
    [5, 5, 5, 5]
    >>> strange_sort_list([])
    []
    """
    (res, switch) = ([], True)
    while lst:
        res.append(min(lst) if switch else max(lst))
        lst.remove(res[-1])
        switch = not switch
    return res

def extended_strange_sort_list(lst: list[int]) -> list[int]:
    """
    Given list of integers, return list in strange order.
    Extended strange sorting, is when you start with the minimum value,
    then maximum of the remaining integers, then maximum and minimum and so on.

    Examples:
    >>> extended_strange_sort_list([1, 2, 3, 4])
    [1, 4, 3, 2]
    >>> extended_strange_sort_list([5, 5, 5, 5])
    [5, 5, 5, 5]
    >>> extended_strange_sort_list([])
    []
    """
    res = []
    for idx in range(len(lst)):
        res.append(min(lst) if idx % 4 in [0, 3] else max(lst))
        lst.remove(res[-1])
    return res


def triangle_area(a: int, b: int, c: int) -> float:
    """
    Given the lengths of the three sides of a triangle. Return the area of
    the triangle rounded to 2 decimal points if the three sides form a valid triangle.
    Otherwise return -1
    Three sides make a valid triangle when the sum of any two sides is greater
    than the third side.
    Example:
    >>> triangle_area(3, 4, 5)
    6.0
    >>> triangle_area(1, 2, 10)
    -1
    """
    if a + b <= c or a + c <= b or b + c <= a:
        return -1
    s = (a + b + c) / 2
    area = (s * (s - a) * (s - b) * (s - c)) ** 0.5
    area = round(area, 2)
    return area

def sum_of_triangle_areas(triangles: List[List[int]]) -> float:
    """
    Return the sum of the areas of all given triangles.
    Each triangle is given as a list of the lengths of its three sides.
    If the input includes any invalid triangles, return -1.
    Example:
    >>> sum_of_triangle_areas([[3, 4, 5], [5, 12, 13]])
    36.0
    >>> sum_of_triangle_areas([[5, 12, 13], [1, 1, 10]])
    -1
    """
    triangle_areas = [triangle_area(a, b, c) for (a, b, c) in triangles]
    if -1 in triangle_areas:
        return -1
    else:
        return sum(triangle_areas)

def check(candidate):
    assert candidate([[3, 4, 5], [5, 12, 13], [5, 5, 6]]) == 48.0
    assert candidate([[6, 8, 10], [10, 10, 12]]) == 72.0
    assert candidate([[3, 4, 5], [3, 4, 7]]) == -1.0

def test_check():
    check(sum_of_triangle_areas)

test_check()


def will_it_fly(q: List[int], w: int) -> bool:
    """
    Write a function that returns True if the object q will fly, and False otherwise.
    The object q will fly if it's balanced (it is a palindromic list) and the sum of its elements is less than or equal the maximum possible weight w.

    Example:
    >>> will_it_fly([1, 2], 5)
    False
    # 1+2 is less than the maximum possible weight, but it's unbalanced.

    >>> will_it_fly([3, 2, 3], 1)
    False
    # it's balanced, but 3+2+3 is more than the maximum possible weight.

    >>> will_it_fly([3, 2, 3], 9)
    True
    # 3+2+3 is less than the maximum possible weight, and it's balanced.

    >>> will_it_fly([3], 5)
    True
    # 3 is less than the maximum possible weight, and it's balanced.
    """
    if sum(q) > w:
        return False
    (i, j) = (0, len(q) - 1)
    while i < j:
        if q[i] != q[j]:
            return False
        i += 1
        j -= 1
    return True

def is_palindrome(q: List[int]) -> bool:
    """
    Write a function that determines whether a given list is a palindrome.
    Example:
    >>> is_palindrome([1, 2])
    False
    >>> is_palindrome([1, 2, 1])
    True
    """
    return will_it_fly(q, sum(q))

def check(candidate):
    assert candidate([1, 2, 3, 4, 5, 6, 7, 8]) is False
    assert candidate([1, 2, 3, 2, 1]) is True
    assert candidate([1, 1, 1, 1]) is True

def test_check():
    check(is_palindrome)

test_check()


def smallest_change(arr: List[int]) -> int:
    """
    Given an array arr of integers, find the minimum number of elements that
    need to be changed to make the array palindromic. A palindromic array is an array that
    is read the same backwards and forwards. In one change, you can change one element to any other element.

    For example:
    >>> smallest_change([1, 2, 3, 5, 4, 7, 9, 6])
    4
    >>> smallest_change([1, 2, 3, 4, 3, 2, 2])
    1
    >>> smallest_change([1, 2, 3, 2, 1])
    0
    """
    ans = 0
    for i in range(len(arr) // 2):
        if arr[i] != arr[len(arr) - i - 1]:
            ans += 1
    return ans

def is_palindrome(arr: List[int]) -> bool:
    """
    Write a function that determines whether a given list is a palindrome.
    Example:
    >>> is_palindrome([1, 2])
    False
    >>> is_palindrome([1, 2, 1])
    True
    """
    return smallest_change(arr) == 0


def total_match(lst1: List[str], lst2: List[str]) -> List[str]:
    """
    Write a function that accepts two lists of strings and returns the list that has
    total number of chars in the all strings of the list less than the other list.

    if the two lists have the same number of chars, return the first list.

    Examples
    >>> total_match([], [])
    []
    >>> total_match(['hi', 'admin'], ['hI', 'Hi'])
    ['hI', 'Hi']
    >>> total_match(['hi', 'admin'], ['hi', 'hi', 'admin', 'project'])
    ['hi', 'admin']
    >>> total_match(['hi', 'admin'], ['hI', 'hi', 'hi'])
    ['hI', 'hi', 'hi']
    >>> total_match(['4'], ['1', '2', '3', '4', '5'])
    ['4']
    """
    l1 = 0
    for st in lst1:
        l1 += len(st)
    l2 = 0
    for st in lst2:
        l2 += len(st)
    if l1 <= l2:
        return lst1
    else:
        return lst2

def total_match_three(lst1: List[str], lst2: List[str], lst3: List[str]) -> List[str]:
    """
    Return the list of strings with the smallest total number of characters
    among the three string lists.
    If some lists have the same total number of characters,
    return the list that appears ealier.
    Examples:
    >>> total_match_three(['a'], ['a', 'b'], ['a', 'b', 'c'])
    ['a']
    >>> total_match_three(['abcd'], ['a', 'b'])
    ['a', 'b']
    >>> total_match_three(['a'], ['b'], ['c'])
    ['a']
    """
    return total_match(total_match(lst1, lst2), lst3)

def check(candidate):
    assert candidate(['total', 'match', 'three'], ['I', 'love', 'you'], ['This', 'is', 'good']) == ['I', 'love', 'you']
    assert candidate(['a', 'aa', 'aaa'], ['aaaaa'], ['aaaaaaa']) == ['aaaaa']
    assert candidate(['a', 'bcd'], ['ab', 'cd'], ['abc', 'd']) == ['a', 'bcd']

def test_check():
    check(total_match_three)

test_check()


def is_multiply_prime(a: int) -> bool:
    """Write a function that returns true if the given number is the multiplication of 3 prime numbers
    and false otherwise.
    Knowing that (a) is less then 100.
    Example:
    >>> is_multiply_prime(30)
    True
    30 = 2 * 3 * 5
    """

    def is_prime(n):
        for j in range(2, n):
            if n % j == 0:
                return False
        return True
    for i in range(2, 101):
        if not is_prime(i):
            continue
        for j in range(2, 101):
            if not is_prime(j):
                continue
            for k in range(2, 101):
                if not is_prime(k):
                    continue
                if i * j * k == a:
                    return True
    return False

def sum_of_multiply_primes(nums: List[int]) -> int:
    """
    Return the sum of numbers among the given numbers
    that can be expressed as the product of three prime numbers.
    Examples:
    >>> sum_of_multiply_prime([30, 42])
    72
    >>> sum_of_multiply_prime([30, 35, 40, 42])
    72
    """
    return sum([n for n in nums if is_multiply_prime(n)])

def check(candidate):
    assert candidate([30, 42, 66, 70, 78]) == 286
    assert candidate([25, 40, 55, 72, 77]) == 0
    assert candidate([25, 30, 40, 42, 55, 66, 70, 72, 77, 78]) == 286

def test_check():
    check(sum_of_multiply_primes)

test_check()


def is_simple_power(x: int, n: int) -> bool:
    """Your task is to write a function that returns true if a number x is a simple
    power of n and false in other cases.
    x is a simple power of n if n**int=x
    For example:
    >>> is_simple_power(1, 4)
    True
    >>> is_simple_power(2, 2)
    True
    >>> is_simple_power(8, 2)
    True
    >>> is_simple_power(3, 2)
    False
    >>> is_simple_power(3, 1)
    False
    >>> is_simple_power(5, 3)
    False
    """
    if n == 1:
        return x == 1
    power = 1
    while power < x:
        power = power * n
    return power == x

def log(n: int, x: int) -> int:
    """
    Implement a function that calculates the value log_n(x)
    and returns it if it is an integer, otherwise returns -1.
    Examples:
    >>> log(2, 8)
    3
    >>> log(2, 3)
    -1
    """
    if is_simple_power(x, n):
        value = 0
        while x > 1:
            x /= n
            value += 1
        return value
    else:
        return -1

def check(candidate):
    assert candidate(2, 1024) == 10
    assert candidate(3, 27) == 3
    assert candidate(3, 8) == -1

def test_check():
    check(log)

test_check()


def iscube(a: int) -> bool:
    """
    Write a function that takes an integer a and returns True
    if this ingeger is a cube of some integer number.
    Note: you may assume the input is always valid.
    Examples:
    >>> iscube(1)
    True
    >>> iscube(2)
    False
    >>> iscube(-1)
    True
    >>> iscube(64)
    True
    >>> iscube(0)
    True
    >>> iscube(180)
    False
    """
    a = abs(a)
    return int(round(a ** (1.0 / 3))) ** 3 == a

def num_cube_pairs(nums1: List[int], nums2: List[int]) -> int:
    """
    Find the number of pairs (n1, n2) where n1 + n2 equals to
    a cube of some integer number. (n1 in nums1 and n2 in nums2)
    Examples:
    >>> num_cube_pairs([1, 2, 3], [1, 2, 3])
    0
    >>> num_cube_pairs([1, 2, 3], [5, 6])
    2
    """
    return len([1 for n1 in nums1 for n2 in nums2 if iscube(n1 + n2)])

def check(candidate):
    assert candidate([1, 2, 3, 4], [1, 2, 3, 4]) == 1
    assert candidate([1, 2, 3, 4], [-2, 0, 2, 4]) == 5
    assert candidate([5, 25], [39, 100]) == 2

def test_check():
    check(num_cube_pairs)

test_check()


def hex_key(num: str) -> int:
    """You have been tasked to write a function that receives
    a hexadecimal number as a string and counts the number of hexadecimal
    digits that are primes (prime number, or a prime, is a natural number
    greater than 1 that is not a product of two smaller natural numbers).
    Hexadecimal digits are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F.
    Prime numbers are 2, 3, 5, 7, 11, 13, 17,...
    So you have to determine a number of the following digits: 2, 3, 5, 7,
    B (=decimal 11), D (=decimal 13).
    Note: you may assume the input is always correct or empty string,
    and symbols A,B,C,D,E,F are always uppercase.
    Examples:
    >>> hex_key('AB')
    1
    >>> hex_key('1077E')
    2
    >>> hex_key('ABED1A33')
    4
    >>> hex_key('123456789ABCDEF0')
    6
    >>> hex_key('2020')
    2
    """
    primes = ('2', '3', '5', '7', 'B', 'D')
    total = 0
    for i in range(0, len(num)):
        if num[i] in primes:
            total += 1
    return total

def num_not_hex_primes(num: str) -> int:
    """
    Count the number of hexadecimal digits in the given hexadecimal string
    that are not prime.
    Examples:
    >>> num_not_hex_primes('AB')
    1
    >>> num_not_hex_primes('1077E')
    3
    """
    return len(num) - hex_key(num)

def check(candidate):
    assert candidate('12345678') == 4
    assert candidate('ABCDEF') == 4
    assert candidate('11AA22BB33CC44DD') == 8

def test_check():
    check(num_not_hex_primes)

test_check()


def decimal_to_binary(decimal: int) -> str:
    """You will be given a number in decimal form and your task is to convert it to
    binary format. The function should return a string, with each character representing a binary
    number. Each character in the string will be '0' or '1'.

    There will be an extra couple of characters 'db' at the beginning and at the end of the string.
    The extra characters are there to help with the format.

    Examples:
    >>> decimal_to_binary(15)
    'db1111db'
    >>> decimal_to_binary(32)
    'db100000db'
    """
    return 'db' + bin(decimal)[2:] + 'db'

def num_1s_in_binary(decimal: int) -> int:
    """
    Return the count of digit 1 in the binary representation of the given number.
    Examples:
    >>> num_1s_in_binary(15)
    4
    >>> num_1s_in_binary(32)
    1
    """
    return decimal_to_binary(decimal).count('1')

def check(candidate):
    assert candidate(1000) == 6
    assert candidate(1023) == 10
    assert candidate(1024) == 1

def test_check():
    check(num_1s_in_binary)

test_check()


def is_happy(s: str) -> bool:
    """You are given a string s.
    Your task is to check if the string is happy or not.
    A string is happy if its length is at least 3 and every 3 consecutive letters are distinct
    For example:
    >>> is_happy('a')
    False
    >>> is_happy('aa')
    False
    >>> is_happy('abcd')
    True
    >>> is_happy('aabb')
    False
    >>> is_happy('adb')
    True
    >>> is_happy('xyy')
    False
    """
    if len(s) < 3:
        return False
    for i in range(len(s) - 2):
        if s[i] == s[i + 1] or s[i + 1] == s[i + 2] or s[i] == s[i + 2]:
            return False
    return True

def num_happy_sentences(d: str) -> int:
    """
    Implement a function that, given a document d where sentences are concatenated
    with newlines as separators, returns the count of happy sentences.
    Examples:
    >>> num_happy_sentences('a
aa')
    0
    >>> num_happy_sentences('abcd
aabb
adb')
    2
    """
    return len([1 for s in d.splitlines() if is_happy(s)])

def check(candidate):
    assert candidate('aaa\nababab\nabcabcabc') == 1
    assert candidate('a\nab\nabc\nabcd') == 2
    assert candidate('numhappysentences\niloveyou\nthisisgood') == 1

def test_check():
    check(num_happy_sentences)

test_check()


def numerical_letter_grade(grades: List[float]) -> List[str]:
    """It is the last week of the semester and the teacher has to give the grades
    to students. The teacher has been making her own algorithm for grading.
    The only problem is, she has lost the code she used for grading.
    She has given you a list of GPAs for some students and you have to write
    a function that can output a list of letter grades using the following table:
             GPA       |    Letter grade
              4.0                A+
            > 3.7                A
            > 3.3                A-
            > 3.0                B+
            > 2.7                B
            > 2.3                B-
            > 2.0                C+
            > 1.7                C
            > 1.3                C-
            > 1.0                D+
            > 0.7                D
            > 0.0                D-
              0.0                E

    Example:
    >>> grade_equation([4.0, 3, 1.7, 2, 3.5])
    ['A+', 'B', 'C-', 'C', 'A-']
    """
    letter_grade = []
    for gpa in grades:
        if gpa == 4.0:
            letter_grade.append('A+')
        elif gpa > 3.7:
            letter_grade.append('A')
        elif gpa > 3.3:
            letter_grade.append('A-')
        elif gpa > 3.0:
            letter_grade.append('B+')
        elif gpa > 2.7:
            letter_grade.append('B')
        elif gpa > 2.3:
            letter_grade.append('B-')
        elif gpa > 2.0:
            letter_grade.append('C+')
        elif gpa > 1.7:
            letter_grade.append('C')
        elif gpa > 1.3:
            letter_grade.append('C-')
        elif gpa > 1.0:
            letter_grade.append('D+')
        elif gpa > 0.7:
            letter_grade.append('D')
        elif gpa > 0.0:
            letter_grade.append('D-')
        else:
            letter_grade.append('E')
    return letter_grade

def num_students_above_C(grades: List[float]) -> int:
    """
    Given a list of students' GPAs, return the number of students
    who will receive a grade of B- or higher.
    Examples:
    >>> num_students_above_C([4.0, 3, 1.7, 2, 3.5])
    3
    """
    grades = numerical_letter_grade(grades)
    return len([1 for grade in grades if grade[0] < 'C'])

def check(candidate):
    assert candidate([0.0, 1.0, 2.0, 3.0, 4.0]) == 2
    assert candidate([2.1, 2.2, 2.3, 2.4, 2.5]) == 2
    assert candidate([1.4, 2.8, 2.0, 3.5, 3.0, 2.1, 0.7]) == 3

def test_check():
    check(num_students_above_C)

test_check()


def prime_length(string: str) -> bool:
    """Write a function that takes a string and returns True if the string
    length is a prime number or False otherwise
    Examples
    >>> prime_length('Hello')
    True
    >>> prime_length('abcdcba')
    True
    >>> prime_length('kittens')
    True
    >>> prime_length('orange')
    False
    """
    l = len(string)
    if l == 0 or l == 1:
        return False
    for i in range(2, l):
        if l % i == 0:
            return False
    return True

def is_concat_length_prime(strings: List[str]) -> bool:
    """
    Implement a function that checks whether the length of the string
    obtained by concatenating the given strings is a prime number.
    Examples:
    >>> is_concat_length_prime(['He', 'llo'])
    True
    >>> is_concat_length_prime(['or', 'an', 'ge'])
    False
    """
    return prime_length(''.join(strings))

def check(candidate):
    assert candidate(['ab', 'abc', 'abcd', 'ab']) is True
    assert candidate(['aaaaaaaaaa', 'aaaaa']) is False
    assert candidate(['is', 'concat', 'length', 'prime']) is True

def test_check():
    check(is_concat_length_prime)

test_check()


def starts_one_ends(n: int) -> int:
    """
    Given a positive integer n, return the count of the numbers of n-digit
    positive integers that start or end with 1.
    """
    if n == 1:
        return 1
    return 18 * 10 ** (n - 2)

def non_starts_or_ends_with_one_count(n: int) -> int:
    """
    Return the count of n-digit positive integers
    that do not start or end with 1.
    Examples:
    >>> non_starts_or_ends_with_one_count(1)
    8
    >>> non_starts_or_ends_with_one_count(2)
    72
    """
    return len(range(10 ** (n - 1), 10 ** n)) - starts_one_ends(n)

def check(candidate):
    assert candidate(3) == 720
    assert candidate(4) == 7200
    assert candidate(5) == 72000

def test_check():
    check(non_starts_or_ends_with_one_count)

test_check()


def solve(N: int) -> str:
    """Given a positive integer N, return the total sum of its digits in binary.

    Example
    >>> solve(1000)
    '1'
    >>> solve(150)
    '110'
    >>> solve(147)
    '1100'

    Variables:
        @N integer
             Constraints: 0 ≤ N ≤ 10000.
    Output:
         a string of binary number
    """
    return bin(sum((int(i) for i in str(N))))[2:]

def sum_digits_to_binary(string: str) -> str:
    """
    Calculate the sum of numerical characters in the given string
    and return it as a binary representation.
    Examples:
    >>> sum_digits_to_binary('10a00')
    '1'
    >>> sum_digits_to_binary('a1b5c0d')
    '110'
    """
    digits = ''.join([c for c in string if c.isdecimal()])
    return solve(int(digits))

def check(candidate):
    assert candidate('1234') == '1010'
    assert candidate('a3b2c1d0e') == '110'
    assert candidate('sum2digits9to4binary1') == '10000'

def test_check():
    check(sum_digits_to_binary)

test_check()


def add(lst: List[int]) -> int:
    """Given a non-empty list of integers lst. add the even elements that are at odd indices..

    Examples:
    >>> add([4, 2, 6, 7])
    2
    """
    return sum([lst[i] for i in range(1, len(lst), 2) if lst[i] % 2 == 0])

def sum_even_second_digits(number: int) -> int:
    """
    Return the sum of even numbers among every second digit in the given number.
    Examples:
    >>> sum_even_second_digits(4267)
    2
    """
    return add([int(c) for c in str(number)])

def check(candidate):
    assert candidate(123456) == 12
    assert candidate(234567) == 0
    assert candidate(202307102232) == 4

def test_check():
    check(sum_even_second_digits)

test_check()


def anti_shuffle(s: str) -> str:
    """
    Write a function that takes a string and returns an ordered version of it.
    Ordered version of string, is a string where all words (separated by space)
    are replaced by a new word where all the characters arranged in
    ascending order based on ascii value.
    Note: You should keep the order of words and blank spaces in the sentence.

    For example:
    >>> anti_shuffle('Hi')
    'Hi'
    >>> anti_shuffle('hello')
    'ehllo'
    >>> anti_shuffle('Hello World!!!')
    'Hello !!!Wdlor'
    """
    return ' '.join([''.join(sorted(list(i))) for i in s.split(' ')])

def sort_and_concatenate_strings(strings: List[str]) -> str:
    """
    Implement a function that takes a list of strings,
    sorts each string in ascending order,
    and then concatenates them using a space as the separator.
    Examples:
    >>> sort_and_concatenate_strings(['hello'])
    'ehllo'
    >>> sort_and_concatenate_strings(['Hello', 'World!!!'])
    'Hello !!!Wdlor'
    """
    return anti_shuffle(' '.join(strings))

def check(candidate):
    assert candidate(['abcd', 'dcba', 'bdac']) == 'abcd abcd abcd'
    assert candidate(['sort', 'and', 'concatenate', 'strings']) == 'orst adn aacceennott ginrsst'
    assert candidate(['heLLo', 'worLd!']) == 'LLeho !Ldorw'

def test_check():
    check(sort_and_concatenate_strings)

test_check()


def get_row(lst: List[List[int]], x: int) -> List[Tuple[int, int]]:
    """
    You are given a 2 dimensional data, as a nested lists,
    which is similar to matrix, however, unlike matrices,
    each row may contain a different number of columns.
    Given lst, and integer x, find integers x in the list,
    and return list of tuples, [(x1, y1), (x2, y2) ...] such that
    each tuple is a coordinate - (row, columns), starting with 0.
    Sort coordinates initially by rows in ascending order.
    Also, sort coordinates of the row by columns in descending order.

    Examples:
    >>> get_row([[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 1, 6], [1, 2, 3, 4, 5, 1]], 1)
    [(0, 0), (1, 4), (1, 0), (2, 5), (2, 0)]
    >>> get_row([], 1)
    []
    >>> get_row([[], [1], [1, 2, 3]], 3)
    [(2, 2)]
    """
    coords = [(i, j) for i in range(len(lst)) for j in range(len(lst[i])) if lst[i][j] == x]
    return sorted(sorted(coords, key=lambda x: x[1], reverse=True), key=lambda x: x[0])

def count_integer_in_nested_lists(lst: List[List[int]], x: int) -> int:
    """
    Implement a function that counts how many times an integer x appears
    in a list of lists of integers.
    Examples:
    >>> count_integer_in_nested_lists([[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 1, 6], [1, 2, 3, 4, 5, 1]], 1)
    5
    >>> count_integer_in_nested_lists([[], [1], [1, 2, 3]], 3)
    1
    """
    return len(get_row(lst, x))


def sort_array(array: List[int]) -> List[int]:
    """
    Given an array of non-negative integers, return a copy of the given array after sorting,
    you will sort the given array in ascending order if the sum( first index value, last index value) is odd,
    or sort it in descending order if the sum( first index value, last index value) is even.

    Note:
    * don't change the given array.

    Examples:
    >>> sort_array([])
    []
    >>> sort_array([5])
    [5]
    >>> sort_array([2, 4, 3, 0, 1, 5])
    [0, 1, 2, 3, 4, 5]
    >>> sort_array([2, 4, 3, 0, 1, 5, 6])
    [6, 5, 4, 3, 2, 1, 0]
    """
    return [] if len(array) == 0 else sorted(array, reverse=(array[0] + array[-1]) % 2 == 0)

def count_elements_in_original_position(array: List[int]) -> int:
    """
    Given an integer array, return the count of elements that remain in their original positions
    when the array is sorted in ascending order if the sum of the first and last elements is odd,
    or in descending order if the sum is even.
    Examples:
    >>> count_elements_in_original_position([2, 4, 3, 0, 1, 5])
    1
    >>> count_elements_in_original_position([2, 4, 3, 0, 1, 5, 6])
    0
    """
    sorted_array = sort_array(array)
    return len([1 for (a, b) in zip(array, sorted_array) if a == b])

def check(candidate):
    assert candidate([10, 2, 8, 3, 1, 5, 4, 7, 9, 6]) == 4
    assert candidate([6, 8, 3, 1, 5, 7, 4, 2, 9]) == 3
    assert candidate([1, 3, 5, 3, 1, 3, 5]) == 1

def test_check():
    check(count_elements_in_original_position)

test_check()


def encrypt(s: str) -> str:
    """Create a function encrypt that takes a string as an argument and
    returns a string encrypted with the alphabet being rotated.
    The alphabet should be rotated in a manner such that the letters
    shift down by two multiplied to two places.
    For example:
    >>> encrypt('hi')
    'lm'
    >>> encrypt('asdfghjkl')
    'ewhjklnop'
    >>> encrypt('gf')
    'kj'
    >>> encrypt('et')
    'ix'
    """
    d = 'abcdefghijklmnopqrstuvwxyz'
    out = ''
    for c in s:
        if c in d:
            out += d[(d.index(c) + 2 * 2) % 26]
        else:
            out += c
    return out

def is_start_of_end_with_x_after_encryption(string: str) -> bool:
    """
    Implement a function that determines whether a given string starts or ends with 'x' after encryption.
    Examples:
    >>> is_start_of_end_with_x_after_encryption('gf')
    False
    >>> is_start_of_end_with_x_after_encryption('et')
    True
    """
    string = encrypt(string)
    return string[0] == 'x' or string[-1] == 'x'

def check(candidate):
    assert candidate('abcdttttefgh') is False
    assert candidate('abcdefght') is True
    assert candidate('tttttttttt') is True

def test_check():
    check(is_start_of_end_with_x_after_encryption)

test_check()


def next_smallest(lst: List[int]) -> Optional[int]:
    """
    You are given a list of integers.
    Write a function next_smallest() that returns the 2nd smallest element of the list.
    Return None if there is no such element.
    >>> next_smallest([1, 2, 3, 4, 5])
    2
    >>> next_smallest([5, 1, 4, 3, 2])
    2
    >>> next_smallest([])
    None
    >>> next_smallest([1, 1])
    None
    """
    lst = sorted(set(lst))
    return None if len(lst) < 2 else lst[1]

def remove_second_smallest(lst: List[int]) -> List[int]:
    """
    Return the list obtained by removing the second smallest value(s) from the given integer list.
    If there is no such value, return the original integer list.
    Examples:
    >>> remove_second_smallest([1, 2, 3, 4, 5])
    [1, 3, 4, 5]
    >>> remove_second_smallest([1, 1])
    [1, 1]
    >>> remove_second_smallest([1, 1, 2, 2])
    [1, 1]
    """
    second_smallest = next_smallest(lst)
    if second_smallest is not None:
        lst = [n for n in lst if n != second_smallest]
    return lst


def is_bored(S: str) -> int:
    """
    You'll be given a string of words, and your task is to count the number
    of boredoms. A boredom is a sentence that starts with the word "I".
    Sentences are delimited by '.', '?' or '!'.

    For example:
    >>> is_bored('Hello world')
    0
    >>> is_bored('The sky is blue. The sun is shining. I love this weather')
    1
    """
    import re
    sentences = re.split('[.?!]\\s*', S)
    return sum((sentence[0:2] == 'I ' for sentence in sentences))

def count_non_boredoms(string: str) -> int:
    """
    Return the count of non-boredoms in the given string.
    Here, boredom refers to sentences starting with the word 'I',
    and sentences are separated by '.', '?', or '!'.
    Note that empty sentences are not counted.
    Examples:
    >>> is_bored('Hello world')
    1
    >>> is_bored('The sky is blue. The sun is shining. I love this weather')
    2
    >>> is_bored('. ? !')
    0
    """
    sentences = string.replace('?', '.').replace('!', '.').split('.')
    num_sentences = len([sentence for sentence in sentences if len(sentence.strip()) > 0])
    return num_sentences - is_bored(string)

def check(candidate):
    assert candidate('aa. bb? cc! dd. ee? ff!') == 6
    assert candidate('You and I... A I!!') == 2
    assert candidate('Count non boredoms. This is good? I love you!') == 2

def test_check():
    check(count_non_boredoms)

test_check()


def any_int(x: float, y: float, z: float) -> bool:
    """
    Create a function that takes 3 numbers.
    Returns true if one of the numbers is equal to the sum of the other two, and all numbers are integers.
    Returns false in any other cases.

    Examples
    >>> any_int(5, 2, 7)
    True

    >>> any_int(3, 2, 2)
    False

    >>> any_int(3, -2, 1)
    True

    >>> any_int(3.6, -2.2, 2)
    False

    """
    if isinstance(x, int) and isinstance(y, int) and isinstance(z, int):
        if x + y == z or x + z == y or y + z == x:
            return True
        return False
    return False

def count_integer_sum_cases(xs: List[float], ys: List[float], zs: List[float]) -> int:
    """
    Return the count of cases where,
    by selecting one element from each of the three given lists,
    if all three selected elements are integers
    and one element can be expressed as the sum of the other two elements.
    Examples:
    >>> count_integer_sum_cases([5, 10], [2], [7])
    1
    >>> count_integer_sum_cases([3], [2, -2], [2, 1])
    2
    """
    return len([1 for x in xs for y in ys for z in zs if any_int(x, y, z)])

def check(candidate):
    assert candidate([1], [1, 2], [1, 2, 3]) == 3
    assert candidate([1], [1, 2.0], [1, 2, 3]) == 1
    assert candidate([-1, 0, 1], [-10, 0, 10], [-100, 0, 100]) == 1

def test_check():
    check(count_integer_sum_cases)

test_check()


def encode(message: str) -> str:
    """
    Write a function that takes a message, and encodes in such a
    way that it swaps case of all letters, replaces all vowels in
    the message with the letter that appears 2 places ahead of that
    vowel in the english alphabet.
    Assume only letters.

    Examples:
    >>> encode('test')
    'TGST'
    >>> encode('This is a message')
    'tHKS KS C MGSSCGG'
    """
    vowels = 'aeiouAEIOU'
    vowels_replace = dict([(i, chr(ord(i) + 2)) for i in vowels])
    message = message.swapcase()
    return ''.join([vowels_replace[i] if i in vowels else i for i in message])

def count_changed_alphabet_characters(message: str) -> int:
    """
    Return the count of characters in the given string
    that change their alphabet after encoding.
    Examples:
    >>> count_changed_alphabet_characters('test')
    1
    >>> count_changed_alphabet_characters('This is a message')
    6
    """
    encoded_message = encode(message)
    return len([1 for (a, b) in zip(message.lower(), encoded_message.lower()) if a != b])

def check(candidate):
    assert candidate('abebcciddBCDOUBCD') == 5
    assert candidate('a bc def gae') == 4
    assert candidate('Count Changed Alphabet Characters') == 10

def test_check():
    check(count_changed_alphabet_characters)

test_check()