From d08b10bcd4a4f1f4a3416049a90e028974ba5939 Mon Sep 17 00:00:00 2001 From: Faithy4444 <161722786+Faithy4444@users.noreply.github.com> Date: Sat, 25 Oct 2025 10:50:50 +0200 Subject: [PATCH] improve with precomputing --- .../common_prefix/common_prefix.py | 37 +++++++++++-------- .../count_letters/count_letters.py | 17 ++++----- 2 files changed, 29 insertions(+), 25 deletions(-) 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..85fa6ed 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,31 @@ from typing import List - -def find_longest_common_prefix(strings: List[str]): +def find_longest_common_prefix(strings: List[str]) -> 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. + Returns the longest string common at the start of any two strings in the list. """ + if len(strings) < 2: + return "" + + # Precompute the set of prefixes for each string + prefixes = {} + for s in strings: + prefixes[s] = [s[:i] for i in range(1, len(s) + 1)] + longest = "" - for string_index, string in enumerate(strings): - for other_string in strings[string_index+1:]: - common = find_common_prefix(string, other_string) + n = len(strings) + for i in range(n): + for j in range(i + 1, n): + # Compare prefixes of strings[i] and strings[j] efficiently + common = _common_prefix_precomputed(prefixes[strings[i]], strings[j]) if len(common) > len(longest): longest = common - return longest + 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] +def _common_prefix_precomputed(prefix_list: List[str], other: str) -> str: + # Find the longest prefix of other that exists in prefix_list + for prefix in reversed(prefix_list): + if other.startswith(prefix): + return prefix + return "" 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..f9e71c0 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,11 @@ def count_letters(s: str) -> int: """ - count_letters returns the number of letters which only occur in upper case in the passed string. + 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) - + # Precompute sets of lowercase and uppercase letters in the string + lower_letters = {c for c in s if c.islower()} + upper_letters = {c for c in s if c.isupper()} -def is_upper_case(letter: str) -> bool: - return letter == letter.upper() + # Count letters that appear only in uppercase + only_upper = {c for c in upper_letters if c.lower() not in lower_letters} + return len(only_upper)