From a78facdaa5d70251b4b494af4e0161e530facc19 Mon Sep 17 00:00:00 2001 From: svedire Date: Sat, 19 Sep 2020 15:40:05 +0530 Subject: [PATCH 1/6] Added check_if_string_can_be_rearranged_as_palindrome function. --- ...f_string_can_be_converted_to_palindrome.py | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 strings/check_if_string_can_be_converted_to_palindrome.py diff --git a/strings/check_if_string_can_be_converted_to_palindrome.py b/strings/check_if_string_can_be_converted_to_palindrome.py new file mode 100644 index 000000000000..a198ccd605ef --- /dev/null +++ b/strings/check_if_string_can_be_converted_to_palindrome.py @@ -0,0 +1,60 @@ +# Created by susmith98 + +# Problem Description: +# Check if characters of the given string can be rearranged to form a palindrome. + +def check_if_string_can_be_rearranged_as_palindrome(input_str: str = "",) -> bool: + """ + A Palindrome is a String that reads the same forward as it does backwards. + Examples of Palindromes mom, dad, malayalam + >>> check_if_string_can_be_rearranged_as_palindrome("Momo") + True + >>> check_if_string_can_be_rearranged_as_palindrome("Mother") + False + >>> check_if_string_can_be_rearranged_as_palindrome("Father") + False + """ + if len(input_str) == 0: + return True + lower_case_input_str = input_str.lower() + # character_freq_dict: Stores the frequency of every character in the input string + character_freq_dict = {} + + for character in lower_case_input_str: + character_freq_dict[character] = character_freq_dict.get(character, 0) + 1 + """ + Above line of code is equivalent to: + 1) Getting the frequency of current character till previous index + >>> character_freq = character_freq_dict.get(character, 0) + 2) Incrementing the frequency of current character by 1 + >>> character_freq = character_freq + 1 + 3) Updating the frequency of current character + >>> character_freq_dict[character] = character_freq + """ + """ + OBSERVATIONS: + Even length palindrome + -> Every character appears even no.of times. + Odd length palindrome + -> Every character appears even no.of times except for one character. + LOGIC: + Step 1: We'll count number of characters that appear odd number of times i.e oddChar + Step 2:If we find more than 1 character that appears odd number of times, + It is not possible to rearrange as a palindrome + """ + oddChar = 0 + + for character_count in character_freq_dict.values(): + if character_count % 2 == 1: + oddChar = oddChar + 1 + if oddChar > 1: + return False + return True + + +if __name__ == "__main__": + check_str = input( + "Enter string to determine if it can be rearranged as a palindrome or not: " + ).strip() + status = check_if_string_can_be_rearranged_as_palindrome(check_str) + print(f"{check_str} can {'' if status else 'not '}be rearranged as a palindrome") From 9a31de43ad935affc6a07d3d2fd5ae7478775627 Mon Sep 17 00:00:00 2001 From: svedire Date: Sat, 19 Sep 2020 21:02:15 +0530 Subject: [PATCH 2/6] Added counter implementation and benchmark function. --- ...f_string_can_be_converted_to_palindrome.py | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/strings/check_if_string_can_be_converted_to_palindrome.py b/strings/check_if_string_can_be_converted_to_palindrome.py index a198ccd605ef..429702cf602c 100644 --- a/strings/check_if_string_can_be_converted_to_palindrome.py +++ b/strings/check_if_string_can_be_converted_to_palindrome.py @@ -1,9 +1,25 @@ # Created by susmith98 +from collections import Counter +from timeit import timeit + # Problem Description: # Check if characters of the given string can be rearranged to form a palindrome. -def check_if_string_can_be_rearranged_as_palindrome(input_str: str = "",) -> bool: +def check_if_string_can_be_rearranged_as_palindrome_counter(input_str: str = "",) -> bool: + """ + A Palindrome is a String that reads the same forward as it does backwards. + Examples of Palindromes mom, dad, malayalam + >>> check_if_string_can_be_rearranged_as_palindrome("Momo") + True + >>> check_if_string_can_be_rearranged_as_palindrome("Mother") + False + >>> check_if_string_can_be_rearranged_as_palindrome("Father") + False + """ + return sum(c % 2 for c in Counter(input_str.lower()).values()) < 2 + +def check_if_string_can_be_rearranged_as_palindrome(input_str: str = "") -> bool: """ A Palindrome is a String that reads the same forward as it does backwards. Examples of Palindromes mom, dad, malayalam @@ -51,10 +67,33 @@ def check_if_string_can_be_rearranged_as_palindrome(input_str: str = "",) -> boo return False return True +def benchmark(input_str: str = "") -> None: + """ + Benchmark code for comparing above 2 functions + """ + print("\nFor string = ", input_str, ":") + print( + "> check_if_string_can_be_rearranged_as_palindrome()", + "\tans =", + check_if_string_can_be_rearranged_as_palindrome(input_str), + "\ttime =", + timeit("z.check_if_string_can_be_rearranged_as_palindrome(z.check_str)", setup="import __main__ as z"), + "seconds", + ) + print( + "> check_if_string_can_be_rearranged_as_palindrome_counter()", + "\tans =", + check_if_string_can_be_rearranged_as_palindrome_counter(input_str), + "\ttime =", + timeit("z.check_if_string_can_be_rearranged_as_palindrome_counter(z.check_str)", setup="import __main__ as z"), + "seconds", + ) + if __name__ == "__main__": check_str = input( "Enter string to determine if it can be rearranged as a palindrome or not: " ).strip() - status = check_if_string_can_be_rearranged_as_palindrome(check_str) + benchmark(check_str) + status = check_if_string_can_be_rearranged_as_palindrome_counter(check_str) print(f"{check_str} can {'' if status else 'not '}be rearranged as a palindrome") From a034156f9e7f494ae1e545570298ab3d16943f96 Mon Sep 17 00:00:00 2001 From: svedire Date: Sat, 19 Sep 2020 21:10:27 +0530 Subject: [PATCH 3/6] flake changes --- ..._if_string_can_be_converted_to_palindrome.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/strings/check_if_string_can_be_converted_to_palindrome.py b/strings/check_if_string_can_be_converted_to_palindrome.py index 429702cf602c..950752f80a7b 100644 --- a/strings/check_if_string_can_be_converted_to_palindrome.py +++ b/strings/check_if_string_can_be_converted_to_palindrome.py @@ -6,7 +6,10 @@ # Problem Description: # Check if characters of the given string can be rearranged to form a palindrome. -def check_if_string_can_be_rearranged_as_palindrome_counter(input_str: str = "",) -> bool: + +def check_if_string_can_be_rearranged_as_palindrome_counter( + input_str: str = "", +) -> bool: """ A Palindrome is a String that reads the same forward as it does backwards. Examples of Palindromes mom, dad, malayalam @@ -19,6 +22,7 @@ def check_if_string_can_be_rearranged_as_palindrome_counter(input_str: str = "", """ return sum(c % 2 for c in Counter(input_str.lower()).values()) < 2 + def check_if_string_can_be_rearranged_as_palindrome(input_str: str = "") -> bool: """ A Palindrome is a String that reads the same forward as it does backwards. @@ -67,6 +71,7 @@ def check_if_string_can_be_rearranged_as_palindrome(input_str: str = "") -> bool return False return True + def benchmark(input_str: str = "") -> None: """ Benchmark code for comparing above 2 functions @@ -77,7 +82,10 @@ def benchmark(input_str: str = "") -> None: "\tans =", check_if_string_can_be_rearranged_as_palindrome(input_str), "\ttime =", - timeit("z.check_if_string_can_be_rearranged_as_palindrome(z.check_str)", setup="import __main__ as z"), + timeit( + "z.check_if_string_can_be_rearranged_as_palindrome(z.check_str)", + setup="import __main__ as z", + ), "seconds", ) print( @@ -85,7 +93,10 @@ def benchmark(input_str: str = "") -> None: "\tans =", check_if_string_can_be_rearranged_as_palindrome_counter(input_str), "\ttime =", - timeit("z.check_if_string_can_be_rearranged_as_palindrome_counter(z.check_str)", setup="import __main__ as z"), + timeit( + "z.check_if_string_can_be_rearranged_as_palindrome_counter(z.check_str)", + setup="import __main__ as z", + ), "seconds", ) From 0b9110932960a7b8fcd2d4ad6858c52f176068b0 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sat, 19 Sep 2020 20:30:03 +0200 Subject: [PATCH 4/6] Update and rename check_if_string_can_be_converted_to_palindrome.py to can_string_be_rearranged_as_palindrome.py --- ...can_string_be_rearranged_as_palindrome.py} | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) rename strings/{check_if_string_can_be_converted_to_palindrome.py => can_string_be_rearranged_as_palindrome.py} (63%) diff --git a/strings/check_if_string_can_be_converted_to_palindrome.py b/strings/can_string_be_rearranged_as_palindrome.py similarity index 63% rename from strings/check_if_string_can_be_converted_to_palindrome.py rename to strings/can_string_be_rearranged_as_palindrome.py index 950752f80a7b..dffdc57cbc5d 100644 --- a/strings/check_if_string_can_be_converted_to_palindrome.py +++ b/strings/can_string_be_rearranged_as_palindrome.py @@ -5,38 +5,41 @@ # Problem Description: # Check if characters of the given string can be rearranged to form a palindrome. +# Counter is faster for long strings and non-Counter is faster for shorter strings. -def check_if_string_can_be_rearranged_as_palindrome_counter( - input_str: str = "", -) -> bool: +def can_string_be_rearranged_as_palindrome_counter(input_str: str = "",) -> bool: """ A Palindrome is a String that reads the same forward as it does backwards. Examples of Palindromes mom, dad, malayalam - >>> check_if_string_can_be_rearranged_as_palindrome("Momo") + >>> can_string_be_rearranged_as_palindrome_counter("Momo") True - >>> check_if_string_can_be_rearranged_as_palindrome("Mother") + >>> can_string_be_rearranged_as_palindrome_counter("Mother") False - >>> check_if_string_can_be_rearranged_as_palindrome("Father") + >>> can_string_be_rearranged_as_palindrome_counter("Father") False + >>> can_string_be_rearranged_as_palindrome_counter("A man a plan a canal Panama") + True """ - return sum(c % 2 for c in Counter(input_str.lower()).values()) < 2 + return sum(c % 2 for c in Counter(input_str.replace(" ", "").lower()).values()) < 2 -def check_if_string_can_be_rearranged_as_palindrome(input_str: str = "") -> bool: +def can_string_be_rearranged_as_palindrome(input_str: str = "") -> bool: """ A Palindrome is a String that reads the same forward as it does backwards. Examples of Palindromes mom, dad, malayalam - >>> check_if_string_can_be_rearranged_as_palindrome("Momo") + >>> can_string_be_rearranged_as_palindrome("Momo") True - >>> check_if_string_can_be_rearranged_as_palindrome("Mother") + >>> can_string_be_rearranged_as_palindrome("Mother") False - >>> check_if_string_can_be_rearranged_as_palindrome("Father") + >>> can_string_be_rearranged_as_palindrome("Father") False + >>> can_string_be_rearranged_as_palindrome_counter("A man a plan a canal Panama") + True """ if len(input_str) == 0: return True - lower_case_input_str = input_str.lower() + lower_case_input_str = input_str.replace(" ", "").lower() # character_freq_dict: Stores the frequency of every character in the input string character_freq_dict = {} @@ -65,8 +68,8 @@ def check_if_string_can_be_rearranged_as_palindrome(input_str: str = "") -> bool oddChar = 0 for character_count in character_freq_dict.values(): - if character_count % 2 == 1: - oddChar = oddChar + 1 + if character_count % 2: + oddChar += 1 if oddChar > 1: return False return True @@ -78,23 +81,23 @@ def benchmark(input_str: str = "") -> None: """ print("\nFor string = ", input_str, ":") print( - "> check_if_string_can_be_rearranged_as_palindrome()", + "> can_string_be_rearranged_as_palindrome_counter()", "\tans =", - check_if_string_can_be_rearranged_as_palindrome(input_str), + can_string_be_rearranged_as_palindrome_counter(input_str), "\ttime =", timeit( - "z.check_if_string_can_be_rearranged_as_palindrome(z.check_str)", + "z.can_string_be_rearranged_as_palindrome_counter(z.check_str)", setup="import __main__ as z", ), "seconds", ) print( - "> check_if_string_can_be_rearranged_as_palindrome_counter()", + "> can_string_be_rearranged_as_palindrome()", "\tans =", - check_if_string_can_be_rearranged_as_palindrome_counter(input_str), + can_string_be_rearranged_as_palindrome(input_str), "\ttime =", timeit( - "z.check_if_string_can_be_rearranged_as_palindrome_counter(z.check_str)", + "z.can_string_be_rearranged_as_palindrome(z.check_str)", setup="import __main__ as z", ), "seconds", @@ -106,5 +109,5 @@ def benchmark(input_str: str = "") -> None: "Enter string to determine if it can be rearranged as a palindrome or not: " ).strip() benchmark(check_str) - status = check_if_string_can_be_rearranged_as_palindrome_counter(check_str) + status = can_string_be_rearranged_as_palindrome_counter(check_str) print(f"{check_str} can {'' if status else 'not '}be rearranged as a palindrome") From cd54a954a3fcd6b2beb3ba5da6ba9d0cfcd4818a Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sat, 19 Sep 2020 20:31:03 +0200 Subject: [PATCH 5/6] Update can_string_be_rearranged_as_palindrome.py --- strings/can_string_be_rearranged_as_palindrome.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/strings/can_string_be_rearranged_as_palindrome.py b/strings/can_string_be_rearranged_as_palindrome.py index dffdc57cbc5d..62c273d81f1a 100644 --- a/strings/can_string_be_rearranged_as_palindrome.py +++ b/strings/can_string_be_rearranged_as_palindrome.py @@ -5,7 +5,7 @@ # Problem Description: # Check if characters of the given string can be rearranged to form a palindrome. -# Counter is faster for long strings and non-Counter is faster for shorter strings. +# Counter is faster for long strings and non-Counter is faster for short strings. def can_string_be_rearranged_as_palindrome_counter(input_str: str = "",) -> bool: From ea45a39158874acaf56bbd3b1e7f65ea31797ec3 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sat, 19 Sep 2020 20:38:14 +0200 Subject: [PATCH 6/6] # --- strings/can_string_be_rearranged_as_palindrome.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/strings/can_string_be_rearranged_as_palindrome.py b/strings/can_string_be_rearranged_as_palindrome.py index 62c273d81f1a..92bc3b95b243 100644 --- a/strings/can_string_be_rearranged_as_palindrome.py +++ b/strings/can_string_be_rearranged_as_palindrome.py @@ -5,7 +5,7 @@ # Problem Description: # Check if characters of the given string can be rearranged to form a palindrome. -# Counter is faster for long strings and non-Counter is faster for short strings. +# Counter is faster for long strings and non-Counter is faster for short strings. def can_string_be_rearranged_as_palindrome_counter(input_str: str = "",) -> bool: