def factorial(n): print("Entering factorial with n = ", n) # base case: handle directly if n == 1: result = 1 # recursive case. Make a recursive call and use the result to # produce result else: recResult = factorial(n-1) result = n * recResult print("About to leave factorial({}), returning value {}.".format(n, result)) return result def printList(inList): print("input is: ", inList) if inList == []: return else: print(inList[0]) printList(inList[1:]) def printListReverse(inList): if inList == []: return else: print(inList[-1]) printListReverse(inList[:-1]) def printListReverse2(inList): print("entering printListReverse with input: ", inList) if inList == []: return else: printListReverse2(inList[1:]) print(inList[0]) print("leaving printListReverse") def reverseString(inString): if inString == '': return '' elif len(inString) == 1: return inString else: return(reverseString(inString[1:]) + inString[0]) def reverseString2(inString): if inString == '': return '' else: return( inString[-1] + reverseString2(inString[:-1]) ) def sumListItems(inList): if inList == []: return(0) else: return(inList[0] + sumListItems(inList[1:])) def isPalindrome(inString): if len(inString) < 2: return True if (inString[0] != inString[-1]): return False return isPalindrome(inString[1:-1]) def isPalindrome2(inString): if len(inString) < 2: return True else: return((inString[0] == inString[-1]) and (isPalindrome(inString[1:-1]))) # Return the number of digits in non-negative integer n def numDigits(n): if n < 10: return 1 else: q = n // 10 return 1 + numDigits(q) # Return the sum of digits in non-negative integer n def sumDigits(n): if n < 10: return n else: rem = n % 10 # last digit q = n // 10 # number with last removed return rem + sumDigits(q) # Return a new string with each occurrence of fromChar replaced with toChar def ch(s, fromChar, toChar): if len(s) == 0: return s elif s[0] == fromChar: return toChar + ch(s[1:], fromChar, toChar) else: return s[0] + ch(s[1:], fromChar, toChar) # return number of substrings that have same first and last char # sssCount(abaab) returns 9 because there are 5 single char substrings # plus 'aba', 'abaa', 'baab', 'aa' # def sssCount(s): if len(s) == 1: return 1 if len(s) == 0: return 0 c1 = sssCount(s[1:]) # count for all but last c2 = sssCount(s[0:-1]) # count for all but first c3 = sssCount(s[1:-1]) # count for middle total = c1 + c2 - c3 if s[0] == s[-1]: return total + 1 else: return total # don't run this on large numbers (i.e. over 40)! # We'll discuss why later in the semester ... # def fib(n): if (n == 1) or (n == 2): result = 1 else: fnm1 = fib(n-1) fnm2 = fib(n-2) result = fnm1 + fnm2 return result # Same as above but without intermediate variables. # def fib1(n): if (n == 1) or (n == 2): return 1 else: return fib1(n-1) + fib1(n-2) import time def timeFib(n): t1 = time.time() result = fib(n) t2 = time.time() print("fib({}) required {:.4f} seconds.".format(n, t2 - t1)) # a *much* faster version. Still recursive. # you are not required to unnderstand this. fibTable = ['-', 1, 1] def fibFast(n): #print("fib called with", n, fibTable) if n < len(fibTable): result = fibTable[n] else: result = fibFast(n-1) + fibFast(n-2) #print("adding to table") fibTable.append(result) #print("leaving fib: ", n) return result def timeFibFast(n): t1 = time.time() result = fibFast(n) t2 = time.time() print("fibFast({}) required {:.4f} seconds.".format(n, t2 - t1))