Instructions

Download hw06.zip. Inside the archive, you will find starter files for the questions in this homework, along with a copy of the OK autograder.

Submission: When you are done, submit with python3 ok --submit. You may submit more than once before the deadline; only the final submission will be scored. Check that you have successfully submitted your code on okpy.org.

Readings: This homework relies on following references:

Recursion

Question 1: Reduce

Write the recursive version of the function reduce which takes

  • reducer - a two-argument function that reduces elements to a single value
  • s - a sequence of values
  • base - the starting value in the reduction. This is usually the identity of the reducer

If you're feeling stuck, think about the parameters of reduce.

from operator import add, mul

def reduce(reducer, seq, base):
    """Reduce a sequence under a two-argument function starting from a base value.

    >>> def add(x, y):
    ...     return x + y
    >>> def mul(x, y):
    ...     return x*y
    >>> reduce(add, [1,2,3,4], 0)
    10
    >>> reduce(mul, [1,2,3,4], 0)
    0
    >>> reduce(mul, [1,2,3,4], 1)
    24
    """
    "*** YOUR CODE HERE ***"
    

Use OK to test your code:

python3 ok -q reduce

Question 2: Remove Last from Sequence

Complete the recursive function remove_last which creates a new list identical to the input list s but with the last element in the sequence that is equal to x removed.

Hint: Remember that you can use negative indexing on lists! For example lst[-1] refers to the last element in a list lst, lst[-2] refers to the second to last element...

def remove_last(x, s):
    """Create a new list that is identical to s but with the last
    element from the list that is equal to x removed.

    >>> remove_last(1,[])
    []
    >>> remove_last(1,[1])
    []
    >>> remove_last(1,[1,1])
    [1]
    >>> remove_last(1,[2,1])
    [2]
    >>> remove_last(1,[3,1,2])
    [3, 2]
    >>> remove_last(1,[3,1,2,1])
    [3, 1, 2]
    >>> remove_last(5, [3, 5, 2, 5, 11])
    [3, 5, 2, 11]
    """
    "*** YOUR CODE HERE ***"

Illustrated here is a more complete doctest that shows good testing methodology. It is a little cumbersome as documentation, but you'll want to think about it for your projects. Test every condition that might come up. Then you won't be surprised when it does.

Use OK to test your code:

python3 ok -q remove_last

Question 3: Binary

A decimal, or base 10, number is a number expressed in the everyday format that we are all used to. We can also express numbers with the binary system, which expresses numbers in powers of 2.

For example, 8 (base 10 number) translates to ‘1000’ (binary number).

1 0 0 0
23 22 21 20

‘1’ or ‘0’ indicates whether the value that it represents is included in the base 10 value. 8 can just be represented with 23, so we represent this with a ‘1’ in that corresponding placement and ‘0’ for other powers of 2.

As another example, 5 would translate to ‘101’.

1 0 1
22 21 20

For numbers that are not powers of 2, like 5, we represent them with several powers of 2. We use 22 and 20 for 5.

Notice that we always start with the power of 0 at the right.

Now that you know how to read binary numbers, let’s try to implement binary. Write the recursive function binary which takes in n, a base 10 number, and returns a list representing the representation of the number in base 2.

You may find the following article helpful in understanding how to convert a number from decimal to binary.

def binary(n):
    """Return a list representing the representation of a number in base 2.

    >>> binary(55055)
    [1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1]
    >>> binary(-136)
    ['-', 1, 0, 0, 0, 1, 0, 0, 0]
    """
    "*** YOUR CODE HERE ***"

Use OK to test your code:

python3 ok -q binary

Question 4: Hailstone

For the hailstone function from previously, you pick a positive integer n as the start. If n is even, divide it by 2. If n is odd, multiply it by 3 and add 1. Repeat this process until n is 1. Write a recursive version of hailstone that prints out the values of the sequence and returns the number of steps.

def hailstone_iterative(n):
    """Print out the hailstone sequence starting at n, and return the
    number of elements in the sequence.

    >>> a = hailstone_iterative(10)
    10
    5
    16
    8
    4
    2
    1
    >>> a
    7
    """
    "*** YOUR CODE HERE ***"

def hailstone_recursive(n):
    """Print out the hailstone sequence starting at n, and return the
    number of elements in the sequence.

    >>> a = hailstone_recursive(10)
    10
    5
    16
    8
    4
    2
    1
    >>> a
    7
    """
    "*** YOUR CODE HERE ***"

Use OK to test your code:

python3 ok -q hailstone_iterative
python3 ok -q hailstone_recursive

Tree Recursion

Question 5: Count Change

A set of coins makes change for n if the sum of the values of the coins is n. For example, if you have 1-cent, 2-cent and 4-cent coins, the following sets make change for 7:

  • 7 1-cent coins
  • 5 1-cent, 1 2-cent coins
  • 3 1-cent, 2 2-cent coins
  • 3 1-cent, 1 4-cent coins
  • 1 1-cent, 3 2-cent coins
  • 1 1-cent, 1 2-cent, 1 4-cent coins

Thus, there are 6 ways to make change for 7. Write a function count_change that takes a positive integer n and a list of the coin denominations and returns the number of ways to make change for n using these coins (Hint: You will need to use tree recursion):

def count_change(amount, denominations):
    """Returns the number of ways to make change for amount.

    >>> denominations = [50, 25, 10, 5, 1]
    >>> count_change(7, denominations)
    2
    >>> count_change(100, denominations)
    292
    >>> denominations = [16, 8, 4, 2, 1]
    >>> count_change(7, denominations)
    6
    >>> count_change(10, denominations)
    14
    >>> count_change(20, denominations)
    60
    """
    "*** YOUR CODE HERE ***"

Use OK to test your code:

python3 ok -q count_change

Submit

Make sure to submit this assignment by running:

python3 ok --submit