CSC 161 Grinnell College Spring, 2009
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. Problems numbered 8 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

This page will evolve as the semester progresses. I hope to have each supplemental problem finalized at least 1 week before it is due.


In turning in any programs for the course, please follow these directions:
  1. The first six lines of any C program should be comments containing your name, your mailbox number, this course number (161), and an identification of assignment being solved. For example:
         * Henry M. Walker                     *
         * Box Science II                      *
         * Program for CSC 161                 *
         * Assignment for Tuesday, February 10 *
    Also, a comment is needed for every definition of a C function, stating both pre- and post-conditions for that program unit.

  2. Obtain a listing of your program and a record of relevant test runs using the script command:

  3. Either write on your printout or include a separate statement that argues why your program is correct, based upon the evidence from your test runs.

Some Grading Notes:

Making Change:

  1. Write a program that allows the user to enter the cost of an item and the amount paid by the customer, and then prints out the difference (the amount owed to the customer). Also print out how many bills of each denomination should be given to the customer (one-, five-, ten-, and twenty-dollar bills), and the remainder to be paid in coins. Your computation should use the fewest number of bills. [Do NOT try to compute how many of each coin type should be given to the customer (pennies, nickels, dimes, and quarters).]


  1. Write a program to score a bowling game. Scoring details are available from Wikipedia under Ten-pin Bowling

    The program should ask the user to enter the number of pins hit by successive balls, tabulate the score frame-by-frame, and give the final score. In frames when a strike is thrown, the program should not ask for the pins hit by the second ball (as no ball is thrown). Also, if a spare or strike is thrown in the tenth frame, the program should ask for the correct number of bonus balls and compute the final total appropriately.

Emergency Telephones

  1. [This problem is inspired by Problem 3 on the 1985 Advanced Placement Computer Science Examination; folklore now sometimes refers to this exercise as "The Dreaded TelLocs Problem".]

    The arrangement of streets in many midwestern cities resembles a 2-dimensional grid. If emergency telephones are placed at the intersection of streets, then their location can be modeled by a 2-dimensional array:

        #define east_west_size   25
        #define north_south_size 20
        int tel_locs [east_west_size] [north_south_size];

    Within this array, tel_locs[i][j] is 1 if an emergency telephone is located at intersection of streets i and j, and tel_locs[i][j] is 0 otherwise.

    In a certain city, intersection [r][s] is considered "safe" if the [r][s] is within 2 blocks of an emergency telephone — moving north or east. Thus, (ignoring the edge of the array), [r][s] is "safe" if there is an emergency telephone at [r][s], [r+1][s], [r+2][s], [r][s+1], [r][s+2], or [r+1][s+1]. (Due to one-way streets, the notion of "safe" does not consider emergency telephones located to the south or west of intersections.)

    Write a C program that analyzes a proposed placement of emergency telephones in a city to determine if all intersections in the city can be considered "safe". The program should have these characteristics:

    1. The array tel_locs should be declared and initialized as part of the program. (You should not read in the placement of telephones; the program will have to be edited for each proposed telephone placement.)
    2. A function safe should take a location and a tel_locs array as parameters and return 1 or 0 if the location is "safe" or not (respectively).
    3. The program should print the coordinates of any intersection that is not "safe".
    4. The end of the program should indicate "all safe" if all intersections in the city are "safe" or "unsafe intersections exist" if there is at least one intersection that is not "safe".

Reading Test Data

  1. File in directory /home/walker/151s/labs contains information on test results for a certain class. Each line of the file contains a students first and last name and the results of three hour tests. Write a program that computes the average test score for each student, the maximum and the minimum scores for each test, and prints the results in a nicely formatted table. For example, the table might have the following form:
         Name                        Test
    First        Last        1       2       3     Average
    Egbert       Bacon      88      85      92      88.33   
    Maximum                 --      --      --
    Minimum                 --      --      --

Grading Passwords

  1. Since many modern computer systems use passwords as a means to provide protection and security for users, a major issue can be the identification of appropriate passwords. The main point should be to choose passwords that are not easily guessed, but which the user has a chance of remembering. For example, passwords related to birthdays, anniversaries, family names, or common words are all easily guessed and should be avoided.

    Some common guidelines suggest that a password should contain at least 6 characters and include characters from at least three of the following categories:

    Other guidelines indicate that elements of passwords should be pronounceable. One simple measure of this guideline suggests that any group of letters in a password should contain both vowels and consonants.

    This supplemental problem asks you to write and test a procdure

       char gradePassword (char * password)

    that assigns a grade to the given password, as follows:

Dutch National Flag Problem

  1. Write a program to solve the Dutch National Problem, based on two pictorial loop invariants, as described in the lab on Pictorial Loop Invariants, steps 6-9.

Duplicates on a Doubly-Linked List

  1. Modify ~walker/c/lists/namelist.c, by adding an option that will delete duplicate names on a singly-linked list. When duplicate names appear, the first entry on the list should be retained, and all subsequent duplicate entries deleted.

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%.

Unusual Canceling

  1. The fraction 64/16 has the unusual property that its reduced value of 4 may be obtained by "canceling" the 6 in the numerator with that in the denominator. Write a program to find the other fractions whose numerators and denominators are two-digit numbers and whose values remain unchanged after "canceling."

    Of course, some fractions trivially have this property. For example, when numerator and denominator are multiples of 10, such as 20/30, one can always "cancel" the zeroes. Similarly, cancellation is always possible when the numerator and denominator are equal, as in 22/22. Your program should omit these obvious cases.

Roman Numerals

  1. Write a procedure that reads an integer N between 1 and 1000 from the keyboard and prints the Roman numerals between 1 and N in alphabetical order.

    Note: The Bubble Sort is not covered in this course, because it is never considered to be an acceptable algorithm.

Printing Cross Words

  1. Consider the problem of printing two words, the first word vertically (one letter per line) and the second word horizontally, so the words cross at a common letter. For example, if the first word is FUNCTIONAL and the second is SCHEME, then the desired output is:


    In this problem, you are to write a program that reads two words from a terminal window and prints them in the crossed pattern shown above (assuming they have a letter in common). If the words have more than one letter in common, then they may be printed with the crossing at any common letter. If the words have no letters in common, then the program should print an error message.

Dealing Bridge Hands

  1. 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.

Information on the 1997-1998 Iowa Senate

  1. File /home/walker/151s/labs/ia-senate contains information about the members of the 1997-1998 Iowa Senate. After a title line and a blank line, a typical line has the following form:
    Angelo          Jeff        44      Creston           IA 50801
    Kramer          Mary        37      West Des Moines   IA 50265
    Lundby          Mary        26      Marion            IA 52302-0563
    Thus, a typical line gives the last name, the first name, the district number, the town of residence, the state (always IA), and the town's zip code. The information in these lines is arranged in columns.

    Design and write a Scheme program that reads in data from this file and creates two output files, senators-by-district and senators-by-zip-code, in the current working directory. The senators-by-district file should contain the same data as the source file, in the same format, but with the lines arranged by senate district (column 3). The other file, senators-by-zip-code, should contain a list of all senators in the following format

    Jeff Angelo
    Creston, IA 50801
    A blank line should appear after each senator and city address. In this format, the name appears on a first line (first name, then last), and the city, a comma, the state, and zip code is on the next line -- separated by single spaces in the format shown. Note that a variation of this format (with a street address, if available) might be used for a mailing label.

File Analysis

  1. 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.

    In this program, you should count a word as any contiguous sequence of letters, and apostrophes should be ignored. Thus, "word", "sentence", "O'Henry", "government's", and "friends'" should each be considered as one word.

    Also in the program, you should think of a sentence as any sequence of words that ends with a period, exclamation point, or question mark.

    Exception: 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.
    White space, digits, and other punctuation should be ignored.

Parenthesis Checking

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


    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.


    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 Queues with Linked Lints and implemented as lists.

This document is available on the World Wide Web as

created 22 May 2008
last revised 19 March 2009
Valid HTML 4.01! Valid CSS!
For more information, please contact Henry M. Walker at