Homework 10 (Due Sat 12-Nov at 8pm)

Important Notes:
  1. Read the "Important Notes" at the top of hw1. The same general rules apply to this hw regarding solo, sample solution videos, etc.
  2. This homework is solo. You must not collaborate with anyone (besides current course TAs and faculty) in any way. See the syllabus for more details.
  3. The same rules about recursion from hw9 apply to this hw, with one exception: unlike last hw, in this hw you can use for loops or while loops, as long as you also use recursion meaningfully in each problem.
  4. You will need these starter files:
  5. For this hw, you may submit to Autolab up to 5 times, but only your last submission counts.
  6. Do not hardcode the test cases in your solutions.

  1. Tree class [20 pts]
  2. createFullTree(height, numChildren, valueForAllNodes) [10 pts]
  3. GameTree class [10 pts]
  4. NimGameTree class [10 pts]
  5. knightsTour(rows, cols) # with backtracking [50 pts]

  1. Tree class
  2. [20 pts] [autograded]

    In this assignment, we will be representing trees (as discussed in recitation last week) using object-oriented programming. We'll start with implementing a Tree class. Each instance of the Tree class will store:
    A instance of Tree that has no children (and empty list of children) is called a leaf.

    Example tree
    Once we implement this Tree class, we'll be able to build the above example tree. We could do this by either A) starting from the bottom (the leaves) and assembling up or B) starting at the top node and building down. See both examples below.

    Example tree construction, bottom-up


    Example tree construction, top-down

    Implement a Tree class with the following methods:


    Example tree 1         Example tree 1

  3. createFullTree(height, numChildren, valueForAllNodes)
  4. [10 pts] [autograded]

    Implement the recursive function createFullTree(height, numChildren, valueForAllNodes) that recursively creates and returns a new Tree instance with height equal to height. Other than the leaf nodes at the bottom of the tree, each sub-tree in this "full" tree will have numChildren children. Every node, from the top node to the leaves, will have the same value, valueForAllNodes. If either height or numChildren equals zero, the function will return a Tree instance with a single node that has no children.

  5. GameTree class
  6. [10 pts] [autograded]

    Implement a GameTree class that inherits from the Tree class and adds the following methods:

  7. NimGameTree class
  8. [10 pts] [autograded]

    This NimGameTree class represents a game tree containing all of the possible results from playing a simple variant of the game Nim. In our Nim variant, there is a single pile of sticks from which two players take turns taking either one or two sticks. The player that takes the last set of sticks wins.

    Implement a NimGameTree class that inherits from the GameTree class and has the following constructor method:
    For example, given tree = NimGameTree(3, True), calling print(tree) will print:
    3, myTurn=True
    **2, myTurn=False
    ****1, myTurn=True
    ******0, myTurn=False
    ****0, myTurn=True
    **1, myTurn=False
    ****0, myTurn=True
    
    

  9. knightsTour(rows, cols) # with backtracking
  10. [50 pts] [autograded]

    First, read about the Knight's Tour problem here. Next, write the function knightsTour(rows, cols) that takes a non-negative int n and returns a 2d list of a knight's tour on a rows-by-cols board, or None if this does not exist. This is a slight generalization since here we will allow non-square rectangular boards.

    Following these instructions, knightsTour(4, 5) should return a legal 4x5 knight's tour, such as this one:
    [
     [ 1, 14,  5, 18,  7], 
     [10, 19,  8, 13,  4],
     [15,  2, 11,  6, 17],
     [20,  9, 16,  3, 12]
    ]
    
    Here we see that the tour started at 1, which is at the top-left corner. Then following the sequence 1,2,3,... to follow each move in order.

    Note that it is possible for some dimensions that there is a legal knight's tour, only not one starting at the top-left corner. You will have to account for that in your solution.

    Also: backtracking can be slow, and your solution will probably not run fast enough after 6-by-6 or so. That's ok. :-)

    Hint: if your solution is "correct" but takes a long time to run, you may be able to speed it up by placing the 1st number before calling your backtracker. Most but not all boards we will consider have a solution with 1 in the top-left corner. So you can just use the usual nested for loops to place the 1 in every possible location, but first at (0,0), and then backtracking from there. That may well speed things up a bit.

    Optional extra challenge: speed this up even more! There are techniques that can make this work fast enough for somewhat larger boards (though they still bog down eventually). You can do some pondering of your own, or some internet sleuthing, but in any case, try to make this run faster. Or not, since it is optional.

    In any case, have fun!