
from timeit import timeit

_lowercase											=    {
    """MALAYALAM""": True,
    """String""": False,
    """rotor""": True,
    """level""": True,
    """A""": True,
    """BB""": True,
    """ABC""": False,
    """amanaplanacanalpanama""": True,  # "a man a plan a canal panama"
}
# Ensure our test data is valid
assert all((key == key[::-1]) is value for key, value in test_data.items())
def 							SCREAMING_SNAKE_CASE_	(					UpperCAmelCase_	:     str				)			->						bool:
       SCREAMING_SNAKE_CASE_							:				int		=0
       SCREAMING_SNAKE_CASE_							:				Optional[Any]		=len(UpperCAmelCase_				) - 1
       while start_i < end_i:
              if s[start_i] == s[end_i]:
                     start_i += 1
                     end_i -= 1
              else:
                     return False
       return True
def 							SCREAMING_SNAKE_CASE_	(					UpperCAmelCase_	:     str				)			->						bool:
       SCREAMING_SNAKE_CASE_							:				Tuple		=len(UpperCAmelCase_				) // 2
       SCREAMING_SNAKE_CASE_							:				Dict		=len(UpperCAmelCase_				)

       # We need to traverse till half of the length of string
       # as we can get access of the i'th last element from
       # i'th index.
       # eg: [0,1,2,3,4,5] => 4th index can be accessed
       # with the help of 1st index (i==n-i-1)
       # where n is length of string
       return all(s[i] == s[n - i - 1] for i in range(UpperCAmelCase_				)				)
def 							SCREAMING_SNAKE_CASE_	(					UpperCAmelCase_	:     str				)			->						bool:
       if len(UpperCAmelCase_				) <= 2:
              return True
       if s[0] == s[len(UpperCAmelCase_				) - 1]:
              return is_palindrome_recursive(s[1:-1]				)
       else:
              return False
def 							SCREAMING_SNAKE_CASE_	(					UpperCAmelCase_	:     str				)			->						bool:
       return s == s[::-1]
def 							SCREAMING_SNAKE_CASE_	(					UpperCAmelCase_	:     str				)			->						None:
       SCREAMING_SNAKE_CASE_							:				Optional[int]		=f'all({name}(key) is value for key, value in test_data.items())'
       SCREAMING_SNAKE_CASE_							:				List[Any]		=f'from __main__ import test_data, {name}'
       SCREAMING_SNAKE_CASE_							:				Optional[Any]		=5_0_0_0_0_0
       SCREAMING_SNAKE_CASE_							:				Any		=timeit(stmt=UpperCAmelCase_			,							setup=UpperCAmelCase_			,							number=UpperCAmelCase_				)
       print(f'{name:<35} finished {number:,} runs in {result:.5f} seconds'				)


if __name__ == "__main__":
 for key, value in test_data.items():
  assert is_palindrome(key) is is_palindrome_recursive(key)
  assert is_palindrome(key) is is_palindrome_slice(key)
  print(F"{key:21} {value}")
 print("""a man a plan a canal panama""")

 # finished 500,000 runs in 0.46793 seconds
 benchmark_function("""is_palindrome_slice""")
 # finished 500,000 runs in 0.85234 seconds
 benchmark_function("""is_palindrome""")
 # finished 500,000 runs in 1.32028 seconds
 benchmark_function("""is_palindrome_recursive""")
 # finished 500,000 runs in 2.08679 seconds
 benchmark_function("""is_palindrome_traversal""")


def 							SCREAMING_SNAKE_CASE_	(					UpperCAmelCase_	:     list				)			->						float:
       SCREAMING_SNAKE_CASE_							:				Dict		=0
       while len(UpperCAmelCase_				) > 1:
              SCREAMING_SNAKE_CASE_							:				Tuple		=0
              # Consider two files with minimum cost to be merged
              for _ in range(2				):
                     SCREAMING_SNAKE_CASE_							:				int		=files.index(min(UpperCAmelCase_				)				)
                     temp += files[min_index]
                     files.pop(UpperCAmelCase_				)
              files.append(UpperCAmelCase_				)
              optimal_merge_cost += temp
       return optimal_merge_cost


if __name__ == "__main__":
 import doctest

 doctest.testmod()
