diff --git a/solutions/maximum_length.py b/solutions/maximum_length.py new file mode 100644 index 000000000..5789a2f38 --- /dev/null +++ b/solutions/maximum_length.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module to find the maximum length of the +concatenation of a subsequence of arr that has unique characters. + +Return the maximum possible length of s + +Module contents: + - maxLength: Function to get the Maximum Length of a Concatenated String with Unique Characters + - backtrack: Helper function to perform backtracking + +Created on 2024-01-12 +Author: Kefah Albashityalshaer +""" + + +def max_length(arr: list) -> int: + """ + Function to get the Maximum Length of a Concatenated String with Unique Characters + + Takes a list of strings and returns the max length of concatenated string with unique characters + + Parameters: + arr: list of stings elements to process + + Returns -> int: the maximum length + + Examples: + >>> max_length(["un","iq","ue"]) + 4 + >>> max_length(["cha","r","act","ers"]) + 6 + >>> max_length(["abcdefghijklmnopqrstuvwxyz"]) + 26 + >>> max_length(["a", "bb", "ccc"]) + 1 + >>> max_length([]) + 0 + """ + assert isinstance(arr, list), "input should be a list of strings" + + # Helper function to perform backtracking + def backtrack(index, current_string): + # If the current string has duplicate characters, return 0 + if len(current_string) != len(set(current_string)): + return 0 + + # Calculate the maximum length by trying to add each subsequent string + max_length = len(current_string) + for i in range(index, len(arr)): + max_length = max(max_length, backtrack(i + 1, current_string + arr[i])) + return max_length + + # Start the backtracking from index 0 and an empty string + return backtrack(0, "") diff --git a/solutions/tests/test_maximum_length.py b/solutions/tests/test_maximum_length.py new file mode 100644 index 000000000..e4b7b1d94 --- /dev/null +++ b/solutions/tests/test_maximum_length.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Test module for maximum_length function. + +Test categories: + - Standard cases: list of strings that may have unique or overlapping characters + - Edge cases: empty lists, strings with identical bounds or duplicate characters, substrings with repetitive letters + - Defensive tests: invalid inputs, assertions, or `TypeError` exceptions + +Created on 2024-01-12 +Author: Kefah Albashityalshaer +""" + +import unittest + +from ..maximum_length import max_length + + +class TestMaxLengthFunction(unittest.TestCase): + # Standard test cases + def test_basic_cases(self): + self.assertEqual( + max_length(["un", "iq", "ue"]), 4 + ) # "uniq" forms a concatenated string of length 4 + self.assertEqual( + max_length(["cha", "r", "act", "ers"]), 6 + ) # The longest concatenated string is "acters" (length 6) + self.assertEqual( + max_length(["abcdefghijklmnopqrstuvwxyz"]), 26 + ) # The string contains all unique lowercase letters (length 26) + + # Edge Cases + def test_empty_list(self): + self.assertEqual( + max_length([]), 0 + ) # No strings to concatenate, so the result is 0 + + def test_single_element(self): + self.assertEqual(max_length(["a"]), 1) + self.assertEqual(max_length(["abcdef"]), 6) + + def test_no_unique_concatenation(self): + self.assertEqual(max_length(["a", "bb", "ccc"]), 1) + + def test_repeated_characters(self): + self.assertEqual(max_length(["abc", "def", "abc"]), 6) + + def test_large_input(self): + arr = ["ab", "cd", "ef", "gh", "ij", "kl", "mnop"] + self.assertEqual(max_length(arr), 16) # Longest possible combination + + # Defensive tests + def test_invalid_input(self): + with self.assertRaises( + AssertionError, + msg="Input should raise an AssertionError for non-list input.", + ): + max_length("not a list") + + def test_non_string_input(self): + with self.assertRaises(TypeError): + max_length(["abc", 123, "def"]) + + def test_empty_strings(self): + self.assertEqual(max_length(["", "abc", "de"]), 5) + + +if __name__ == "__main__": + unittest.main()