CSC 161 Grinnell College Fall, 2013
 
Imperative Problem Solving and Data Structures
 
 

Supplemental Problems

This listing of problems is under revision!
Specifically, problems will likely be revised in the new few days.

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 8                             *
         *****************************************************************/
    
        /* ***************************************************************
         * 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@cs.grinnell.edu, as follows:
    • 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. Car Insurance Rates for Drivers 16-24 Years Old

    Insurance rates for drivers 16-24 years old depend on numerous factors, including age, driving environment (e.g,. urban, suburban, rural), make, model and age of car, etc. Also, after establishing a basic insurance rate, discounts may be available for certain types of drivers. This problem considers a simplified rate schedule for car insurance.

    According to Aol Autos, the average annual base rate for a high school or college-age driver is:

    Age Average Annual Rate
    16-19 $2,999
    20-24 2,040

    From this base, insurance companies offer various discounts. For the purposes of this problem, consider the following discounts that may or may not be typical.

    • Students with good grades can get a "good student" discount: 25%
    • Young drivers who have had a driving course can get a "driver education" discount: 21%
    • Young drivers who have been driving at least 3 years can get a "good driver" discount, if they have not had an accident or traffic ticket in the past 3 years: 17%

    When a young driver is eligible for several of these discounts, combination rules may apply. For the purposes of this problem, apply the following rules which may or may not reflect practice.

    • If a driver is eligible for two of these discounts, then the discounts are added — up to a 40% discount.
    • If a driver is eligible for all three discounts, then the driver receives a 50% discount.

    The following table summarizes these discounts:

    Good Student Driver Education Good Driver Discount
    Yes No No 25%
    No Yes No 21%
    No No Yes 17%
    Yes Yes No 40%
    Yes No Yes 40%
    No Yes Yes 38%
    Yes Yes Yes 50%

    Write a program that contains a drivers age (between 16 and 24, inclusive), whether or not the driver is a "good student", has had "drivers education", and is a "good driver" (drivers at least 19). (For each factor, the program should have a variable, with value 1 or 0 reflecting whether that factor applies. For example, a good_Driver variable would be 1 if the driver is eligible for a "good driver" discount and 0 if not.) The program then should print the annual car insurance rate for this driver, based on the above sample data.

    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.

  1. Status of Loan Balance

    The wording of this problem is slightly edited from Problem 9 in Section 3.2 of "Problems for Computer Solutions Using BASIC" by Henry M. Walker, Winthrop Publishers, 1980.

    If $387.46 for an airline ticket is charged on a credit card, the company may specify a minimum monthly payment of $15.00 each month until the loan is paid off. This problem asks you to investigate the "cost" of making only the minimum payment. Interest might be charged at the rate of 1.5% of the outstanding balance at the end of a month. The balance for the next month is computed by the formula:

    new balance = old balance + interest - payment

    Write a program that contains the initial balance of a loan, the monthly interest rate, and the constant monthly payment. Have the program print a labeled table showing the month number and the balance at the beginning of that month (the balance at the beginning of the month 1 is the amount borrowed). Continue printing until a payment would cause the balance to drop to zero or below. Also print the final payment necessary to close the loan, the total amount made in payments, and the "cost" of the loan (total payments - loan).

    Problem-specific grading form for Supplemental Problem 2

  1. A Polyalphabetic Cipher

    Background: Monoalphabetic Ciphers

    A common approach for encoding messages involves replacing one letter by another throughout the message. Such an encoding method is called monoalphabetic substitution. As an example, consider the following encoding scheme:

    
    Plain alphabet:   ABCDEFGHIJKLMNOPQRSTUVWXYZ
    Cipher alphabet:  XDQTVBKRAUGMZHYWCJOSENILPF
    

    Now consider the message, "THIS IS A MESSAGE TO ENCODE." For each letter in the message, we encode it by looking up each letter in the plain alphabet and replacing it by the corresponding in the cipher alphabet. Characters not in the plain alphabet (e.g., punctuation) are left unchanged. Thus, the letter T is replaced by the letter S, "THIS" becomes "SRAO", and the entire message is encoded as "SRAO AO X ZVOOXKV SY VHQYTV." Note that the space and period characters are not changed.

    Note: This type of monoalpabetic substitution is the base for many word and letter puzzles in newspapers and magazines.

    Monoalphabetic Ciphers Are Reasonably Easy to Break

    As you might expect from a puzzle that is used widely in the popular press, monoalphabetic ciphers are reasonably easy to break. Since each letter of the alphabet in the original message is always converted to the same letter in the enciphered message, properties of English can be considered. For example, in a newspaper puzzle, if a coded word is shown to be one letter long (and if the language is English), then the coded letter likely stands for either 'A' or 'I', since those are the only two 1-letter words in common English. Similarly, if one counted the number of times each coded letter appeared, the most common coded letter likely stands for 'E' or 'T', because those two letters arise much more often than others in typical English text. As one more illustration, if a three-letter coded word appears frequently — and if the first two letters appear frequently elsewhere, then the three-letter coded word has a good chance of representing the word "THE".

    Polyalphabetic Ciphers

    To discourage code breakers from utilizing common characteristics of English (or another language), one common encryption approach is to utilize several alphabets. For example, sometimes 'A' will be encrypted by one letter, and another time 'A' will be encrypted by another letter. Since one letter in the original translates to several candidates, a code breaker is likely to have a difficult time exploiting many statistical properties of language.

    To implement this strategy, one approach might utilize a different cipher alphabet for each letter to be encrypted. However, in practice, this is impractical. The sender and intended receiver of the message would have to communicate the full text of all of the cipher alphabets — a significant challenge for extensive communications at a distance.

    As an alternative, a common approach utilizes just one cipher alphabet (as in a monoalphabetic cipher), but with some preliminary steps. We combine an example with a description of the general algorithm.

    Encryption

    Suppose we want to encrypt the message:

    THIS LINE TESTS BOTH ENCRYPTION AND DECRYPTION

    using the same cipher alphabet as above:

    
    Plain alphabet:   ABCDEFGHIJKLMNOPQRSTUVWXYZ
    Cipher alphabet:  XDQTVBKRAUGMZHYWCJOSENILPF
    

    Step 0: Consider the following table, in which each row is the usual English alphabet, shifted left 1 character from the previous line:

    
    ABCDEFGHIJKLMNOPQRSTUVWXYZ
    BCDEFGHIJKLMNOPQRSTUVWXYZA
    CDEFGHIJKLMNOPQRSTUVWXYZAB
    DEFGHIJKLMNOPQRSTUVWXYZABC
    EFGHIJKLMNOPQRSTUVWXYZABCD
    FGHIJKLMNOPQRSTUVWXYZABCDE
    GHIJKLMNOPQRSTUVWXYZABCDEF
    HIJKLMNOPQRSTUVWXYZABCDEFG
    IJKLMNOPQRSTUVWXYZABCDEFGH
    JKLMNOPQRSTUVWXYZABCDEFGHI
    KLMNOPQRSTUVWXYZABCDEFGHIJ
    LMNOPQRSTUVWXYZABCDEFGHIJK
    MNOPQRSTUVWXYZABCDEFGHIJKL
    NOPQRSTUVWXYZABCDEFGHIJKLM
    OPQRSTUVWXYZABCDEFGHIJKLMN
    PQRSTUVWXYZABCDEFGHIJKLMNO
    QRSTUVWXYZABCDEFGHIJKLMNOP
    RSTUVWXYZABCDEFGHIJKLMNOPQ
    STUVWXYZABCDEFGHIJKLMNOPQR
    TUVWXYZABCDEFGHIJKLMNOPQRS
    UVWXYZABCDEFGHIJKLMNOPQRST
    VWXYZABCDEFGHIJKLMNOPQRSTU
    WXYZABCDEFGHIJKLMNOPQRSTUV
    XYZABCDEFGHIJKLMNOPQRSTUVW
    YZABCDEFGHIJKLMNOPQRSTUVWX
    ZABCDEFGHIJKLMNOPQRSTUVWXY
    

    This table can be computed easily, as follows:

    • The first row (row 0) is the regular alphabet.
    • The second row (row 1) is obtained from the first row by replacing each letter in the original by one letter later.
    • The third row (row 2) is obtained from the first row by replacing each letter in the original by two letters later.
    • The third row (row 3) is obtained from the first row by replacing each letter in the original by three letters later.
    • In general, row i is obtained from the first row by replacing each letter by the ith one later.

    For each row, once the letter 'Z' appears, the line continues with 'A', 'B', ... . Effectively, if we listed the letters as having numbers 0 (for 'A'), 1 (for 'B'), ... 25 (for 'Z'), then the ith row is (0+i)%26, (1+1)%26, (2+i)%26, ..., (25+i)%26.

    Step 1: We utilize a "keyword" — in this case, suppose the sender and original receiver agree upon the word, "COMPUTER". We use this keyword to shift successive letters in our original message:

    • For the first character in our message, we use the shift so that 'A' becomes 'C' (the first letter in "COMPUTER"). For our overall message, "THIS LINE TESTS BOTH ENCRYPTION AND DECRYPTION", the first letter 'T' will be encoded using the 'A' to 'C' shift, so that 'T' will become 'V'.
    • For the second character in our message, we use the shift so that 'A' becomes 'O' (the second letter in "COMPUTER"). The second letter, 'H', in our message becomes 'V'.
    • For the third character in our message, we use the shift so that 'A' becomes 'M' (the third letter in "COMPUTER"). The third letter, 'I', in our message becomes 'U'.
    • For the fourth character in our message, we use the shift so that 'A' becomes 'P' (the fourth letter in "COMPUTER"). The third letter, 'I', in our message becomes 'H'.
    • The fifth character in our message is a space. As a non-letter, we leave it as a space.
    • The sixth character in our message is again a letter, so we shift according to the sixth letter in "COMPUTER" — the 'T'. The 'L' in "LINE" becomes an 'E' after the shift.
    • The seventh and eighth characters in our message 'I' and 'N' are shifted according to the 'E' and 'R' rows in "COMPUTER" to yield 'M' and 'E'.
    • To encode the ninth character in our message, we have already used all letters in "COMPUTER" for the shift, so we just start again with the shift for 'A' to 'C'. In this case 'E' becomes 'G'.

    To summarize for this step, each letter in the message is shifted by an amount according to the row that shifts 'A' successively to the letters in our keyword.

    In our example,

    
    THIS LINE TESTS BOTH ENCRYPTION AND DECRYPTION
    

    becomes

    
    VVUH EMEG FTMMW DCFW XRTTMBICHR CBP XXGIADFXIG
    

    Step 2: Once we have the original letters shifted according to our keyword, we code each shifted letter by the cipher alphabet.

    
    Plain alphabet:   ABCDEFGHIJKLMNOPQRSTUVWXYZ
    Cipher alphabet:  XDQTVBKRAUGMZHYWCJOSENILPF
    

    The resulting encrypted message is:

    
    NNER VZVK BSZZI TQBI LJSSZDAQRJ QDW LLKAXTBLAK
    

    Decryption

    To decrypt an encoded message, we follow the steps for encryption in reverse order.

    • We look up each letter in the coded message in the cipher alphabet and replace it with the plain alphabet ("ABCDE...").
    • We shift each letter backward, based on successive letters in the keyword.

    Problem

    Write a program that encrypts a message according to a cipher alphabet and a keyword.

    • The program should read the cipher alphabet and the keyword.
    • The program should read a message on one line. (Messages extending over two or more lines need not be considered for this problem.)
    • The program should encrypt and print the message, according to the polyalphabetic cipher described in this narrative.

    Notes:

    • Although letters (in the alphabets, keyword, and message) may be entered in lower case or upper case, the program should convert all letters to upper case. Thereafter, processing in this problem may assume all letters are upper case.
    • Non-letters should be left alone in the encoding.
    • You may assume the message will not exceed 100 characters.
    • You may assume the cipher alphabet contains only distinct letters.
    • While the description of the shifts of alphabets in Steps 1 and 2 involve a table, it is not necessary to utilize a table. Modular arithmetic on the numbers 0 to 25 (for letters 'A' through 'Z') can reduce the complexity of this problem substantially. Think of the upper case character ch as corresponding to the index ch - 'A'.
    • You are encouraged to store the cipher alphabet in a character array.
    • If one knows the index i of the plain text character, then the corresponding cipher letter is cipherAlphabet[i].
    • The encryption code need not be complicated and lengthy. I packaged encryption of the message into a procedure of less than 25 lines, including procedure header, comments, and lines containing a single left or right brace.

    Extra Credit

    This problem involves primarily encryption. As this problem is being written, its complexity is unclear, and a student could earn 25 of 25 points for a complete and well-tested encryption program.

    Students wishing to extend their work to include decryption would be eligible for up to 10 additional points (for a total of 35 out of 25).

    Reference: A nice treatment of transposition ciphers may be found in Abraham Sinkov, "Elementary Cryptanalysis: A Mathematical Approach", The New Mathematical Library, Random House and the Mathematical Association of America, 1968, Chapter 3. A revised edition of the book is available in Abraham Sinkov and Todd Feil, "Elementary Cryptanalysis Second Edition", The New Mathematical Library, Mathematical Association of America, 2009.

    Problem-specific grading form for Supplemental Problem 3

  1. Word Arrangement/Adjacent Letters

    Many word puzzles and games involve words placed in a 2-dimension grid. For example, consider the following 17 words:

    
    THEORY
    STRING
    ARRAY
    APPLE
    GRINNELL
    COMPUTER
    PHYSICS 
    CALCULUS
    ALGEBRA
    SCHEME 
    NETWORK
    PROGRAM
    NEW
    EQUATION
    MEMORY
    LOGIC 
    SYSTEM
    

    These words might be placed in the following 14 by 21 grid. (In this display, the digits on the left and top help identify the row and column of each letter, but these numbers should not be considered part of the grid.)

    
                Column
                   11111111112 
         012345678901234567890
    Row   
     0       SYSTEM          
     1   COMPUTER            
     2      PROGRAM           
     3   MEMORY NETWORK    E  
     4      STRING   A     Q  
     5       A  L    L     U  
     6       R CO    G     A  
     7    TP R AG    E     TS 
     8    HH A LI    B     IC 
     9    EY Y CC    R     OH  
    10    OS   U     A     NEW
    11   GRINNELL           M 
    12    YC   U            E 
    13     S   S                        
    

    With any arrangement of words, one can count the number of letters immediately adjacent to a position (up, down, left, right, or one square along a diagonal. For the above example, such a count would yield the following table, where each entry is the number of adjacent letters. (Again, row and column numbers are included for reference, but these identifiers can be ignored in the problem that follows.)

    
                Column
                   11111111112 
         012345678901234567890
    Row   
     0   233445543110000000000
     1   123578877420000000000
     2   467787766443321001110
     3   124687877533321002120
     4   234565555435441003230
     5   001446654103230003230
     6   122425443003230003341
     7   233526553003230003442
     8   355626553003230003553
     9   355515442003230003564
    10   466646552002120002453
    11   366424431001110001444
    12   355535441000000000212
    13   132202120000000000111
    

    Write a program that

    • reads the size of a grid (the number of rows m and columns n),
    • reads an m by n grid of characters
    • once read, the program outputs the grid of characters (do not label row numbers or column numbers)
    • computes and prints the grid of counts (do not label row numbers or column numbers)i
    • identifies the two locations with the highest counts

    Notes:

    • Your program may assume that there are at least n characters entered for each row of the grid (more than n characters may be entered on a row, but any extra characters should be ignored.)
    • In the example, any row/column with the count 8 could be identified as having the highest count, and any other row/column with the count 8 could be identified as having the second highest count.
    • If several row/column locations have the same highest or the same second-highest counts, then any row/column with the correct count could be reported.

    Problem-specific grading form for Supplemental Problem 4

  1. Singly-linked-list Processing

    Program namelist.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 end (not the beginning or middle) 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 end of the list.
    • Function removeDuplicates removes duplicates 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 putLast moves a node for a specified name to the end of the list.

      • The function asks the user for a name
      • If the name is found as the last item on the list, a note is printed to confirm this location, but the list is not changed.
      • If the name is found on the list, but the name is not last,
        • the first node with that name is located
        • that node is removed from its current location
        • that node is inserted at the end of the current list

        In this processing no new node is created and no existing node is freed. Rather an existing node is moved.

      • If the name is not found on the list, an error message is printed and the list is not changed.

    Programming Hints:

    • In Program namelist.c, code for addName and print should not be changed in any way.
    • Program namelist.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 cases 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. Insipid Integers

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

    Consider the iteration procedure which begins with a positive number n0, and generates a sequence by the rule:

    nj+1 = sum of the squares of the digits of nj
    Remarks:
    1. If any term in the sequence equals 1, then all successive terms are 1.
    2. If any term in the sequence equals 58, then the sequence cycles:
      ..., 58, 89, 145, 42, 20, 4, 16, 37, 58, 89, ...
    3. It is known that either condition 1 or 2 must occur.
    Definition: An integer n0 is called "insipid" if condition 1 occurs.

    Problem: Find all integers between 1 and 99 which are insipid.

    Programming Notes:

    • In solving this problem you should not use string functions. Rather, consider using C's arithmetic operations for integers, such as / (integer division) and % (integer remainder) to extract the digits of an integer.
    • In organizing your solution, write a function isInsipid, which takes an integer as parameter and which returns true (1) or false (0) as to whether or not the integer is insipid.
    • The main C procedure should call the isInsipid function in checking which of the numbers between 1 and 99 are insipid.
    • Although the definition of an insipid integer involves a sequence, the program need not store all numbers in the sequence. Presumable one would want to store the original number n0. Otherwise, once nj+1 is computed, there is no need to retain the value of nj.
  1. Multiplication of Three-, Four-, or Five-Digit Numbers

    Write a program show-multiplication that reads two integers of three, four, or five digit from the keyboard and then prints their product in the following format:

    
    Enter first number:  749
    Enter second number: 381
    
    
            749
        x   381
        –––––––
            749
          5992
         2247
        –––––––
         285369
    

    As in any long multiplication, there should be a line of intermediate results for each digit of the second number.

  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: 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. 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. City Data

    The file ~walker/151p/labs/lab26.dat contains several items of information about large American cities. More specifically, in ~walker/151p/labs/lab26.dat , each entry consists of the name of the city (line 1), the county or counties (line 2) and the state (line 3) in which it is situated, the year in which it was incorporated (line 4), its population as determined by the census of 1980 (line 5), its area in square kilometers (line 6), an estimate of the number of telephones in the city (line 7), and the number of radio stations (line 8) and television stations (line 9) serving the city. Thus a typical entry reads as follows:

    
    Albuquerque
    Bernalillo
    New Mexico
    1891
    331767
    247
    323935
    14
    5
    
    A blank line follows each entry, including the last.

    Write a procedure which has a filename as parameter and which answers the following questions about the cities represented in the data files.

    1. Which of those cities has the highest population density (population divided by area)?
    2. Which of these cities has over one million telephones?
    3. Which city has the lowest per capita number of radio and television stations (together)?
    The answers to each of these questions should be printed neatly and clearly by the procedure.

  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.