Reverse string
To reverse a string we
place the head behind the tail.

def reverse_string_recursive(str):
if len(str) <= 1:
return str
head = str[0]
tail = str[1:]
res = reverse_string_recursive(tail) + head
return res
def reverse_string_iterative(str):
m = len(str)
s =
for i in range(1, m + 1):
s += str[m - i]
return s
assert reverse_string_recursive('S') == 'S'
assert reverse_string_recursive('XY') == 'YX'
assert reverse_string_recursive('CAT') == 'TAC'
assert reverse_string_recursive('Hello World!') == '!dlroW olleH'
assert reverse_string_iterative('S') == 'S'
assert reverse_string_iterative('XY') == 'YX'
assert reverse_string_iterative('CAT') == 'TAC'
assert reverse_string_iterative('Hello World!') == '!dlroW olleH'
try:
reverse_string_recursive('a' * 1000)
except RecursionError as e:
print(e)
str = reverse_string_iterative('a' * 1000)
print(str)
Palindrome
A palindrome is a word
spelled the same forward or backward.

def isPalindrome_recursive(s):
if len(s) <= 1:
return True
first = s[0]
last = s[-1]
middle = s[1:-1]
if first == last:
return isPalindrome_recursive(middle)
return False
def isPalindrome_iterative(s):
m = len(s)
for i in range(0, m):
first = s[i]
last = s[m-1-i]
if first != last:
return False
return True
assert isPalindrome_recursive('level') == True
assert isPalindrome_recursive('rac e car') == True
assert isPalindrome_recursive('levels') == False
assert isPalindrome_recursive('race car') == False
assert isPalindrome_iterative('level') == True
assert isPalindrome_iterative('rac e car') == True
assert isPalindrome_iterative('levels') == False
assert isPalindrome_iterative('race car') == False
import random
def generate_palindrome(length):
chars = [chr(random.randint(97, 122)) for _ in range(length//2)]
reversed = chars[::-1]
return ''.join(chars + reversed)
str_random = generate_palindrome(2000)
print(str_random)
try:
print(isPalindrome_recursive(str_random))
except RecursionError as e:
print("isPalindorme_recursive(str2000)", e)
print("isPalindrome_iterative(str2000)", isPalindrome_iterative(str_random))
Head Permutations
A permutation is a specific ordering of
all elements of a set.

def head_permutations(chars):
head = chars[0]
tail = chars[1:]
prms = []
for k in range(len(tail) + 1):
prms.append(tail[0:k] + head + tail[k:])
return prms
print(', '.join(head_permutations('BC')))
print(', '.join(head_permutations('BCD')))
Permutations
A permutation of a set is a
specific ordering of all elements.

def get_permutations(chars):
if len(chars) == 1:
return [chars]
head = chars[0]
tail = chars[1:]
tail_prms = get_permutations(tail)
prms = []
for tail in tail_prms:
for k in range(len(tail) + 1):
prms.append(tail[0:k] + head + tail[k:])
return prms
print("Permutations without repetition:")
P1 = get_permutations('ABC')
P2 = get_permutations('ABCD')
print(len(P1), ' '.join(P1))
print(len(P2), ' '.join(P2))
Combinations
A combination is a
selection of elements from a set, and order doesn't matter.

def combinations(s, k):
if k == 0: return ['']
if s == '': return []
head = s[:1]
tail = s[1:]
C1 = [head + c for c in combinations(tail, k-1)]
C2 = combinations(tail, k)
return C1 + C2
print("K-Combinations:")
print(' '.join(combinations('ABC', 2)))
print(' '.join(combinations('ABCD', 3)))