diff --git a/.gitignore b/.gitignore index bfb5886..e6a373a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ .DS_Store node_modules -.venv +venv __pycache__ diff --git a/Sprint-2/improve_with_precomputing/common_prefix/common_prefix.py b/Sprint-2/improve_with_precomputing/common_prefix/common_prefix.py index f4839e7..3a60a9c 100644 --- a/Sprint-2/improve_with_precomputing/common_prefix/common_prefix.py +++ b/Sprint-2/improve_with_precomputing/common_prefix/common_prefix.py @@ -1,24 +1,29 @@ from typing import List - def find_longest_common_prefix(strings: List[str]): """ find_longest_common_prefix returns the longest string common at the start of any two strings in the passed list. In the event that an empty list, a list containing one string, or a list of strings with no common prefixes is passed, the empty string will be returned. """ + if len(strings) < 2: + return "" + + # Precompute by sorting - longest common prefixes will be between adjacent strings + sorted_strings = sorted(strings) longest = "" - for string_index, string in enumerate(strings): - for other_string in strings[string_index+1:]: - common = find_common_prefix(string, other_string) - if len(common) > len(longest): - longest = common + + # Compare each string with its neighbor to find common prefixes + for i in range(len(sorted_strings) - 1): + common = find_common_prefix(sorted_strings[i], sorted_strings[i + 1]) + if len(common) > len(longest): + longest = common + return longest - def find_common_prefix(left: str, right: str) -> str: min_length = min(len(left), len(right)) for i in range(min_length): if left[i] != right[i]: return left[:i] - return left[:min_length] + return left[:min_length] \ No newline at end of file diff --git a/Sprint-2/improve_with_precomputing/common_prefix/common_prefix_test.py b/Sprint-2/improve_with_precomputing/common_prefix/common_prefix_test.py index a22ef79..e279b83 100644 --- a/Sprint-2/improve_with_precomputing/common_prefix/common_prefix_test.py +++ b/Sprint-2/improve_with_precomputing/common_prefix/common_prefix_test.py @@ -36,5 +36,32 @@ def test_really_long_list(self): common_prefix = find_longest_common_prefix(strings) self.assertRegex(common_prefix, "^hello.*$") + def test_multiple_equal_length_prefixes(self): + """Test when there are multiple prefixes of the same length""" + strings = [ + "apple_pie", + "apple_cider", + "banana_split", + "grape_bread", + "grape_pie" + ] + # Both "apple_" and "grape_" are length 6, either could be returned + result = find_longest_common_prefix(strings) + self.assertTrue(result in ["apple_", "grape_"]) + self.assertEqual(len(result), 6) + + def test_identical_strings(self): + """Test when multiple strings are identical""" + strings = [ + "identical", + "different", + "identical", + "identical", + "another" + ] + # The longest prefix is between identical strings: "identical" + self.assertEqual(find_longest_common_prefix(strings), "identical") + + if __name__ == "__main__": unittest.main() diff --git a/Sprint-2/improve_with_precomputing/count_letters/count_letters.py b/Sprint-2/improve_with_precomputing/count_letters/count_letters.py index 62c3ec0..4084798 100644 --- a/Sprint-2/improve_with_precomputing/count_letters/count_letters.py +++ b/Sprint-2/improve_with_precomputing/count_letters/count_letters.py @@ -1,14 +1,25 @@ def count_letters(s: str) -> int: - """ + """ count_letters returns the number of letters which only occur in upper case in the passed string. """ - only_upper = set() - for letter in s: - if is_upper_case(letter): - if letter.lower() not in s: - only_upper.add(letter) - return len(only_upper) - - -def is_upper_case(letter: str) -> bool: - return letter == letter.upper() + if not s: + return 0 + + # Precompute using fixed arrays for maximum performance + has_upper = [False] * 26 + has_lower = [False] * 26 + + for char in s: + code = ord(char) + if 65 <= code <= 90: # A-Z + has_upper[code - 65] = True + elif 97 <= code <= 122: # a-z + has_lower[code - 97] = True + + # Count uppercase letters without lowercase counterparts + count = 0 + for i in range(26): + if has_upper[i] and not has_lower[i]: + count += 1 + + return count \ No newline at end of file