CSC 161 Grinnell College Spring, 2015
 
Imperative Problem Solving and Data Structures
 
 

Supplemental Problems

Problems on this page are under revision; started problems (*) are likely to change before the semester begins. Do not rely upon this page until classes start in January!

Supplemental Problems extend the range of problems considered in the course and help sharpen problem-solving skills. To support this objective, all Supplemental Problems are to be done individually.

Problems numbered 6 or higher may be turned in for extra credit.

Quick links: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15

Submission Details

Use the link, Detailed Coursework Instructions, to find specific instructions regarding code, submission, and testing of supplemental problems.

Some Grading Notes:


  1. Grocery-Gas Loyalty Program

    Several grocery stores have programs that encourage customer loyalty. In one common approach, a customer has a card from the grocery store that keeps track of the amount the customer has spent at the store in the last two weeks. Based upon the total expenditure, the customer is entitled to a discount at a cooperating gas station. The following table shows a hypothetical type of discount policy that represents a composite of several store programs:

    Amount Spent
    at Grocery Store
    Discount per Gallon on Gas Maximum Number of Gallons
    at Discounted Price
    $0.00 — $39.99 no discount no discount
    $40.00 — $79.99 2 cents per gallon up to 15 gallons
    $80.00 — $99.99 2 cents per gallon no limit on gallons
    $100.00 — $129.99 5 cents per gallon up to $1.50 discount
    $130.00 — $149.99 5 cents per gallon no limit on gallons
    $150.00 — $174.99 9 cents per gallon up to 17 gallons
    $175.00 or more 12 cents per gallon no limit on gallons

    Write a program that begins with initialized variables for the two-week total for grocery purchases, a price per gallon for gas (before any discount), and the number of gallons purchased. The program should print:

    • the initial data (grocery purchases, gasoline price per gallon, and number of gallons purchases)
    • the total cost for the gasoline, before discount,
    • he actual discount received (covering all gallons, not the actual price per gallon), and
    • the total price paid actually paid for the gas.

    Grading Forms

  1. Interest in a Savings Account

    A simple savings account earns compound interest over time, based upon an annual interest rate (e.g., 1% or 9%) per year. The basic computations proceed as follows:

    • A monthly interest rate is computed:
      monthlyRate = annRate / 1200.0;
      
    • The monthly rate determines the interest the bank adds to the account each month, according to the formula:
      interest = monthlyRate * (old balance)
      new balance = (old balance) + interest
      

    For example, at an annual rate of 8%, the monthly rate is 0.00666667. With a starting balance of $100, the computations proceed as follows for the first year:

           Starting   Monthly   Ending
    Month   Balance   Interest  Balance
      0      ------     ----     100.00
      1      100.00     0.67     100.67
      2      100.67     0.67     101.34
      3      101.34     0.68     102.01
      4      102.01     0.68     102.69
      5      102.69     0.68     103.38
      6      103.38     0.69     104.07
      7      104.07     0.69     104.76
      8      104.76     0.70     105.46
      9      105.46     0.70     106.16
     10      106.16     0.71     106.87
     11      106.87     0.71     107.58
     12      107.58     0.72     108.30
    

    This problem asks to you

    • write a procedure computeUntilDouble that computes monthly balance until the amount in the account doubles from the initial balance.
    • write a program that uses computeUntilDouble in several ways.

    The following notes provide additional information regarding this work.

    • procedure computeUntilDouble

      • The procedure should have the following signature:
        void computeUntilDouble (double initial_balance, double annual_rate,
                                 char print_option, int * months_to_double)
        
        • initial_balance gives the initial balance, before any interest has accrued.
        • annual_rate gives the annual percentage interest rate
        • print_option specifies one of three alternatives:
          • 'n': no printing is to be done by the procedure
          • 'm': the status of the account (i.e., month number, starting balance, interest for that month, and ending balance) is printed every month.
          • 'y': the status of the account (i.e., month number, starting balance, interest for that month, and ending balance) is printed every year (i.e., every 12 months).
      • months_to_double refers to an integer variable in the main program, and the number of months required for the account balance to double is stored in this variable when the procedure concludes.
      • Processing in computeUntilDouble continues until the balance in the account doubles from its original value.
      • Regardless of what printing option is selected, computeUntilDouble may have only one loop. Within the loop, the print_option should be consulted to determine whether or not to print the account balance for that loop iteration.
    • The program should compute and print the following:

      • An initial table should be printed, giving a monthly status report for an account that starts with $100 at an 8% annual percentage rate. (That is, the first part of this table should agree exactly with the sample table given above — although spaces on a line may be inserted or deleted.)
      • A second table should be printed, giving an annual status report for an account that starts with $300 at a 2% annual percentage rate.
      • Starting with $100.00 in an account, the program should print a table giving the number of months for the account to double with annual interest rates of 1%, 2%, 3%, ..., 9%.

    Grading Forms

  1. Unsharp Mask

    This problem largely represents a revision, by Jerod Weinman, of an earlier draft written by Henry M. Walker. Henry M. Walker added modest additional editing.

    In CSC 151, you created a variety of interesting image transformations, but all of them were limited to the information at a single pixel. In this assignment we examine a category of image processing operations that use a small neighborhood surrounding a pixel. In particular, we will use the so-called "unsharp mask" technique, which adds a fraction of the difference between a blurred version of the image and the original back to an image in order to further enhance the places that change most when blurred (i.e., image details).

    Original
                                                         Image Blurred
                                                        Image Sharpened
                                                      Image
    Original Image Blurred Image Sharpened Image

    Sharpening an image with the blurred version (the unsharp mask) might proceed with the following basic steps

    for each channel in R, G, B
        data ← getChannel(image, channel)
        avg ← calculateWindowAverage(data)
        diff ← data - avg
        data ← data  +  factor * diff
        setChannel(image, data, channel)
    

    where data, avg, and diff are all two dimensional arrays representing the appropriate quantities. The arithmetic operations shown (e.g., - and +) must be applied to corresponding locations in these arrays.

    Note that while values in avg must necessarily stay within the unsigned char range required by images, diff could have both positive or negative values, which means we need to process these intermediate steps outside the Picture data type. It's also possible that the changes to data could take it outside the valid 0…255 range. Thus, we must clip the results before returning them to a Picture.

    To sharpen, factor should be positive, but is typically in the range of 0.5-1.5. (You can experiment to determine a value you find appealing.)

    How should one calculate a window average? Each point in the result should be the average of the pixels from the original data from around a 3 by 3 grid around that position. That is, for a given row r and column c, compute the average among the values in positions

    [c-1, r-1] [c, r-1] [c+1, r-1]
    [c-1, r] [c, r] [c+1, r]
    [c-1, r+1] [c, r+1] [c+1, r+1]

    When any of these row/column positions falls outside the image (i.e., above the top, to the left or right, below the bottom), ignore that position in computing the average.

    Details

    Write a program that takes a picture from the Scribbler 2's camera and sharpens it using this technique. That is, the program should do the following:

    • Take a picture from the Scribbler 2's camera and display it.
    • Use the original picture to obtain and display an averaged image.
    • Use these two images to obtain and display a sharpened image.

    Programming Notes

    • Each step in the pseudocode algorithm shown in the introduction should be done by a separate function that takes and/or modifies appropriate parameters.
    • The program may contain no global variables.
    • Your averaging procedure may be easier to read and understand (not to mention more general) if you use loops to cover the region, rather than explicitly enumerating the neighbors.

    Grading Forms

    1. Library Book Borrowing

      A public library allows residents to check out up to five books at a time. Assuming the town is small, everyone is known by name, so only a person's name, the number of books, and the due date are stored. (No need to keep track of addresses or telephone numbers — that information is well known throughout the town.) In support of this application, we will store the relevant data on a singly-linked list using node declarations:

           #define maxStrLen 100
           #define maxBooks 5
           struct item {
               char name [maxNameLen];
               int numBooks;
               char booksBorrowed [maxBooks] [maxStrLen];
               char dueDate [basStrLen];
               struct item * next;
               }
      

      To make processing easy (at least for this problem), a resident checks out one to five books with a common due date. Further checkouts are not allowed, until all previous books are returned. Residents can inquire about what books they have checked out at anhy time.

      Initial processing notes:

      • The main menu for working with residents and checked out books is as follows:

        Library checkout  options:
           c:  check out 1-5 books (but only if resident has no books currently checked out)
           p:  print all residents with checked out books
           s:  search the checkout list for a given resident, 
                  printing the resident's name, books checked out (if any), and due date
           r:  return a book, given resident's name and book title
           q:  quit
        
      • When a resident checks out books, the titles are stored as rows in the booksBorrowed array. For convenience in printing, the titles are all in the first rows of the table. If the resident has not borrowed the maximum of five books, the last rows are left blank.

      • When a resident wants to check out books (option c), the list is searched. If the resident has no books outstanding, a new node is created for the resident. For efficient insertion, this node should be added at the front of the linked list. (For example, one might use the approach of Scheme-like lists.)

      • Printing (option p) should display resident names with checked out books, the books they have borrowed, and the common due date. The resident's records may appear in any order. However, printing should not change the list itself.

      • Some residents inquire often about their checked-out books, and some residents ask rarely. Thus, in improve efficiency for curious residents, whenever a search for a resident (option s) is performed, the resident's record is moved one node closer to the front of the list. (Assuming the resident has checkout books to find. If the resident's name is already first, the list is not changed.) This movement of nodes will help ensure that commonly accessed nodes stay near the front of the list.

      • When a book is returned (option r), the book title is removed from the resident's record in the node.

        • If other books remain checked out, the book titles are moved down in the two-domensional array. so they are all together as the first rows of the table.
        • If no other books remain checked out, the resident's record is removed from the list.
      • Each menu option for this problem (except quit) should be performed by a separate function. (Helper functions are allowed. As long as the main program calls a function for each menu option, processing may be organized in whatever way seems appropriate.

      • Global variables may not be used in this problem. (Each declaration of a global variable will yield a 15 point penalty, so the use of two global variables guarantees 0 points for this problem.)

      Grading Forms

    1. Scrabble with Undo and Redo Button

      The game of Scrabble is a word game, in which players place letters on a grid to form words. After the first word is placed on the board, subsequent words must intersect one or more existing words. In the game, letters from a player are connected to letters already on the board to form words. Many descriptions of the game are available online, including a reasonably thorough discussion on Wikipedia.

      This problem a basic software program for recording and displaying player moves involving the addition of a word to the board, where a new word will intersect with an existing word. For example, consider the following grid:

      
              P R O G R A M 
        M E M O R Y
            N E T W O R K 
        S Y S T E M                   E
              S T R I N G     A N T I Q U E
                      O       L       U
                    C O L L E G E     A
          T P       A D       E       T S
          H H       L L       B       I C
          E Y       C E       R       O H I O
          O S       U         A       N E
        G R I N N E L L                 M
          Y C       U                   E
            S       S
      

      This grid contains numerous words arranged horizontally or vertically, and each word is connected to one or more other words at various letters. When inserting a word, it is not required that every letter of the new word must form a word with every adjacent letter. For example, the words PROGRAM, MEMORY, NETWORK, SYSTEM and STRING at the top left are positioned along the vertical word POETS. Reading down in the next column from POETS, one gets the sequence RRTET; this is not a word, but that is irrelevant to the rules for this problem.

      Within this context, a first word may be placed anywhere on the grid. Thereafter adding a new word requires that the word connect with at least one existing letter already on the grid. If the new word would extend over several existing letters, then the corresponding letters must match. For example, in the illustration, the word RARE could be added vertically using the R in PROGRAM and the R in NETWORK. However, the word RAKE could not be added in this position. The first R would fit with the R of PROGRAM, but the K in RAKE does not match the grid element already on the grid (the R in NETWORK).

      This problem asks you to support four operations for a simple game of scrabble; a fifth operation, redo, is optional for extra credit.

      Menu options:
         i:  initialize the board
         a:  add a new word to the board
         u:  undo the previous word addition(s)
         r:  redo the previous undo operation
         q: quit
      

      Operation Notes:

      • Option i: initialize the board, so that all squares are blank. As part of this operation, all record of any past moves is erased.
      • Option a: The user is asked for a string, a starting square (row and column numbers), and an orientation (horizontal or vertical).
        • If this is the first string on the board, the program checks that the string fits on the board from the designated starting point.
          • If so, the string is placed on the board, and the move is remembered.
          • If not, the add command is ignored, and the board remains blank.
        • If this is not the first string on the board, the program checks that the string fits on the board and overlaps with one or more existing words and does not conflict with any other existing words.
          • If so, the string is placed on the board, and the move is remembered.
          • If not, this add command is canceled, and the previous history of commands remains the same.
      • Option u: The board is updated to remove the word most recently added, if any. If the option is chosen several times, multiple words from the most recent add commands are removed.
      • Option r: (optional, for extra credit) The previous undo operation, if any, is canceled, so the word removed by "undo" is added again. That is, the redo command cancels exactly one undo operation. Multiple redo commands cancel the corresponding undo operations. If an add command has inserted a word onto the board after the most recent undo command, then the redo command is ignored.
      • Option q: all processing is completed, and the game is over.

      After each operation (except quit), the program should print the current layout of the board.

      Programming Notes:

      • Implementing an undo operation requires keeping track of the past letters placed on the board and where they were placed. Implementing several undo operations means that each add operation must be recorded, with access to the most recent add first. This last in-first out represents the standard method of storage for a stack. In this case, an item on the stack will be the letters actually placed on the board (likely ignoring letters already there), the starting location, and the word orientation (e.g., horizontal or vertical).

      • An undo operation requires popping the top element the stack and removing the relevant characters from the board. However, the undone action should not forgotten, as this information could be needed for a redo operation. Further undo actions would also need to be stored for a potential redo. In every case, it is always the most recent undone action we would want to redo, which suggests we should store these undone actions in their own redo stack.

        Thus, a redo action would pop an element from the redo stack, replay the action, and push it onto the undo stack (as with a normal play). Further redo actions would repeat this process.

        In this way, a user could conceivably navigate pushing the same items back and forth between the undo and redo stacks in a manner functionally equivalent to navigating forward and backward through a linear history of the board states.

        However, an add after undo or redo operations must reset the forward history of the board. Put another way, an add after an undo or redo should empty the redo stack, while undo operations could still go further backward

      • Your program must use a self-contained list-based stack library package, such as developed in the lab on stacks. You should include a Makefile for building all elements of your program (which will require at least two .c files and one .h file).

      Grading Forms


    Any of the following problems may be done for extra credit. As noted in the course syllabus, however, a student's overall problems' average may not exceed 120%.

    1. Computing nth Roots

      Basic Algorithm: The Bisection Method

      Suppose we are given a continuous function f, and we want to approximate a value r where f(r)=0. While this can be a difficult problem in general, suppose that we can guess two points a and b (perhaps from a graph) where f(a) and f(b) have opposite signs. The four possible cases are shown below:

      four cases for the bisection method

      We are given a and b for which f(a) and f(b) have opposite signs. Thus, we can infer that a root r must lie in the interval [a, b]. In one step, we can cut this interval in half as follows. If f(a) and f(m) have opposite signs, then r must lie in the interval [a, m]; otherwise, r must lie in the interval [m, b].

      Applying the Bisection Method to f(x) = xn - r

      As a special case for the Bisection Method, consider the function f(x) = xn - r, where n is a positive integer and r is a positive real number. A root of this function occurs when r = xn, or r is the nth root of r.

      Write a program that inputs a positive integer n, a positive real number r, and a positive real number acc and uses the bisection method to compute the nth root of r.

      Programming Notes:

      • The only arithmetic operations allowed in this program are addition (+), subtraction (-), multiplication (*), and division (/). Use of any other operations or library functions will result in an immediate -10 on this problem (that's right, your score on supplemental problems will be reduced by 10 points, for taking up time without making progress on the problem.) For example, use of C's power function pow in the math library would yield negative points for this problem.
      • Your program should use the bisection method with the function f(x) = xn - r.
      • Computations should continue until the size of the interval is less that acc, the accuracy desired for the answer.
      • Once the loop stops,
        • if an interval endpoint happens to be a root of the function, return that endpoint as the answer.
        • otherwise, use the midpoint of the interval as final approximation to the desired nth root.
      • The Bisection Method requires an initial guess at endpoints. Although you can use whatever guesses you wish (as long as the function at those points has oppostive signs), the following are suggestions to consider (as easy guesses that always work).
        • Choose 0 as the left endpoint (a in the figure).
        • If r ≤ 1.0, choose 1.0 as the right endpoint (b in the figure).
        • If r ≥ 1.0, choose r as the right endpoint (b in the figure).
      • Whatever starting endpoints you use, include a paragraph about why those initial values fulfill the conditions for the Bisection Method.
    1. Trip Planning

      In planning a trip by automobile, several routes might be considered. Some roads may be direct, but speed limits vary according to the type of road. Further, travel through cities may take longer than routes that avoid driving through city centers. This problem considers finding routes in Iowa that will take the least amount of time from one city to another. For reference, the Iowa Department of Transportation posts a map of the main routes in Iowa. Most highways run north-south or east-west; interstate highways run through the middle of the state, US highways and some state roads run in some areas with reasonably high speed, and rural or county roads connect many smaller towns.

      In this problem, we consider the main interstates, US highways, state roads, and county roads. We do not consider small connecting roads, improved gravel roads, or rough gravel streets intended for low-speed farm travel. Further, all routes start at a designated starting city, go from one city to an adjacent city, until a destination city is reached.

      The following table identifies the time (in mimutes) for direct travel from one city to another within the northeastern quadrant of Iowa. (Data from Google maps, accessed January 2, 2015.) A dash indicates there is not a direct highway between cities, so a traveler must follow a path through intermediate cities on the way.

        Ames Cedar Rapids Charles City Clinton Davenport Decorah Des Moines Dubuque Grinnell 10Iowa City 11Iowa Falls 12Manchester 13Maquoketa 14Marshalltown 15Mason City 16Nevada 17New Hampton 18Waterloo 19Webster City
      Ames            35 min        50 min.          14 min      44 min
      Cedar Rapids      98 min.    141 min.    77 min.  74 min.  32 min.    54 min.  70 min.  76 min.        51 min.  
      Charles City                    78 min.        39 min    22 min.  48 min  
      Clinton    98 min.    47 min.                43 min.            
      Davenport        47 min.      74 min.    59 min.    44 min.              
      Decorah    141 min.          115 min.        90 min.          48 min.    
      Des Moines  35 min              51 min.          54 min.          
      Dubuque    77 min.      74 min.  115 min.      89 min.    47 min.  33 min.          87 min.  
      Grinnell    74 min.          51 min.    63 min.  92 min.      38 min.        80 min.  
      Iowa City    32 min.      59 min.      89 min.  63 min.    77 min.              
      Iowa Falls  50 min.    78 min.            92 min.        57 min.  58 min.  51 min.    54 min.  35 min.
      Manchester    54 min.      44 min.  90 min.    47 min.    77 min.    68 min.          48 min.  
      Maquoketa    70 min.    43 min        33 min.        68 min.            
      Marshalltown    76 min.          54 min.    38 min.    57 min.        36 min.    64 min.  
      Mason City      39 min.                58 min.        91 min.    70 min.
      Nevada  14 min.                    51 min.      36 min.  91 min.      78 min.
      New Hampton      22 min.      48 min.                      44 min.  
      Waterloo    51 min.  48 min.          87 min.  80 min.    54 min.  48 min.    64 min.      44 min.  
      Webster City  44 min.                    35 min.        70 min.  78 min.    

      Write a program that reads two cities and determines the path with the least driving time between them. The program should print both the list of cities on the path and the total time for the overall route.

    1. Checking Proximity to Electrical Service

      Archetectural plans for a building often show the location of electrical outlets. In this problem, a program reviews the minimum distances from room locations to elctrical outlets throughout the building.

      Since walls often are constructed with 2" by 4" studs, consider placing the floor plan of a building on a 4" grid. A sample floor plan is shown below for a 25' by 15' structure (grid size 76 by 46) (where the numbers show distance in feet):

                                        1  1  1  1  1  1  1  1  1  1  2  2  2  2  2  2
          0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
       0  wwwwwwwwwwwwwwwwwvwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwvwwwwwwwwwwwwwwwwwwwww
          w                                w                                         w
          w                                w                                         w
       1  w                                w                                         w
          w                                w                                         w
          .                                w                                         w
       2  .                                =                                         <
          .                                w                                         w
          .                                w                                         w
       3  .                                w                                         w
          .                                w                                         w
          .                                .                                         w
       4  .                                .                                         w
          .                                .                                         w
          .                                .                                         w
       5  .                                .                                         w
          .                                .                                         <
          .                                .                                         w
       6  w                                .                                         w
          w                                .                                         w
          w                                .                                         w
       7  w                                .                                         w
          w                          f     w                                         w
          w                                w                                         w
       8  wwwwwwwwwwwwww|wwwwwwwwwwwwwwwwwwwwwwww.............www|wwwwwwwwwwwwwwwwwwww
          w                                                                          w
          w                                                                          w
       9  w                          f                                               <
          w                                                                          w
          w                                                                          w
      10  w                                                                          .
          w                                                                          .
          w                                                                          .
        w                                                                          .
        w                                                                          .
          >                                                                          .
      12  w                                                                          .
          w                                                                          .
          w                                                                          .
      13  w                                                                          .
          w                                                                          .
          w                                                                          w
      14  w                                                                          w
          w                                                               f          w
          w                                                                          w
      15  wwwwwwwwwww^wwwwwwwwwwwwwwwwwwwwwwwwww^wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
      

      This floor plan uses a simple notation for these main elements:

      • w represents part of a wal
      • . represnets part of a door
      • a space represents open space within a room
      • <, > and = represent electrical outlets in the left, right side, and both sides of a wall shown vertically on the diagram,
      • ^, v, and | represent electrical outlets on the top, bottom, and both sizes of walls shown horizontally on the diagram.
      • f represents the location of a floor plug inside a room.

      In the example, the left wall has two electrical outlets accessible to the room on the right, the right wall has two outlets accessible to the left, and the middle wall has one location where outlets are available on both the left and right. Similarly the wall at the top has two outlets available to the rooms at the top, the wall at the bottom as two outlets available to the room above, and the middle wall has two locations with outlets available to the rooms on both sides.

      Although this representation is reasonably primitive, it translates simply to a 2-dimensional character array. Pragmatically, this should be set up by first asking the user for the size of the grid and then entering the character codes row by row.

      Write a program that reads the grid and then reads positions in the grid. For each position read, the program should compute the approximate shortest distance (in inches) to an electrical outlet.

      Programming notes:

      • Each horizontal character in the grid represents 4".
      • Each vertical character in the grid represents 4".
      • Diagonal distances can be computed using the Pythagorean Theorem.
      • Of course, wires cannot go through walls — only through open space and through doors.
    1. Directing a Robot to Follow a Tape

      Assume that tape has been place on the floor, and suppose that the color of the tape is significantly different (i.e., darker or lighter) than the floor. This problem asks you to write a program that will control the robot to follow the tape for at least a minute or two.

      Some programming notes:

      • In the lab on two-dimensional arrays, one exercise asks to locate an area of the brightest light in a picture. In this problem, use a similar approach to find the edge of a piece of tape on the floor. Since the color of the tape contrasts with the floor, one should scan a picture from the robot to determine where the color changes substantially from light to dark or dark to light.
      • If the color change is approximately straight ahead, the robot might go forward a short distance before taking another picture.
      • If the color change on the left side of the picture, the right motor might be directed to move more quickly than the left motor, so the robot will move somewhat to the left. The farther the color change is to the left, the more the difference between the right and left motors. After moving a short distance, the robot might stop and take another picture.
      • If the color change is to the right, the right motor might be directed to move less quickly than the left motor, so the robot will move somewhat to the right. The farther the color change is to the left, the more the difference between the right and left motors. After moving a short distance, the robot might stop and take another picture.

      Overall, the robot should follow a tape that winds left and right around the floor for at 10 or more feet.

    1. Assigning Lab Partners

      In CSC 161 and numerous other courses, students may work on labs or projects (sometimes other assignments) in small groups (usually pairs). These groups are assigned by the instructor, and groups are changed frequently. This problem seeks a program to determine these assigned groups. (Currently, the assignments are done manually, with a labor-intensive process.) The basic requirements follow:

      • Suppose there are N students in the class (where N is between 24 and 38). For the purposes of this problem, the students are numbered 1, ..., N.
      • Early in the semester, students are given the option of indicating
        • which 1-3 students they would like to work with a few times over the semester, and
        • which 1-3 students they would like NOT to work with during the semester.
        Following past history, for this problem, we assume no more than 6 students indicate preferences of whom to work with, and no more than 6 identify 1 or 2 people they do not want to work with. (Usually the numbers are just 2 or 3 in each category.)
      • Groups of 2 are preferred for an assignment, but a group of 3 is needed if N is odd.
      • Students expressing an interest in working with another designated person may be assigned that person up to 3 times during the semester, and these repeated assignments should be spread out over several groupings. Otherwise, students should be working with someone different with each assignment.
      • During the semester, a student should not be asked to work in a group of three more than once.
      • Sometimes during the semester (but not often), a student drops the course. That is, the student may be assigned a group for the first several weeks, but the student should not be assigned a partner after a designated week.

      Write a program that identifies and prints up to 14 assignments of students (i.e., up to one new assignment of pairs each week). The program should have the following features:

      • The program is deterministic. That is, the program makes the same assignments every time it is run. (This allows the program to be run several times during the semester, if a few people drop.)
      • The program provides the option that up to 8 students may drop the course after varying assignments. (In practice, there are rarely more than 2 drops, so allowing 8 is intended to be safe.)
      • Under varying circumstances, it may not be possible to make different assignments each week. However, in all cases, a student should never have to work with someone they explicitly wanted to avoid. Also, the resulting assignments should have as few repeated pairs of students as possible, with students wanting to work together never having more than 4 assignments together.
    1. Making Change

      Suppose a store's cash register stocks as many coins (pennies, nickels, dimes, quarters, fifty-cent pieces, and one-dollar coins) and as many bills (one-dollar, five dollar, ten dollar, and twenty dollar denominations) as possible.

      Write a program that reads an amount of change (up to $200.00) and prints:

      • all possible ways to make change, and
      • the number of this alternatives.

      Programming Notes:

      • Permutations of coins should be counted only once. That is, to make change for $0.11, four options should be counted: eleven pennies, six pennies and one nickel, one penny and two nickels, and one penny and one dime. The program should not count one penny and two nickels as being different from one nickel one penny and another nickel or as being different from two nickels and one penny.
      • Use of one-dollar coin should be considered as being different from a one-dollar bill.
      • The program should be reasonably efficient.
      • To help save paper in testing, the program may have a command-line argument "print" or "no-print" that turns on or off the listing of all possible ways to make change. If this is implemented, "no-print" would indicate that the total number of ways to make change would be printed, but not the actual listing of all of those alternatives.

      Hint: Although this problem can be solved in many ways, one reasonably efficient, simple, and elegant algorithm makes heavy use of recursion.

    1. Elementary Text Analysis

      Write a C program that takes the name of a file as a command-line argument, opens the file, reads through it to determine the number of words in each sentence, displays the total number of words and sentences, and computes the average number of words per sentence. The results should be printed in a table (at standard output), such as shown below:

      
           This program counts words and sentences in file "comp.text ".
      
           Sentence:  1    Words: 29
           Sentence:  2    Words: 41
           Sentence:  3    Words: 16
           Sentence:  4    Words: 22
           Sentence:  5    Words: 44
           Sentence:  6    Words: 14
           Sentence:  7    Words: 32
      
           File "comp.text" contains 198 words words in 7 sentences
           for an average of 28.3 words per sentence.
      

      Notes for this problem:

      • A word is defined as any contiguous sequence of letters. Apostrophes at the beginning or the end of a word should be ignored. Apostrophes with letters immediately before and after are considered part of a word. For example, "O'Henry", "I've", "you're", "friend's" and "friends'" should each be considered as one word.

      • A sentence is defined as any sequence of words that ends with a period, exclamation point, or question mark, except a period after a single capital letter (e.g., an initial) or embedded within digits (e.g., a real number) should not be counted as being the end of a sentence.

      • Digits and punctuation (other than apostrophes, periods, explanation points, and question marks) should be considered the same as white space. Thus,

           After they walked, talked, and ate, the first person said, "I'd like 
           to swim: crawl, side stroke, and butterfly."
        

        Should be considered the same as

           After they walked  talked  and ate  the first person said   I'd like 
           to swim  crawl  side stroke  and butterfly
        
      • White space (e.g., spaces, tabs, line feeds, and return characters) are considered as equivalent. Multiple white space characters are considered the same as one space character. Thus, the above passage would equivalent to the following:

        After they walked talked and ate the first person said I'd like to swim crawl side stroke and butterfly
        
    1. County Data

      The file /home/walker/207/data-sets/iowa-population-by-county.txt contains population and race information for Iowa counties from the 2010 census. County information is contained on two successive lines, followed by a blank line (for readability).

      1. The first county line contains the county name
      2. The second county line specifies the population of various racial groups within the county.
        • Column 1 gives the total population
        • Column 2 gives the number of whites only (no mixed race)
        • Column 3 gives the number Black or African Americans only
        • Column 4 gives the number of American Indians and Alaska Natives only
        • Column 5 gives the number of Asians only
        • Column 6 gives the number of Native Hawaiians and Other Pacific Islanders only
        • Column 7 gives the number of people identifying two or more races

      Write a program that reads a filename from the terminal and then determines the ranking of Poweshiek County regarding the total number of Black/African Americans. The result should be a ranking number (where 1 means that the county has the largest number of Black/African Americans and 99 means that the count has the smallest number of Iowa's 99 counties).

      Programming Notes:

      • In consideration of space efficiency, arrays may not be used in this problem. Arrays place constraints on the number of counties that might be present in a state.
      • In consideration of processing efficiency, the program should read through the file no more than twice. Multiple passes through the data would require many disk accesses, which involves substantial overhead.
    1. Filtering and Reporting Data

      Gemstones are attractive forms of rock crystal, commonly used for decoration and in jewelry. Gemstones also have interesting mineral properties. Gemstones may be classified in a variety of ways, including chemical composition, crystal structure, color, specific gravity, refractive index, and hardness:

      1. Chemical Composition: While some gemstones are primarily composed of atoms of one element (e.g., diamonds are mostly carbon, with coloring coming from traces of other elements), other gemstones are made up of atoms of several atoms (e.g., mica molecules include oxygen, hydrogen, silicon, aluminum, iron, and/or many others). On-line sources of information include general references (e.g., Common Mineral Groups) and references to specific minerals (e.g., micas).

      2. Color may be classified informally (e.g., red, yellow, etc.) or more formally by viewing thin slices of mineral crystals through the microscope, using polarized light (see, for example, Minerals under the Microscope).

      3. Specific Gravity is a measure of the density of a mineral. More precisely, specific gravity is the ratio of the weight of the mineral in air to its weight in an equal volume of water. More details are available from various on-line sources (see, for example, the Mineral and Gemstone Kingdom's glossary for specific gravity.

      4. Refractive Index provides a measure of how much light bends within a crystal. The higher the refractive index, the more bending and the more brilliant a crystal is likely to appear. For more information, see various on-line sources, such as Refractive Index.

      5. Crystal Structure: Crystals typically have one of several standard shapes or structures, including cubic, tetragonal, orthorhombic, hexagonal, monoclinic, and triclinic. While the details of such structures are beyond the scope of this problem, the World Wide Web contains many useful references, including crystal forms (at the macro-level) and the (atomic-level) representation of structures prepared as part of lecture series by S. J. Heyes.

      6. Hardness often is measured on the (nonlinear) Mohs Scale, which associates a hardness number to each mineral, from 1 (softest) to 10 (hardest):

        1. Talc
        2. Gypsum
        3. Calcite
        4. Fluorite
        5. Apatite
        6. Orthoclase
        7. Quartz
        8. Topaz
        9. Corundum
        10. Diamond

        As a comparison, a fingernail has hardness 2.5, glass has hardness 5.5, and a steel file has hardness 6.5. Minerals of the same hardness should not scratch each other, but a mineral of one hardness will scratch minerals with a lower hardness number.

      File /home/walker/151s/labs/gems.txt contains information on several gemstones, including color, hardness, specific gravity, and refractive index. Within the file, each line contains information about a specific gemstone.

      Here are a couple of sample lines, and a character 'ruler' to show how wide the fields are:

                11111111112222222222333333333344444444445555555555666666666677777
      012345678901234567890123456789012345678901234567890123456789012345678901234
      
                      Zircon        RED           7.5         4.50         1.95
                       Topaz     YELLOW             8         3.53         1.62
      

      To clarify, the names of the gemstones come first in a line and are right-justified in a column. The colors come next, followed by hardness (on a scale 1 to 10), then specific gravity, and finally refractive index (generally between 1.3 and 2.5).

      Write a program print-by-color that will let you select the gemstones of a certain color and print the information about those gemstones, where the resulting table is in alphabetical order by gemstone name and where the columns are labeled.

      For example, if this procedure is invoked with the statement

      
      (print-by-color "GREY")
      
      the procedure should return a table, such as the following:
      
                                                            Specific   Refractive
                    Gemstone       Color       Hardness      Gravity      Index
      
                   Alabaster       GREY             2         2.32         1.53
                    Bakelite       GREY           2.5         1.28         1.65
                     Calcite       GREY             3          2.7         2.71
                      Casein       GREY           2.5         1.33         1.55
                    Celluoid       GREY             2         1.35         1.50
                  Chalcedony       GREY             7         2.62         1.53
                    Corundum       GREY             9         3.99         3.99
                     Diamond       GREY            10         3.52         3.52
                    Hematite       GREY             6         5.10         5.05
                       Ivory       GREY           2.5         1.80         1.54
                     Jadeite       GREY             7         3.34         3.33
                 Labradorite       GREY             6          2.7         2.70
                      Marble       GREY             3         2.71         1.50
                  Meerschaum       GREY             2         1.50         1.53
                    Nephrite       GREY           3.5         3.00         2.96
                        Opal       GREY             6         2.10         2.10
                      Quartz       GREY             7         2.65         1.55
                      Quartz       GREY             7         3.33         2.65
                        Talc       GREY             1         2.70         2.75
      
      Another possible format might be:
      
                                             Specific   Refractive
      Gemstone Name       Color    Hardness   Gravity      Index
      
      Alabaster            GREY       2         2.32        1.53
      Bakelite             GREY       2.5       1.28        1.65
      Calcite              GREY       3         2.70        2.71
      Casein               GREY       2.5       1.33        1.55
      Celluoid             GREY       2         1.35        1.50
      Chalcedony           GREY       7         2.62        1.53
      Corundum             GREY       9         3.99        3.99
      Diamond              GREY      10         3.52        3.52
      Hematite             GREY       6         5.10        5.05
      Ivory                GREY       2.5       1.80        1.54
      Jadeite              GREY       7         3.34        3.33
      Labradorite          GREY       6         2.70        2.70
      Marble               GREY       3         2.71        1.50
      Meerschaum           GREY       2         1.50        1.53
      Nephrite             GREY       3.5       3.00        2.96
      Opal                 GREY       6         2.10        2.10
      Quartz               GREY       7         2.65        1.55
      Quartz               GREY       7         3.33        2.65
      Talc                 GREY       1         2.70        2.75
      

      As shown in each example, the gemstone names and properties must appear in labeled columns. Gemstone names may be either left-justified or right-justified.

      Note that some gemstones, such as Quartz above, appear several times in the table, since variations of a gemstone may have different properties.

    1. Parenthesis Checking

      Write a program that reads a line of text from the terminal and checks if the parentheses in the line are balanced.

      Notes

      1. The program should distinguish among three types of parentheses, { }, [ ], ( ).
      2. Parentheses checking should involve working from the inside of nested parentheses to the outside.
      3. In each case, the appropriate right parenthesis should be matched with a left parenthesis of the same type.

      Examples

      1. ( these { parentheses[] match } perfectly ) !!!
      2. (the {right [parentheses ) on } this line ] are in the wrong order.
      3. this ( line { is missing } one (round ) right parenthesis.

      Comments on a solution to the problem: This problem can be solved reasonably easily using a single left-to-right scan of a line, if left parentheses are placed on a stack as they are encountered. Then, when a right parenthesis is found, the stack can be popped and one can check if the right parenthesis has the same type as the left one.

      Programming Note: Your program should use a self-contained Stack library package, as described in the lab on Stacks and implemented as lists.