1. Recursion
a funny game “Cat in the Hat”
http://www.codeskulptor.org/#poc_cat_in_the_hat.py
example for recursion
#sum_up_to(n):
# base case: 1 when n = 1
# recursive case: n + sum_up_to(n-1) when n > 1
def sum_up_to(n):
# base case
if n == 1:
return 1
# recursive case
else:
return n + sum_up_to(n-1)
def is_palindrome(word):
if len(word) < 2:
# base case
return True
else:
# recursive case
if word[0] != word[-1]:
return False
else:
return is_palindrome(word[1:-1])
def gen_all_permutations(outcomes):
answer_set = set()
if len(outcomes) == 1:
perm = list(outcomes)
answer_set.add(tuple(perm))
return answer_set
rest_permutations = list(gen_all_permutations(outcomes[1 :]))
for perm in rest_permutations:
for idx in range(len(perm) + 1):
temp_list = list(perm)
temp_list.insert(idx, outcomes[0])
answer_set.add(tuple(temp_list))
return answer_set
2. Binary Search
Binary Search codes:
http://www.codeskulptor.org/#poc_binary_search.py
Linear Search: search the element by scanning the list
# Search element in a list
# for i = 0 to n -1
# if L[i] == K
# return True
# return False
Binary Search: compare the element with the middle number in the list to choose upper list or lower list for next search (the list is sorted)
def binary_search(sort_list, element):
if len(sort_list) == 1:
# base case
return sort_list[0] == element
mid = len(sort_list) / 2
if sort_list[mid] > element:
return binary_search(sort_list[: mid], element)
else:
return binary_search(sort_list[mid :], element)
3. Recurrences
Solutions to common recurrences
When building recursive programs, knowing the closed-form solutions to common recurrences is helpful since this knowledge can guide you towards building efficient programs. Below, we list various common recurrences and their approximate solutions.In all cases, we assume that f(1)=1 .
- f(n)=f(n−1)+1→f(n)=n
- f(n)=f(n−1)+n→f(n)=12n(n+1)
- f(n)=2f(n−1)→f(n)=2n−1
- f(n)=n f(n−1)→f(n)=n!
- f(n)=f(n2)+1 →f(n)≈log2(n)+1
- f(n)=f(n2)+n →f(n)≈2n−1
- f(n)=2f(n2) →f(n)≈n
- f(n)=2f(n2)+1→f(n)≈2n−1
- f(n)=2f(n2)+n→f(n)≈n(log2(n)+1)
This recursive Python function that computes the Fibonacci numbers is not efficient
def fib(num):
if num == 0:
return 0
elif num == 1:
return 1
else:
return fib(num - 1) + fib(num - 2)
One technique for avoiding this issue is memoization , a technique in which the values computed by calls to fib are stored in an auxiliary dictionary for later use.
def memoized_fib(num, memo_dict):
if num in memo_dict:
return memo_dict[num]
else:
sum1 = memoized_fib(num - 1, memo_dict)
sum2 = memoized_fib(num - 2, memo_dict)
memo_dict[num] = sum1 + sum2
return sum1 + sum2
4. Reading Files
# Reading files from the network
import urllib2
import codeskulptor
FILENAME = "examples_files_dracula.txt"
# http://codeskulptor-examples.commondatastorage.googleapis.com/examples_files_dracula.txt
url = codeskulptor.file2url(FILENAME)
netfile = urllib2.urlopen(url)
# read() only works once
data = netfile.read()
print data
print type(data)
# readlines() only works once
for line in netfile.readlines():
print line
#print line[:-1]
# Reading files from the network
import urllib2
import codeskulptor
FILENAME = "examples_files_dracula.txt"
# http://codeskulptor-examples.commondatastorage.googleapis.com/examples_files_dracula.txt
url = codeskulptor.file2url(FILENAME)
netfile = urllib2.urlopen(url)
# read() only works once
data = netfile.read()
print data
print type(data)
# readlines() only works once
for line in netfile.readlines():
print line
#print line[:-1]
5. Word Wrangler
1. *merge sorted list & merge_sort*
def merge(list1, list2):
"""
Merge two sorted lists.
Returns a new sorted list containing all of the elements that
are in either list1 and list2.
This function can be iterative.
"""
merged_list = []
# duplicate the input lists
temp_list1 = list(list1)
temp_list2 = list(list2)
while len(temp_list1) and len(temp_list2):
if temp_list1[0] < temp_list2[0]:
merged_list.append(temp_list1.pop(0))
else:
merged_list.append(temp_list2.pop(0))
if len(temp_list1) == 0:
merged_list.extend(temp_list2)
elif len(temp_list2) == 0:
merged_list.extend(temp_list1)
return merged_list
def merge_sort(list1):
"""
Sort the elements of list1.
Return a new sorted list with the same elements as list1.
This function should be recursive.
"""
if len(list1) <= 1:
# base case
sort_list = list(list1)
return sort_list
else:
# recursive case
mid = len(list1) / 2
down_list = merge_sort(list1[ :mid])
up_list = merge_sort(list1[mid :])
return merge(down_list, up_list)
2. *gen_all_strings*
1. Split the input word into two parts: the first character
(first) and the remaining part (rest).
2. Use gen_all_strings to generate all appropriate strings
for rest. Call this list rest_strings.
3. For each string in rest_strings, generate new strings by
inserting the initial character, first, in all possible
positions within the string.
4. Return a list containing the strings in rest_strings
as well as the new strings generated in step 3.
def gen_all_strings(word):
"""
Generate all strings that can be composed from the letters in word
in any order.
Returns a list of all strings that can be formed from the letters
in word.
This function should be recursive.
"""
all_strings = []
if len(word) == 0:
# base case
all_strings.append("")
else:
# recursive case
first = word[0]
rest = word[1 :]
rest_strings = (gen_all_strings(rest))
all_strings.extend(rest_strings)
for string in rest_strings:
if len(string) == 0:
all_strings.append(first)
else:
for idx in range(len(string) + 1):
all_strings.append("".join([string[:idx], first, string[idx:]]))
return all_strings
3. *Word Wrangler*
http://www.codeskulptor.org/#user39_gMEWuD77jcQzxUH_0.py
"""
Student code for Word Wrangler game
"""
import urllib2
import codeskulptor
import poc_wrangler_provided as provided
WORDFILE = "assets_scrabble_words3.txt"
# Functions to manipulate ordered word lists
def remove_duplicates(list1):
"""
Eliminate duplicates in a sorted list.
Returns a new sorted list with the same elements in list1, but
with no duplicates.
This function can be iterative.
"""
unique_list = []
for element in list1:
if len(unique_list) == 0 or unique_list[-1] != element:
unique_list.append(element)
return unique_list
def intersect(list1, list2):
"""
Compute the intersection of two sorted lists.
Returns a new sorted list containing only elements that are in
both list1 and list2.
This function can be iterative.
"""
intersect_list = []
# duplicate the input lists
temp_list1 = list(list1)
temp_list2 = list(list2)
while len(temp_list1) and len(temp_list2):
if temp_list1[0] < temp_list2[0]:
temp_list1.pop(0)
elif temp_list1[0] > temp_list2[0]:
temp_list2.pop(0)
else:
intersect_list.append(temp_list1.pop(0))
intersect_list.append(temp_list2.pop(0))
return remove_duplicates(intersect_list)
# Functions to perform merge sort
def merge(list1, list2):
"""
Merge two sorted lists.
Returns a new sorted list containing all of the elements that
are in either list1 and list2.
This function can be iterative.
"""
merged_list = []
# duplicate the input lists
temp_list1 = list(list1)
temp_list2 = list(list2)
while len(temp_list1) and len(temp_list2):
if temp_list1[0] < temp_list2[0]:
merged_list.append(temp_list1.pop(0))
else:
merged_list.append(temp_list2.pop(0))
if len(temp_list1) == 0:
merged_list.extend(temp_list2)
elif len(temp_list2) == 0:
merged_list.extend(temp_list1)
return merged_list
def merge_sort(list1):
"""
Sort the elements of list1.
Return a new sorted list with the same elements as list1.
This function should be recursive.
"""
if len(list1) <= 1:
# base case
sort_list = list(list1)
return sort_list
else:
# recursive case
mid = len(list1) / 2
down_list = merge_sort(list1[ :mid])
up_list = merge_sort(list1[mid :])
return merge(down_list, up_list)
# Function to generate all strings for the word wrangler game
def gen_all_strings(word):
"""
Generate all strings that can be composed from the letters in word
in any order.
Returns a list of all strings that can be formed from the letters
in word.
This function should be recursive.
"""
all_strings = []
if len(word) == 0:
# base case
all_strings.append("")
else:
# recursive case
first = word[0]
rest = word[1 :]
rest_strings = (gen_all_strings(rest))
all_strings.extend(rest_strings)
for string in rest_strings:
if len(string) == 0:
all_strings.append(first)
else:
for idx in range(len(string) + 1):
all_strings.append("".join([string[:idx], first, string[idx:]]))
return all_strings
# Function to load words from a file
def load_words(filename):
"""
Load word list from the file named filename.
Returns a list of strings.
"""
url = codeskulptor.file2url(filename)
netfile = urllib2.urlopen(url)
lines = []
for line in netfile.readlines():
lines.append(line[:-1])
return lines
def run():
"""
Run game.
"""
words = load_words(WORDFILE)
wrangler = provided.WordWrangler(words, remove_duplicates,
intersect, merge_sort,
gen_all_strings)
provided.run_game(wrangler)
# Uncomment when you are ready to try the game
run()