diff --git a/backtracking/remove_invalid_parenthese.py b/backtracking/remove_invalid_parenthese.py new file mode 100644 index 000000000000..756c169b9d58 --- /dev/null +++ b/backtracking/remove_invalid_parenthese.py @@ -0,0 +1,118 @@ +def remove_invalid_parentheses(input_string: str) -> list[str]: + """ + Removes the minimum number of invalid parentheses + to make the input string valid. + + Args: + input_string (str): The input string containing parentheses. + + Returns: + List[str]: A list of valid strings after removing + the minimum number of parentheses. + + Examples: + >>> remove_invalid_parentheses(")(a)())") + ['(a())', '(a)()'] + + >>> remove_invalid_parentheses("()())()") + ['(())()', '()()()'] + + >>> remove_invalid_parentheses(")(") + [''] + """ + + def is_valid(next_string: str) -> bool: + """ + Helper function to check if a string has valid parentheses. + + Params: + next_string (str): The input string to be checked. + Returns: + bool: True if the parentheses in the string are valid, False otherwise. + + Examples: + >>> is_valid("(a)())") + False + + >>> is_valid("(a())") + True + + >>> is_valid(")(a)()") + False + + """ + count: int = 0 + for char in next_string: + if char == "(": + count += 1 + elif char == ")": + count -= 1 + if count < 0: + return False + return count == 0 + + def dfs( + current_string: str, start_index: int, left_removed: int, right_removed: int + ) -> None: + """ + Depth-first search function to generate valid combinations + of the input string. + + Params: + current_string (str): The current string being processed. + start_index (int): The index to start processing from. + left_removed (int): The number of left parentheses to be removed. + right_removed (int): The number of right parentheses to be removed. + Returns: + None + Examples: + >>> dfs("()())()", 0, 0, 1) + None + + >>> dfs("()())(", 6, 0, 0) + None + + >>> dfs(")(a)())", 0, 0,, 2) + None + """ + if left_removed == 0 and right_removed == 0: + if is_valid(current_string): + valid_parentheses.add(current_string) + return + for i in range(start_index, len(current_string)): + if i > start_index and current_string[i] == current_string[i - 1]: + continue + if current_string[i] == "(" and left_removed > 0: + dfs( + current_string[:i] + current_string[i + 1 :], + i, + left_removed - 1, + right_removed, + ) + elif current_string[i] == ")" and right_removed > 0: + dfs( + current_string[:i] + current_string[i + 1 :], + i, + left_removed, + right_removed - 1, + ) + + valid_parentheses: set = set() + left_removed_count = 0 + right_removed_count = 0 + for char in input_string: + if char == "(": + left_removed_count += 1 + elif char == ")": + if left_removed_count > 0: + left_removed_count -= 1 + else: + right_removed_count += 1 + dfs(input_string, 0, left_removed_count, right_removed_count) + return sorted(valid_parentheses) + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/conversions/binary_to_decimal.py b/conversions/binary_to_decimal.py deleted file mode 100644 index 914a9318c225..000000000000 --- a/conversions/binary_to_decimal.py +++ /dev/null @@ -1,43 +0,0 @@ -def bin_to_decimal(bin_string: str) -> int: - """ - Convert a binary value to its decimal equivalent - - >>> bin_to_decimal("101") - 5 - >>> bin_to_decimal(" 1010 ") - 10 - >>> bin_to_decimal("-11101") - -29 - >>> bin_to_decimal("0") - 0 - >>> bin_to_decimal("a") - Traceback (most recent call last): - ... - ValueError: Non-binary value was passed to the function - >>> bin_to_decimal("") - Traceback (most recent call last): - ... - ValueError: Empty string was passed to the function - >>> bin_to_decimal("39") - Traceback (most recent call last): - ... - ValueError: Non-binary value was passed to the function - """ - bin_string = str(bin_string).strip() - if not bin_string: - raise ValueError("Empty string was passed to the function") - is_negative = bin_string[0] == "-" - if is_negative: - bin_string = bin_string[1:] - if not all(char in "01" for char in bin_string): - raise ValueError("Non-binary value was passed to the function") - decimal_number = 0 - for char in bin_string: - decimal_number = 2 * decimal_number + int(char) - return -decimal_number if is_negative else decimal_number - - -if __name__ == "__main__": - from doctest import testmod - - testmod() diff --git a/conversions/binary_to_gray.py b/conversions/binary_to_gray.py new file mode 100644 index 000000000000..e94fe67b77f6 --- /dev/null +++ b/conversions/binary_to_gray.py @@ -0,0 +1,42 @@ +""" +This code converts gray code to binary +and +binary code to gray code. +""" + + +def binary_to_gray(binary: str) -> str: + """ + Convert a binary number to Gray code + binary: A binary number as a string. + return: The Gray code representation as a string. + >>> binary_to_gray("1101101") + '1011011' + + """ + gray = binary[0] + for i in range(1, len(binary)): + gray_bit = int(binary[i]) ^ int(binary[i - 1]) + gray += str(gray_bit) + return gray + + +def gray_to_binary(gray: str) -> str: + """ + Convert Gray code to binary. + + gray: A Gray code representation as a string. + return: The binary number as a string. + >>> gray_to_binary("1011110") + '1101011' + """ + binary = gray[0] + for i in range(1, len(gray)): + binary_bit = int(gray[i]) ^ int(binary[i - 1]) + binary += str(binary_bit) + return binary + + +if __name__ == "__main__": + import doctest + doctest.testmod()