CMU 15-112 Spring 2018: Fundamentals of Programming and Computer Science
Colab 10 (Due Thursday 29-Mar, at 10pm)



  1. evalPrefixNotation(lst) [30 pts]
    Background: in so-called 'prefix notation', an arithmetic expression is listed with the operator first. So instead of writing '2 + 3' we would write '+ 2 3'. Actually, for this problem, we'll represent the expression in a list, so we'd write ['+', 2, 3]. Each value can itself be another full expression, so for example we could have:
    ['+', 2, '*', 3, 4]
    This would be the same as (2 + (3 * 4)), or 14. Again, we could have:
    ['+', '*', 2, 3, '*', 4, 5]
    This would be the same as ((2 * 3) + (4 * 5)), or 26. You can visualize this as a hierarchical structure, where each operator must be followed by two values on the next column:
    +
        *
            2
            3
        *
            4
            5
    
    These expressions can become fairly complex; consider:
    ['*', '+', 2, '*', 3, '-', 8, 7, '+', '*', 2, 2, 5]
    This is the expression (2 + (3 * (8 - 7))) * ((2 * 2) + 5), which is equal to 45.

    With this in mind, write the function evalPrefixNotation(lst) that takes a list lst that contains a legal arithmetic expression in prefix notation, as just described, and returns the value that the expression evaluates to. Your function only needs to work for '+', '-', and '*'.

    Hint: this problem becomes drastically easier to solve if you implement it destructively. Our sample solution used lst.pop(0) to get the first element, for example. Evaluating the operands then becomes much simpler.

  2. findLargestFile(path) [30 pts]
    Without using os.walk, write the recursive function findLargestFile(path), which takes a string path to a folder and returns the full path to the largest file in the folder (and all its subfolders). You can compute the size of a file using os.path.getsize(path). If there are no files, the empty string ("") is returned. You do not need to handle the case where the supplied path is not valid or is not a folder, and you may handle ties however you wish.

    Note that file systems can be very large, so in this problem, efficiency is important! Therefore, you may not use listFiles to gather all the files into one place, and you should avoid calling os.path.getsize on a single file more than once.

    To help test your code, here are some assertions for use with sampleFiles (available in colab10_sampleFiles.zip):

    assert(findLargestFile("sampleFiles/folderA") == "sampleFiles/folderA/folderC/giftwrap.txt") assert(findLargestFile("sampleFiles/folderB") == "sampleFiles/folderB/folderH/driving.txt") assert(findLargestFile("sampleFiles/folderB/folderF") == "")

    Hint: You will almost certainly want to use a wrapper function or an optional parameter to make the problem easier to solve. This will make it easier to pass file size information back along with file names...

  3. solveSudoku(board) [40 pts]
    Write the function solveSudoku(board) that takes a partially-completed Sudoku board (a 2d list with 0's representing empty cells), and returns a solved version of the same puzzle, or None if no such solution exists. You will want to make use of the code you wrote in colab5. If you never completed that code, you should meet with a TA as soon as possible to help you get that code working.

    Here is a very simple testing function to help get you started. You will need to test more than this. We certainly will...

    def testSolveSudoku(): print('Testing solveSudoku()...', end='') board = [ [ 5, 3, 0, 0, 7, 0, 0, 0, 0 ], [ 6, 0, 0, 1, 9, 5, 0, 0, 0 ], [ 0, 9, 8, 0, 0, 0, 0, 6, 0 ], [ 8, 0, 0, 0, 6, 0, 0, 0, 3 ], [ 4, 0, 0, 8, 0, 3, 0, 0, 1 ], [ 7, 0, 0, 0, 2, 0, 0, 0, 6 ], [ 0, 6, 0, 0, 0, 0, 2, 8, 0 ], [ 0, 0, 0, 4, 1, 9, 0, 0, 5 ], [ 0, 0, 0, 0, 8, 0, 0, 7, 9 ] ] solved = solveSudoku(board) solution = [ [5, 3, 4, 6, 7, 8, 9, 1, 2], [6, 7, 2, 1, 9, 5, 3, 4, 8], [1, 9, 8, 3, 4, 2, 5, 6, 7], [8, 5, 9, 7, 6, 1, 4, 2, 3], [4, 2, 6, 8, 5, 3, 7, 9, 1], [7, 1, 3, 9, 2, 4, 8, 5, 6], [9, 6, 1, 5, 3, 7, 2, 8, 4], [2, 8, 7, 4, 1, 9, 6, 3, 5], [3, 4, 5, 2, 8, 6, 1, 7, 9] ] assert(solved == solution) print('Passed!')

    Notes/Hints:
    • To receive any credit for this problem, you must solve it recursively, even if you could dream up a non-recursive solution!
    • This is a backtracking problem. Study the backtracking template and backtracking examples; they will help.
    • Make sure to return None as soon as you determine that a step has no solutions! Otherwise, the code might take a very long time to run.