HW_SOURCE_FILE = 'hw03.py' ############# # Questions # ############# # Q1 def g(n): """Return the value of G(n), computed recursively. >>> g(1) 1 >>> g(2) 2 >>> g(3) 3 >>> g(4) 10 >>> g(5) 22 >>> from construct_check import check >>> check(HW_SOURCE_FILE, 'g', ['While', 'For']) True """ "*** YOUR CODE HERE ***" def g_iter(n): """Return the value of G(n), computed iteratively. >>> g_iter(1) 1 >>> g_iter(2) 2 >>> g_iter(3) 3 >>> g_iter(4) 10 >>> g_iter(5) 22 >>> from construct_check import check >>> check(HW_SOURCE_FILE, 'g_iter', ['Recursion']) True """ "*** YOUR CODE HERE ***" # Q2 def pingpong(n): """Return the nth element of the ping-pong sequence. >>> pingpong(7) 7 >>> pingpong(8) 6 >>> pingpong(15) 1 >>> pingpong(21) -1 >>> pingpong(22) 0 >>> pingpong(30) 6 >>> pingpong(68) 2 >>> pingpong(69) 1 >>> pingpong(70) 0 >>> pingpong(71) 1 >>> pingpong(72) 0 >>> pingpong(100) 2 >>> from construct_check import check >>> check(HW_SOURCE_FILE, 'pingpong', ['Assign', 'AugAssign']) True """ "*** YOUR CODE HERE ***" def has_seven(k): """Returns True if at least one of the digits of k is a 7, False otherwise. >>> has_seven(3) False >>> has_seven(7) True >>> has_seven(2734) True >>> has_seven(2634) False >>> has_seven(734) True >>> has_seven(7777) True """ if k % 10 == 7: return True elif k < 10: return False else: return has_seven(k // 10) # Q3 def count_change(amount): """Return the number of ways to make change for amount. >>> count_change(7) 6 >>> count_change(10) 14 >>> count_change(20) 60 >>> count_change(100) 9828 >>> from construct_check import check >>> check(HW_SOURCE_FILE, 'count_change', ['While', 'For']) True """ "*** YOUR CODE HERE ***" # Q4 def print_move(origin, destination): """Print instructions to move a disk.""" print("Move the top disk from rod", origin, "to rod", destination) def move_stack(n, start, end): """Print the moves required to move n disks on the start pole to the end pole without violating the rules of Towers of Hanoi. n -- number of disks start -- a pole position, either 1, 2, or 3 end -- a pole position, either 1, 2, or 3 There are exactly three poles, and start and end must be different. Assume that the start pole has at least n disks of increasing size, and the end pole is either empty or has a top disk larger than the top n start disks. >>> move_stack(1, 1, 3) Move the top disk from rod 1 to rod 3 >>> move_stack(2, 1, 3) Move the top disk from rod 1 to rod 2 Move the top disk from rod 1 to rod 3 Move the top disk from rod 2 to rod 3 >>> move_stack(3, 1, 3) Move the top disk from rod 1 to rod 3 Move the top disk from rod 1 to rod 2 Move the top disk from rod 3 to rod 2 Move the top disk from rod 1 to rod 3 Move the top disk from rod 2 to rod 1 Move the top disk from rod 2 to rod 3 Move the top disk from rod 1 to rod 3 """ assert 1 <= start <= 3 and 1 <= end <= 3 and start != end, "Bad start/end" "*** YOUR CODE HERE ***" # Q5 def replace_leaf(t, old, new): """Returns a new tree where every leaf value equal to old has been replaced with new. >>> yggdrasil = tree('odin', ... [tree('balder', ... [tree('thor'), ... tree('loki')]), ... tree('frigg', ... [tree('thor')]), ... tree('thor', ... [tree('sif'), ... tree('thor')]), ... tree('thor')]) >>> laerad = copy_tree(yggdrasil) # copy yggdrasil for testing purposes >>> print_tree(replace_leaf(yggdrasil, 'thor', 'freya')) odin balder freya loki frigg freya thor sif freya freya >>> laerad == yggdrasil # Make sure original tree is unmodified True """ "*** YOUR CODE HERE ***" # Tree ADT def tree(label, branches=[]): """Construct a tree with the given label value and a list of branches.""" for branch in branches: assert is_tree(branch), 'branches must be trees' return [label] + list(branches) def label(tree): """Return the label value of a tree.""" return tree[0] def branches(tree): """Return the list of branches of the given tree.""" return tree[1:] def is_tree(tree): """Returns True if the given tree is a tree, and False otherwise.""" if type(tree) != list or len(tree) < 1: return False for branch in branches(tree): if not is_tree(branch): return False return True def is_leaf(tree): """Returns True if the given tree's list of branches is empty, and False otherwise. """ return not branches(tree) def print_tree(t, indent=0): """Print a representation of this tree in which each node is indented by two spaces times its depth from the root. >>> print_tree(tree(1)) 1 >>> print_tree(tree(1, [tree(2)])) 1 2 >>> numbers = tree(1, [tree(2), tree(3, [tree(4), tree(5)]), tree(6, [tree(7)])]) >>> print_tree(numbers) 1 2 3 4 5 6 7 """ print(' ' * indent + str(label(t))) for b in branches(t): print_tree(b, indent + 1) def copy_tree(t): """Returns a copy of t. Only for testing purposes. >>> t = tree(5) >>> copy = copy_tree(t) >>> t = tree(6) >>> print_tree(copy) 5 """ return tree(label(t), [copy_tree(b) for b in branches(t)]) ################### # Extra Questions # ################### # Q6 quine = """ "*** YOUR CODE HERE ***" """ # Q7 def zero(f): return lambda x: x def successor(n): return lambda f: lambda x: f(n(f)(x)) def one(f): """Church numeral 1: same as successor(zero)""" "*** YOUR CODE HERE ***" def two(f): """Church numeral 2: same as successor(successor(zero))""" "*** YOUR CODE HERE ***" three = successor(two) def church_to_int(n): """Convert the Church numeral n to a Python integer. >>> church_to_int(zero) 0 >>> church_to_int(one) 1 >>> church_to_int(two) 2 >>> church_to_int(three) 3 """ "*** YOUR CODE HERE ***" def add_church(m, n): """Return the Church numeral for m + n, for Church numerals m and n. >>> church_to_int(add_church(two, three)) 5 """ "*** YOUR CODE HERE ***" def mul_church(m, n): """Return the Church numeral for m * n, for Church numerals m and n. >>> four = successor(three) >>> church_to_int(mul_church(two, three)) 6 >>> church_to_int(mul_church(three, four)) 12 """ "*** YOUR CODE HERE ***" def pow_church(m, n): """Return the Church numeral m ** n, for Church numerals m and n. >>> church_to_int(pow_church(two, three)) 8 >>> church_to_int(pow_church(three, two)) 9 """ "*** YOUR CODE HERE ***"