diff --git a/src/array_flattener.py b/src/array_flattener.py new file mode 100644 index 00000000..f103f0e1 --- /dev/null +++ b/src/array_flattener.py @@ -0,0 +1,44 @@ +from typing import List, Union, Any, Iterable, Tuple + +def flatten_array(arr: Union[List[Any], Tuple[Any, ...]]) -> List[Any]: + """ + Flatten a nested array (list or tuple) to a single-level list. + + This function recursively flattens a nested list or tuple of arbitrary depth + into a single-level list. It handles nested lists, tuples, and other + iterable types while preserving non-iterable elements. + + Args: + arr (Union[List[Any], Tuple[Any, ...]]): The input nested list/tuple to be flattened. + + Returns: + List[Any]: A flattened list containing all non-list/non-tuple elements. + + Raises: + TypeError: If the input is not a list or tuple. + + Examples: + >>> flatten_array([1, [2, 3], [4, [5, 6]]]) + [1, 2, 3, 4, 5, 6] + >>> flatten_array([1, 2, 3]) + [1, 2, 3] + >>> flatten_array([]) + [] + """ + # Check if input is a valid iterable + if not isinstance(arr, (list, tuple)): + raise TypeError("Input must be a list or tuple") + + # Initialize result list + flattened = [] + + # Iterate through each element + for item in arr: + # If item is a list or tuple, recursively flatten + if isinstance(item, (list, tuple)): + flattened.extend(flatten_array(item)) + else: + # Add non-list/non-tuple items directly + flattened.append(item) + + return flattened \ No newline at end of file diff --git a/src/string_reversal.py b/src/string_reversal.py new file mode 100644 index 00000000..14ac38e0 --- /dev/null +++ b/src/string_reversal.py @@ -0,0 +1,33 @@ +def reverse_string(s: str) -> str: + """ + Reverse the given string manually, preserving all original characters. + + Args: + s (str): The input string to be reversed. + + Returns: + str: The reversed string. + + Raises: + TypeError: If the input is not a string. + """ + # Validate input is a string + if not isinstance(s, str): + raise TypeError("Input must be a string") + + # Manual string reversal using a list and two-pointer technique + # Convert string to list to allow manipulation + chars = list(s) + + # Two-pointer approach to swap characters + left, right = 0, len(chars) - 1 + while left < right: + # Swap characters + chars[left], chars[right] = chars[right], chars[left] + + # Move pointers + left += 1 + right -= 1 + + # Convert back to string and return + return ''.join(chars) \ No newline at end of file diff --git a/tests/test_array_flattener.py b/tests/test_array_flattener.py new file mode 100644 index 00000000..fbbf55de --- /dev/null +++ b/tests/test_array_flattener.py @@ -0,0 +1,33 @@ +import pytest +from src.array_flattener import flatten_array + +def test_flatten_simple_list(): + """Test flattening a simple list""" + assert flatten_array([1, 2, 3]) == [1, 2, 3] + +def test_flatten_nested_list(): + """Test flattening a nested list""" + assert flatten_array([1, [2, 3], [4, [5, 6]]]) == [1, 2, 3, 4, 5, 6] + +def test_flatten_empty_list(): + """Test flattening an empty list""" + assert flatten_array([]) == [] + +def test_flatten_deeply_nested_list(): + """Test flattening a deeply nested list""" + assert flatten_array([1, [2, [3, [4]]], 5]) == [1, 2, 3, 4, 5] + +def test_flatten_mixed_types(): + """Test flattening a list with mixed types""" + assert flatten_array([1, 'a', [2, 'b'], [3, [4, 'c']]]) == [1, 'a', 2, 'b', 3, 4, 'c'] + +def test_flatten_tuple_nested(): + """Test flattening a list with tuple nesting""" + assert flatten_array([1, (2, 3), [4, (5, 6)]]) == [1, 2, 3, 4, 5, 6] + +def test_invalid_input_type(): + """Test that TypeError is raised for non-list input""" + with pytest.raises(TypeError, match="Input must be a list"): + flatten_array("not a list") + with pytest.raises(TypeError, match="Input must be a list"): + flatten_array(123) \ No newline at end of file diff --git a/tests/test_string_reversal.py b/tests/test_string_reversal.py new file mode 100644 index 00000000..94834877 --- /dev/null +++ b/tests/test_string_reversal.py @@ -0,0 +1,38 @@ +import pytest +from src.string_reversal import reverse_string + +def test_reverse_string_basic(): + """Test basic string reversal.""" + assert reverse_string("hello") == "olleh" + assert reverse_string("python") == "nohtyp" + +def test_reverse_string_empty(): + """Test reversing an empty string.""" + assert reverse_string("") == "" + +def test_reverse_string_single_char(): + """Test reversing a single character string.""" + assert reverse_string("a") == "a" + +def test_reverse_string_with_spaces(): + """Test reversing a string with spaces.""" + assert reverse_string("hello world") == "dlrow olleh" + +def test_reverse_string_with_special_chars(): + """Test reversing a string with special characters and mixed content.""" + assert reverse_string("a1b2c3!@#") == "#@!3c2b1a" + +def test_reverse_string_with_unicode(): + """Test reversing a string with unicode characters.""" + assert reverse_string("café") == "éfac" + +def test_reverse_string_invalid_input(): + """Test that TypeError is raised for non-string inputs.""" + with pytest.raises(TypeError, match="Input must be a string"): + reverse_string(123) + + with pytest.raises(TypeError, match="Input must be a string"): + reverse_string(None) + + with pytest.raises(TypeError, match="Input must be a string"): + reverse_string(["hello"]) \ No newline at end of file