CS 111: Introduction to Computer Science

Exam. Due 8:30AM Friday, May 29, 2009.

This is an exam. You may not speak with anybody other than Jeff Ondich about its contents. You may, however, use your book, your notes, the books in the library, the Internet, and divine guidance (should any be offered to you). If you obtain information from some source other than your own brain, cite your source and use quotation marks where appropriate.

Hand your exam in on paper.

  1. (8 points) Some questions about numbers.

    1. What is the base ten equivalent of the binary integer 110111?
    2. What is the binary equivalent of the base ten integer 92?
    3. What is the hexadecimal equivalent of the base ten integer 92?
    4. What base ten integer is represented by the 8-bit two's complement integer 10101101?
    5. What is the 8-bit two's complement equivalent of the base ten integer -92?
  2. (8 points) Sections 11.6.1 through 11.6.3 of your textbook include a discussion of an important Python structure called a dictionary. Your job for this problem is to read about dictionaries, and then write a Python program that does the following:

    • Asks the user for a file name.
    • Opens the file.
    • Reads the file one character at a time, keeping track of how many times each character appears in the file. (This part uses a dictionary.)
    • Closes the file.
    • Prints the characters in descending order of the number of times they appeared in the file.

    This program is very similar to the one described in section 11.6.3, so you should use that section as a starting point for your program. Note that the program I am asking you to write should be simpler than the one in 11.6.3, since reading a single character from a file is easier than reading a single word.

    Hand in a copy of your program on paper, but also hand it in electronically in the usual way. Please call it dictionary.py.

  3. (6 points) Consider the following recursive function.

    def doSomething(s):
            ''' Expects s to be a string. '''
            if len(s) == 0:
                return ''
    
            t = doSomething(s[1:]) + s[0]
            return t
    1. Explain this function's purpose.
    2. Suppose I write a program that calls doSomething('moose'). Including this first call of the function, how many times does doSomething get called, and with what parameter each time? Give your answer by listing the calls of doSomething, including each call's parameter, in the order in which the calls occur.
  4. (8 points) I have a list of integers, and I want to know the distance between the two integers that are furthest apart. For example, if the list is [3, 5, -1, 8, 10, 6], then the distance I'm looking for is 11 (i.e. the distance between 10 and -1). Elmo suggests the following code, which does the job:

    
        def elmo(theList):
            N = len(theList)
            biggestDistance = 0
            for k in range(N):
                for j in range(N):
                    if theList[j] - theList[k] > biggestDistance:
                        biggestDistance = theList[j] - theList[k]
    
            return biggestDistance
        
    • When I used Elmo's code on an array of 10000 integers on my slow old computer at home, it took 7.0 seconds (I tried it several times--7.0 seconds every time). Approximately how long will Elmo's code take to run if N is 40000 (assuming I use the same computer)? Justify your answer. (It is not sufficient to tell me that you ran the code yourself and it took a certain amount of time. I want you to explain why it will take as long as you say it will.)
    • Zoe says she thinks Elmo's code is silly. Describe an algorithm that will run significantly faster than Elmo's, and explain why it's faster.
  5. (3 points) I have mentioned Alan Turing in passing a couple times during class. Since modern educated people ought to know who this guy is, please take a few minutes to look him up, and write down three things he is known for.
  6. (2 free points) I have grown bored with my on-line reading habits. Could you recommend some daily reading that you find interesting?

  7. (12 points) In this problem, you will use sorter.py to compare the performance of selection sort, Insertion Sort, and Merge Sort.

    As we discussed in class, selection sort, insertion sort, and mergesort are all members of a class of sorting algorithms whose performance is usually measured by counting the number of list element comparisons that need to be done to complete the sorting of the list. That is, we count the number of times something like "a[j] < a[k]" gets executed during the run of the algorithm. It would take several pages to provide a reasonably rigorous argument that the comparison count is a good measure of performance for these algorithms. With a lot less rigor, we can say something like this: by counting comparisons, we are counting the number of iterations of the inner loop, and by counting inner loop iterations, we are counting the most time-consuming portion of the algorithm.

    To see how this plays out, try running "python sorter.py bubble 10 verbose" or "python sorter.py bubble 1000" to see a report of the sorting times and number of comparisons for a 10-element list or a 1000-element list. (The "verbose" causes the program to print out the list before and after sorting, to help you believe that sorting is actually taking place.) To try this with the other algorithms, replace "bubble" with "merge", "selection", or "insertion".

    In what follows, you're going to count comparisons and measure running times for the three algorithms and several values of N. Let's get started.

    • Fill in the following chart.

      N Comp. count for Sel. Sort Running time for Sel. Sort Comp. count for Ins. Sort Running time for Ins. Sort Comp. count for Merge Sort Running time for Merge Sort
      5000
      10000
      15000
      20000

    • Describe any patterns you see in the data you collected to fill in the chart above.
    • Is the comparison count for selection sort dependent on the initial data? (For example, if you run selection sort several different times on different randomly generated arrays of 10000 items, is the comparison count the same every time?) How about insertion sort? mergesort?
    • If you don't shuffle the data before sorting, how are the comparison counts for the three sorts affected?
    • Under what conditions would you choose to use mergesort instead of insertion sort and selection sort? When would you choose insertion sort? When would you choose selection sort? (You may feel that the answer to one or more of these questions is "never"--if so, then say so.)