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

Supplemental Problems

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

Format:

In turning in any programs for the course, please follow these directions:
  1. The first lines of any C program should be comments containing your name, your mailbox number, this course number (161), an identification of assignment being solved, and an Academic Honesty certification. (You may not talk to anyone, except the instructor, a class mentor, or an evening lab tutor, for any Supplemental Problem.) For example:
    
        /*****************************************************************
         * Henry M. Walker                                               *
         * Box:  Science                                                 *
         * Supplemental Problem 1 for CSC 161                            *
         * Assignment for Friday, February 7                             *
         *****************************************************************/
    
        /* ***************************************************************
         * Academic honesty certification:                               *
         *   Written/online sources used:                                *
         *     [include textbook(s),                                     *
         *       CSC 161 labs or readings;                               *
         *       complete citations for Web or other written sources]    *
         *     [write "none" if no sources used]                         *
         *   Help obtained                                               *
         *     [indicate names of instructor, class mentors              *
         *      or evening lab tutors, consulted                         *
         *      according to class policy]                               *
         *     [write "none" if none of these sources used]              *
         *   My signature below confirms that the above list of sources  *
         *   is complete AND that I have not talked to anyone else       *
         *   [e.g., CSC 161 students] about the solution to this problem *
         *                                                               *
         *   Signature:                                                  *
         *****************************************************************/
    
    Also, a comment is needed for every definition of a C function, stating both pre- and post-conditions for that program unit.

  2. Email your program to grader-161.01@cs.grinnell.edu or grader-161.02@cs.grinnell.edu, as appropriate, following these instructions:
    • The subject line should include "CSC 161", the assignment name, and your name (when the program involves work with a collaborator, put both names in the subject line).
    • Include the C program as an attachment. If the program involves several files, attach all relevant (.c and .h) files. (Include only the source code (e.g., .c and .h files; do not include compiled code.)
    • Include an attachment that shows test runs of the program.
    • To count as being submitted on time, the time stamp on the email must be before the start of the class in which the work was due.
  3. Turn in a printed copy of your program, relevant output, and a discussion of testing.
    • A printed copy of the program should be on top. (Since your name, box, etc. are required to be at the start of the program, this printout will identify that this is your work.)
    • If your work involves several files, list the main program first; then list any supplementary files.
    • Write a statement that documents the testing process for this program. The statement should include:
      • A numbered listing of the circumstances that can reasonably arise in this problem.
        • For example, if a program is to categorize data, the listing should include a statement of the categories; If some category could be obtained in several ways, the statement should identify each circumstance that could lead to the category.
        • As another example, if the order of initial data might impact processing, then the listing should include circumstances to test the order of input data.
      • A listing of test cases to be considered, with the expected outcome.
        • For each numbered item in the listing of possible circumstances, there should be a corresponding test case identified.
        • Each test case should be specific, including what data will be considered and what output is expected.
    • Compile your program with the gcc command, and run it.
      • If the program does not use the Scribbler 2, include the full range of test cases that demonstrate the correctness of your program. (You should print the full interaction from the terminal during the test runs.)
      • If the program uses the Scribbler 2, include a description of what test runs you used and what results you obtained.
      • The actual test runs should follow the above listing of test cases.
      • Each test run should be annotated (writing on the printout is acceptable), identifying which test case is being run and whether or not the output produced is correct.
    • Once testing is completed, prepare a separate statement that argues why your program is correct, based upon the evidence from your test runs.

Some Grading Notes:


  1. Parking Lot Charges

    A downtown parking lot charges $0.75 per hour for parking between 7:00 am and 5:00 pm, $2.00 per hour between 5:00 pm and midnight (high demand for people seeking entertainment), and $1.25 between midnight and 7:00 am (since late night requires an attendant to be paid time and a half).

    In this problem, we consider cars parked for 24 hours or less; to avoid the parking lot becoming a dumping ground, cars may NOT be parked continuously in the lot for more than a day.

    By widely-used convention, midnight is considered 12:00 am, and noon is considered 12:00 pm.

    Write a program that begins with six assignment statements regarding a car's starting and ending times in the lot:

    • starting hour: hour car entered lot (int 1..12)
    • starting minute: minute car entered lot (int 0..59)
    • start before or after noon: char 'a' for am or char 'p' for pm
    • ending hour: hour car left lot (int 1..12)
    • ending minute: minute car left lot (int 0..59)
    • end before or after noon: char 'a' for am or char 'p' for pm

    The program then should use these times to compute the parking fee charged for the car.

    Three sample variable assignments follow:

    • Car parked 24 hours from 12 midnight one day to 12 midnight the next.
         int start_hour = 12;
         int start_minute = 0;
         int start_ampm = 'a';
         int end_hour = 12;
         int end_minute = 0;
         int end_ampm = 'a';
      
    • Car parked from 5:10 am to 10:47 pm
         int start_hour = 5;
         int start_minute = 10;
         int start_ampm = 'a';
         int end_hour = 10;
         int end_minute = 47;
         int end_ampm = 'p';
      
    • Car parked from 5:15 pm to noon the next day
         int start_hour = 5;
         int start_minute = 15;
         int start_ampm = 'p';
         int end_hour = 12;
         int end_minute = 0;
         int end_ampm = 'p';
      

      Programming Notes:

      • You may NOT use loops or recursion in this program.
      • Rather than work with hours, minutes and am/pm throughout the program, you may want an internal variable (e.g., starttime and endtime) that works with a 24-hour clock. Presumably, the values of these internal variables would be computed based on the six specified variables.

      Grading Forms

      Note: In addition to the program, a separate page should indicate what cases should be considered in the testing of this program, what test data have been identified to test the program in each of the cases, and what the program printed for each of the tests.

      Sample solutions:

  1. Times for Walking and Running

    When running or walking for exercise, it is not uncommon for an individual to determine the time it takes to travel 1/4 mile (in minutes and seconds) and to compute one's speed in miles per hour or kilometers per hour.

    Write a program that prints a table of speeds in the following format:

               Speed in MPH and KPH, Given Time for 1/4 mile
                                  Minutes
    Seconds    3          4          5          6          7
       0
       1
       2
       3
     ...
      29
      30                          2.7/4.4
      31
     ...
      59
    

    For example, in this table, if an individual covers 1/4 mile in 5 minutes, 30 seconds, then the person is traveling about 2.7 miles per hour (MPH) or, equivalently, 4.4 kilometers per hour (KPH).

    Programming Notes:

    • 1 mile is approximately 1.60344 kilometers
    • Your solution must include a function compute_mph to compute miles per hour, given time in minutes and second for traveling 1/4 mile. The function should have the following signature:
      double compute_mph (int min_time, int sec_time)
      
    • Your solution also must include a function compute_kph to compute kilometers per hour, given time in minutes and second for traveling 1/4 mile. The function should have the following signature:
      double compute_kph (int min_time, int sec_time)
      
    • compute_kph should call compute_mph to obtain MPH and then convert miles to kilometers.
    • To print double numbers to one decimal place, use %3.1lf format (or %4.1lf). The .1 indicates 1 digit will be printed after the decimal point.

    Grading Forms

  1. A Modified Sieve Method of Erastosthenes

    This problem is adapted from Problem 8.12 in Introduction to Computing and Computer Science with Pascal, Little, Brown, and Company, 1986, pp. 265-266. Used with permission of the copyright holder.

    Recall that a positive integer greater than or equal to 2 is called prime if it is evenly divisible only by 1 and itself. Thus, the numbers 2, 3, and 5 are prime, but 4 and 6 are not prime (4 is also divisible by 2 and 6 is also divisible by 2 and 3). (Technically in mathematics, 1 is called a unit, not a prime number.)

    In ancient Greece, Erastosthenes gave the following algorithm for determining all prime numbers up to a specified number M.

    1. Write down the numbers 2, 3, ..., M
    2. Cross out numbers as follows
      1. Keep 2, but cross out all multiples of 2 (i.e., cross out 4, 6, 8, ...).
      2. Keep 3, but cross out all multiples of 3 (i.e., cross out6, 9, 12, ...). While 6 is crossed out twice, it only matters that it has been crossed out at least one in Erastosthenes' Sieve.
      3. Since 4 is already crossed out, go on to the next number that is not crossed out (i.e., 5). Keep 5, but cross out all multiples of 5 (i.e., 10, 15, 20, ...).
      • General step. Suppose you have just processed the number P. Go on to the next number that is not crossed out — Q. Keep Q, but cross out all multiples of Q.

    After you have finished all the crossing out, the numbers remaining are primes.

    This method is called the Sieve Method of Erastosthenes.

    When implementing this approach within C, it is common to use an array int arr [0..M+1] to record which elements are still kept and which are crossed out. arr[0] and arr[1] are ignored. The rest are initialized to 0, and crossing out a number corresponds to setting the relevant array element to 1 (or incrementing the relevant array element by 1).

    In this problem, we refine the Sieve Method of Erastosthenes to keep a count of the number of times an integer is crossed out. Also, we modify the approach to cross out for each new value — not just those that have not been crossed out previously. In this way, arr[i] will count the number of non-trivial factors of i (factors other than 1 and i itself). Note that the count will be 0 for prime numbers.

    Write a program that reads an integer M and

    • prints the numbers 2, ..., M and the number of non-trivial factors for each number, and
    • prints the three numbers with the most factors between 2 and M (inclusive).

    Programming Notes:

    • For this problem you may assume M ≥ 4, so at least 3 numbers will be under consideration for finding the three numbers with the highest factor counts.
    • The numbers and counts should be printed 8 to a line. Thus, the first part of the printout might be
      2:0     3:0     4:1     5:0    6:2    7:0     8:2   9:1
      10:2   11:0    12:4  ...
      
    • To find the numbers with the most factors, use the approach illustrated in the module on arrays and functions with program max-min.c. If several numbers share the highest counts, then any numbers with the same high counts may be printed.
    • This program should make one pass through the array to find a maximum in variable max Finding the second or third largest can be done in a similar way, with additional variables max2 and max3. In particular, finding the top three elements should be done in a single loop that goes through each element once.
    • Sorting is not needed in this problem and is inefficient for the question asked. Thus, an algorithm that uses a sorting algorithm will receive 0 credit for the maximum computation.

Grading Forms

Sample solutions

  1. Playing Modified Scrabble

    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 considers 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 write a program to support the addition of new words for this type of word grid. In particular, the program should do the following.

    • When the program starts, it should ask for the number R of rows and the number C of columns for the grid, and a blank grid of this size should be created internally. (This blank grid need not be printed.)
    • Subsequent processing will consider squares identified with a row and column, i and j, with 0 ≤ i ≤ R and 0 ≤ j ≤ C.
    • The user inputs new words, specifying two or four pieces of data:
      • If the user enters a word, followed by a space and the letter R, then the program is free to place the word any place at random where the word fits.
      • If the user enters a word, followed by a space, the letter H, a space, a number i, a space, and another number j, then the word is to be placed horizontally with the first letter at row i and column j.
      • If the user enters a word, followed by a space, the letter V, a space, a number i, a space, and another number j, then the word is to be placed vertically with the first letter at the row i and column j.
    • If the word placement is given and is valid, the word is added to the grid, and the grid is printed. (I.e., the word is added if it intersects with at least one letter already on the board, and the letters match each time the new word intersects an existing one letter in the grid).
    • If the word placement is not given (letter R is entered), then the word is added to the grid once at any valid position (if such a position exists), and the grid is printed.
    • If the word cannot be added at the specified location or if no position is possible for an open placement, then an error message is printed.
    • The program continues to ask the user to enter words until the user enters QUITQUIT, in which case the program stops.

    Programming Notes:

    • In placing any word, it should not run off the edge. That is, if a word is too long to fit in the space from its designated start to the edge of the grid, then no part of the word may be inserted.
    • The program should contain a function check_horizontal that determines if a word can be added horizontally to the grid at a given location:
      /* check if the given word can be added horizontally at the given location
         pre-conditions
            row is a valid row location within the grid
            col is a valid column location within the grid
            word is a valid string
            num_rows is the total number of rows in the grid
            num_cols is the total number of columns in the grid
            grid is the two-dimensional array representing the grid
         post-conditions
            returns true (i.e., 1) if the word can be added to the grid
                    horizontally with the first letter at the given row and col
            returns false (i.e., 0) otherwise
            the grid is NOT changed
      */
      int check_horizontal (char * word, int row, int col, 
                            int num_rows, int num_cols, char grid[num_rows][num_cols])
      
    • The program should contain a function check_vertical that determines if a word can be added vertically to the grid at a given location:
      /* check if the given word can be added horizontally at the given location
         pre-conditions
            row is a valid row location within the grid
            col is a valid column location within the grid
            word is a valid string
            num_rows is the total number of rows in the grid
            num_cols is the total number of columns in the grid
            grid is the two-dimensional array representing the grid
         post-conditions
            returns true (i.e., 1) if the word can be added to the grid
                    vertically with the first letter at the given row and col
            returns false (i.e., 0) otherwise
            the grid is NOT changed
      */
      int check_vertical (char * word, int row, int col, 
                            int num_rows, int num_cols, char grid[num_rows][num_cols])
      

    Grading Forms

  1. Singly-linked-list Processing

    Program namelist-2014-sp.c contains a simple framework for maintaining a singly-linked list of names (with no more than 20 characters). The program has these features:

    • A singly-linked-list structure is defined.
    • The list is initially null.
    • A basic menu identifies several processing options, the program reads a user option, and the program calls a procedure for that option.
    • Procedure addName allows names to be added anywhere on the list.
    • Procedure print allows current names to be printed from the first to the last.

    This problem asks you to implement three additional functions within this program.

    • Function addNamesFromFile asks the user for the name of a file. Then names on separate lines from that file are added to beginning (not the middle or end) of the current list.

      • If no file exists by the given name, the program should print an error message, exit the function, and continue with other processing.
      • If the file exists, each line of the file will be considered a single name, and each name is added, in order, to the beginning of the list. For example, suppose a list begins with the nodes "original" "list" in two nodes:
        original list

        and suppose the file contains the lines

        first
        second
        third
        fourth
        
        Then the resulting list would become
        original list

        As this example illustrates, each new name in the file is added at the front of the list, as it exists at that time.

    • Function removeDuplicates removes duplicate nodes from the current list:

      • The first copy of a name on the list is retained.
      • All copies of a name after the first are deleted.
      • In the final list, the first copies of the names of the original list should be in the same order as at the start.

      In this processing, duplicate nodes should be removed and space deallocated, but no new nodes should be created.

    • Function duplicate adds a duplicate of each node after the node on the current list:

      • For each node on the list,
        • A new is created.
        • The name from the existing node is copied to the new node
        • The new node is inserted into the list after the existing node.

        For example, if the original list had 3 nodes:

        original list

        Then the new list after duplicate would have 6 nodes:

        revised list

    Programming Hints:

    • In Program namelist-2014-sp.c, code for addName and print should not be changed in any way.
    • Program namelist-2014-sp.c also contains stubs for the new operations, but the bodies of these procedures only print a message that the operations are not implemented. This problem asks you to expand these stubs to working procedures.
    • In reading from a file, a name may contain spaces and/or punctuation. However, you may assume each line of the file contains a separate name, and the name has no more than 20 characters. Multiple names will not appear on the same line of a file.
    • Although code within the existing addName procedure itself should not be changed, parts of that code could be copied, modified, and streamlined in another procedure (e.g., addNamesFromFile) for insertion of names from a file.
    • In identifying duplicate names, it is up to the programmer to decide whether or not names with letters in different cases (upper case and lower case) are considered as the same name. Names with the same string of characters (with the same case) should be considered the same, but names with the same characters in different cases may or may not be considered the same (at programmer's discretion).

    Problem-specific grading form for Supplemental Problem 5


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. Syracuse Numbers

    This problem was suggested by Professor Arnold Adelberg.
    The wording of this problem is slightly edited from Problem 14 in Section 4.3 of "Problems for Computer Solutions Using BASIC" by Henry M. Walker, Winthrop Publishers, 1980.

    Consider the following iteration procedure applied to a positive integer n0 to generate a sequence

    n0, n1, n2, n3, ...
    Once the integer nj is known, the next integer nj+1 is computed by the rules:

    1. nj+1 = nj / 2, if nj is even;
    2. nj+1= 3*nj + 1, if nj is odd;

    The original number, nj, is called "Syracuse" if the number 1 appears in the sequence n0, n1, n2, n3, ... .

    Example: The number 5 is "Syracuse" because if the iteration begins with n0 = 5, the sequence is 5, 16, 8, 4, 2, 1, ... .

    Write a program to show that all integers between 1 and 2000 inclusive are "Syracuse".

    Note: You should not use arrays for this problem.

  1. Numbers in Alphabetical Order

    Consider the positive numbers, written as names, such as

       one, two, three, four, five, six, seven, eight, nine, ten,
       eleven, twelve, thirteen, ...
       twenty one, twenty two, ...
    

    Write a program that reads a positive integer n and prints the names of the integers from 1 to n in alphabetical order, where n ≤ 300.

  1. Anagrams

    Sometimes one can simplify a problem by removing the parts that don't matter, and then looking at what's left.

    For instance if you wanted to figure out if two collections of "stuff" were the same, you might remove matching items from each collection until you see if there are items left over. If you have leftover items, the collections were different, and if both collections become empty at the same time, they are identical.

    Use this technique to write a program which will determine whether or not two strings are anagrams of each other.

    Test it by deciding whether or not "one PLUS twelve" is an anagram of "eleven PLUS two", among other test cases. (Note that spaces should match as well as letters.)

    Note: Two programs, one iterative and one recursive, might be eligible for bonus points.

  1. A Simplified Eliza Program

    One of the early, well-known programs within the field of artificial intelligence was called Eliza, a program by Joseph Weizenbaum. The idea was to simulate conversation between a patient and psycho-therapist, based on a series of patterns and corresponding responses. Although the original program had an extensive sequence of patterns, this assignment focuses on the following five rules:

    Pattern     Response Template
    ---1 my singleWord ---2 me ---3 tell me about your singleWord
    ---1 i am ---2 i am sorry to hear you are ---2
    ---1 am i ---2 do you believe you are ---2
    ---1 you ---2 me --- 3 why do you think i ---2 you
    ---1 in what way

    In this table, the blank spaces in a pattern, denoted by subscripted dashes, can be filled in with any sequence of words. Similarly, singleWord represents exactly one word in a sentence. For example, these patterns might generate the following "conversation," where the responses are indented and in italics:

    Sample Dialogue:

    well my friend made me come here
        tell me about your friend
    he says i am depressed
        i am sorry to hear you are depressed
    i think i need help
        in what way
    i wonder if you would help me learning to program Scheme
        why do you think i would help you
    when i registered for the course i wondered am i crazy
        do you believe you are crazy

    Each of these statements and responses follows the template/response patterns given. For example, in the first statement:

    well my friend made me come here

    the presence of the word my near the start of the sentence with the word me later on corresponds to the first pattern, with the following matches:

    Pattern Element     Words from this Sentence
    ---1 well
    my my
    singleWord friend
    ---2 made
    me me
    ---3 come here

    After identifying these pattern elements for the first pattern, the Eliza program uses the corresponding response template. In this case, the program prints "Tell me about your friend". The first four of these words come directly from the template. For the final word, singleWord in the template was matched with the word "friend" in the above analysis.

    Historical Note

    Although this approach may seem simple today, Joseph Weizenbaum used this approach as the basis for his widely heralded Eliza in 1966. In 1976, Weizenbaum noted he "was startled to see how quickly and how deeply people conversing with [ Eliza] became emotionally involved" in the conversation. People shared their hopes and secrets, and they became annoyed if other people looked over their shoulders or otherwise interrupted. Even when they knew Eliza was a program, they often talked as if it were a close personal friend.

    Exercise

    Write a C program to solve this Eliza-based pattern-matching problem. For example, if you entered the successive dialog strings from the "Sample Dialog" above, the program would respond as the example indicates. The program should continue to read user input until the user types "quit".

  1. Simulation of Hi Ho! Cherry-O

    This problem explores statistics for the game of Hi Ho! Cherry-O. For our purposes, we will follow the description of the game as described in Wikipedia. Note, however, that the number of cherries on a player's tree is always between 0 and 10.

    • If one spins 1, 2, 3, or 4, that number of cherries is removed from the tree (except that the number of the tree can never be negative).
    • If one spins a bird and the number of cherries on the tree is 9 or fewer, then the number of cherries on the tree goes up by 1. However, if one spins a bird and the number of cherries on the tree is 10, then the number of cherries on the tree is unchanged.
    • If one spins a dog and the number of cherries on the tree is 8 or fewer, then the number of cherries on the tree goes up by 2. However, if one spins a dog and the number of cherries on the tree is 9 or 10, then the number of cherries on the tree becomes 10 (not higher).
    • If one spins a spilled bucket, then all of the cherries return to the tree.

    The game progresses in rounds, during which each player in turn spins a game spinner that has seven outcomes (as described in the Wikipedia article). In our simulations, we will assume that each outcome of the spinner arises randomly with equal probability.

    Within this framework, the specific purpose of this supplemental problem is general statistics on how many rounds the game is likely to continue, based on the number of people playing the game. The required work for this problem involves three C procedures, combined within a main program.

    • Procedure turn simulates one turn of a player; that is, it takes a number init_cherries as parameter, and adjusts the number of cherries on the tree appropriately — using C's rand function to determine the outcome of the spinner.
    • Procedure playGame has players, the number of players, as input parameter, and returns the number of rounds taken until some player wins.
    • Procedure playNGames has two parameters: players, the number of players in a game, and games, the number of games to be simulated. playNGames returns a list with the maximum, minimum, and average number of rounds taken by the players over the full number of games.

    Hints: Although you are free to approach this problem however you want, the following pieces might help.

    • Write a procedure init_games that takes a number of players as parameter and generates a list of that number of 10's (the initial number of cherries on the trees for each of those players).
    • Write a procedure play_round that takes a list of tree-cherry numbers as parameter, plays one round for each player, and returns a list of new totals for the number of cherries for each player.
    • Write a procedure check_win that takes a list of tree-cherry numbers as parameter and checks if any of the players has won.
  1. Dealing Bridge Hands

    Write a program that simulates the dealing of a deck of cards to give four bridge hands. Each run of the program should give a different random assignment of the cards. The program should print both the cards held for each hand and the point-count for bidding.

    A simple scoring system gives an ace 4 points, a king 3 points, a queen 2 points, and a jack 1 point, with an extra point given if a hand contains all aces and a point deducted if it contains no aces. Points also are given for distribution, with a point given if a hand contains only 2 cards in a suit (a doubleton), 2 points given if a hand contains a single card in a suit (a singleton), and 3 points given if a hand has no cards in some suit.

  1. County Data

    The file /home/walker/207/data-sets/iowa-counties.txt contains population and race information for Iowa counties from the 2010 census. County information is contained on two successive lines.

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

    Write a program that reads a filename from the terminal and then finds the three counties with the highest percentage of non-whites.

  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.

  1. A C Version of Scheme's MAP Procedure

    In Scheme, recall that the map procedure takes a procedure and one or more list(s) as parameters and returns the list obtained by applying the procedure parameter to the list(s). This problem asks you to write a basic version of map in C.

    In particular, write a C procedure map with the following signature:

    
    node * map (int f (int), node * lst)
    

    where node is a list node defined as:

    
       struct node
       { int data;
         struct node * next;
       };
    

    and where f is a function that can be applied to an integer to obtain another integer.

    Notes:

    • The parameter lst points to the first node of a singly-linked list of integers.
    • The list designated by lst is not changed by map.
    • map returns a pointer to the first element of a new list.
    • The resulting singly-linked list has the same length as the list lst and the elements on this new list should have values obtained by applying f to the integers stored in lst (and in the same order).
    • Testing of this procedure is essential. It is suggested that you embed this procedure in a linked-list program (perhaps from one of the laboratory exercises related to linked lists in Modules 101 or 110).

    This problem may be solved either iteratively or recursively. Credit may be obtained for either the interactive or recursive solution. Additional credit is possible for two versions of this procedure, one iterative and the other recursive.