11# Algorithms to determine if a string is palindrome
22
3+ from timeit import timeit
4+
35test_data = {
46 "MALAYALAM" : True ,
57 "String" : False ,
@@ -33,14 +35,33 @@ def is_palindrome(s: str) -> bool:
3335 return True
3436
3537
38+ def is_palindrome_traversal (s : str ) -> bool :
39+ """
40+ Return True if s is a palindrome otherwise return False.
41+
42+ >>> all(is_palindrome_traversal(key) is value for key, value in test_data.items())
43+ True
44+ """
45+ end = len (s ) // 2
46+ n = len (s )
47+
48+ # We need to traverse till half of the length of string
49+ # as we can get access of the i'th last element from
50+ # i'th index.
51+ # eg: [0,1,2,3,4,5] => 4th index can be accessed
52+ # with the help of 1st index (i==n-i-1)
53+ # where n is length of string
54+ return all (s [i ] == s [n - i - 1 ] for i in range (end ))
55+
56+
3657def is_palindrome_recursive (s : str ) -> bool :
3758 """
3859 Return True if s is a palindrome otherwise return False.
3960
4061 >>> all(is_palindrome_recursive(key) is value for key, value in test_data.items())
4162 True
4263 """
43- if len (s ) <= 1 :
64+ if len (s ) <= 2 :
4465 return True
4566 if s [0 ] == s [len (s ) - 1 ]:
4667 return is_palindrome_recursive (s [1 :- 1 ])
@@ -58,9 +79,26 @@ def is_palindrome_slice(s: str) -> bool:
5879 return s == s [::- 1 ]
5980
6081
82+ def benchmark_function (name : str ) -> None :
83+ stmt = f"all({ name } (key) is value for key, value in test_data.items())"
84+ setup = f"from __main__ import test_data, { name } "
85+ number = 500000
86+ result = timeit (stmt = stmt , setup = setup , number = number )
87+ print (f"{ name :<35} finished { number :,} runs in { result :.5f} seconds" )
88+
89+
6190if __name__ == "__main__" :
6291 for key , value in test_data .items ():
6392 assert is_palindrome (key ) is is_palindrome_recursive (key )
6493 assert is_palindrome (key ) is is_palindrome_slice (key )
6594 print (f"{ key :21} { value } " )
6695 print ("a man a plan a canal panama" )
96+
97+ # finished 500,000 runs in 0.46793 seconds
98+ benchmark_function ("is_palindrome_slice" )
99+ # finished 500,000 runs in 0.85234 seconds
100+ benchmark_function ("is_palindrome" )
101+ # finished 500,000 runs in 1.32028 seconds
102+ benchmark_function ("is_palindrome_recursive" )
103+ # finished 500,000 runs in 2.08679 seconds
104+ benchmark_function ("is_palindrome_traversal" )
0 commit comments