susmith98 problem description check if characters of the given string can be rearranged to form a palindrome counter is faster for long strings and noncounter is faster for short strings a palindrome is a string that reads the same forward as it does backwards examples of palindromes mom dad malayalam canstringberearrangedaspalindromecountermomo true canstringberearrangedaspalindromecountermother false canstringberearrangedaspalindromecounterfather false canstringberearrangedaspalindromecountera man a plan a canal panama true a palindrome is a string that reads the same forward as it does backwards examples of palindromes mom dad malayalam canstringberearrangedaspalindromemomo true canstringberearrangedaspalindromemother false canstringberearrangedaspalindromefather false canstringberearrangedaspalindromecountera man a plan a canal panama true characterfreqdict stores the frequency of every character in the input string above line of code is equivalent to 1 getting the frequency of current character till previous index characterfreq characterfreqdict getcharacter 0 2 incrementing the frequency of current character by 1 characterfreq characterfreq 1 3 updating the frequency of current character characterfreqdictcharacter characterfreq 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 benchmark code for comparing above 2 functions susmith98 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 a palindrome is a string that reads the same forward as it does backwards examples of palindromes mom dad malayalam can_string_be_rearranged_as_palindrome_counter momo true can_string_be_rearranged_as_palindrome_counter mother false can_string_be_rearranged_as_palindrome_counter father false can_string_be_rearranged_as_palindrome_counter a man a plan a canal panama true a palindrome is a string that reads the same forward as it does backwards examples of palindromes mom dad malayalam can_string_be_rearranged_as_palindrome momo true can_string_be_rearranged_as_palindrome mother false can_string_be_rearranged_as_palindrome father false can_string_be_rearranged_as_palindrome_counter a man a plan a canal panama true character_freq_dict stores the frequency of every character in the input string 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 benchmark code for comparing above 2 functions
from collections import Counter
from timeit import timeit






def can_string_be_rearranged_as_palindrome_counter(
    input_str: str = "",
) -> bool:
    
    return sum(c % 2 for c in Counter(input_str.replace(" ", "").lower()).values()) < 2


def can_string_be_rearranged_as_palindrome(input_str: str = "") -> bool:
    
    if len(input_str) == 0:
        return True
    lower_case_input_str = input_str.replace(" ", "").lower()
    
    character_freq_dict: dict[str, int] = {}

    for character in lower_case_input_str:
        character_freq_dict[character] = character_freq_dict.get(character, 0) + 1
    
    
    odd_char = 0

    for character_count in character_freq_dict.values():
        if character_count % 2:
            odd_char += 1
    if odd_char > 1:
        return False
    return True


def benchmark(input_str: str = "") -> None:
    
    print("\nFor string = ", input_str, ":")
    print(
        "> can_string_be_rearranged_as_palindrome_counter()",
        "\tans =",
        can_string_be_rearranged_as_palindrome_counter(input_str),
        "\ttime =",
        timeit(
            "z.can_string_be_rearranged_as_palindrome_counter(z.check_str)",
            setup="import __main__ as z",
        ),
        "seconds",
    )
    print(
        "> can_string_be_rearranged_as_palindrome()",
        "\tans =",
        can_string_be_rearranged_as_palindrome(input_str),
        "\ttime =",
        timeit(
            "z.can_string_be_rearranged_as_palindrome(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()
    benchmark(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")