CSC 153 Grinnell College Spring, 2009
Computer Science Fundamentals

Supplemental Problems

This page will evolve as the semester progresses.

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

Supplemental Problems extend the range of problems considered in the course and help sharpen problem-solving skills. Problems numbered 9 or higher may be turned in for extra credit.

Format: In turning in solutions to supplemental problems, follow these directions:

  1. The first three lines of any Scheme or C program should be comments containing your name, your mailbox number, and an identification of assignment being solved. The following lines illustrate this format for Scheme programs.:

       ;;; Henry M. Walker
       ;;; Box:  Science Office
       ;;; Supplemental Problem 0
  2. Comments are required for every procedure, stating in English what that procedure is supposed to do. The following header illustrates an appropriate format for the square root function:

    (define square-root 
       (lambda (number)
       ;;;  pre-condition:  number is a non-negative real number
       ;;; post-condition:  procedure returns the non-negative
       ;;;                  square root of the number parameter
  3. Both the Dr. Scheme and C programming environments provide a mechanism to print a program and to print output from separate windows.

  4. In pen or pencil, annotate your output, so that it is clear what test data produced each result.

  5. For each result, write (in pen or pencil) whether or not the output is correct and how you know. Your argument should be based upon the evidence from the problem (not a tracing of the program).

  6. Include a statement (typewritten, in pencil, or in pen) indicating why your testing covers a reasonable range of cases. That is, explain why your testing allows you to conclude that your program is correct. (If this program were written for a company, your argument should provide adequate proof that you should be paid for your work, based on the problem assigned.)

  7. In addition to turning in your program in paper form, e-mail your program file(s) to The subject line of your e-mail should be:

    CSC 153 Supplemental Problem [number]
    where [number] is the problem number.
Note: It is essential that each supplemental problem follows the specified directions.


Counting List Items by Type
  1. Write a procedure count-by-categories that takes a Scheme expression as its only parameter and that returns a list containing the number of numbers, symbols, and strings in the expression. The expression might be a single atom, a list of atoms, or a list of items that can be atoms or arbitrary lists.

    Some examples follow:

    (count-by-categories '())   ==> (0 0 0) ; 0 numbers, 0 symbols, 0 strings
    (count-by-categories 5)     ==> (1 0 0) ; 1 number , 0 symbols, 0 strings
    (count-by-categories 'a)    ==> (0 1 0) ; 0 numbers, 1 symbol,  0 strings
    (count-by-categories "str") ==> (0 0 1) ; 0 numbers, 0 symbols, 1 string
    (count-by-categories '(5 a b "str" 45) ==> (2 2 1) ; 2 numbers, 2 symbols, 1 string
    (count-by-categories '(5 a (b "str") ((45)))) ==> (2 2 1) ; 2 numbers, 2 symbols, 1 string
    (count-by-categories '(all x (if (human x) (mortal x))))    ==> (0 7 0) ; 0 numbers, 7 symbols, 0 strings

    In implementing this solution, all processing should be tail recursive.

Family Size Simulation

  1. [Derived from Henry M. Walker, Introduction to Computing and Computer Science with Pascal, Little, Brown, and Company, 1986, Section 7.1.]

    A couple decided that they want to raise at least one boy and one girl. They decide to keep having children until they have one child of each gender, and they stop having children. Assume that having a boy or girl is equally likely, and assume that the gender of one child has no influence on the gender of the next. The following steps help investigate how many children such a couple might expect to have.

    We base our investigation on a simulation, using a random number generator available in Dr. Scheme. In particular, the function (random) returns random numbers between 0 and 1. In our simulation, consider the test

       (< (random) 0.5)

    If this test is true, we consider a child to be a boy; if the test is false, we consider the child to be a girl.

    1. Write a procedure couple that requires no parameter and that returns the number of children a couple has in order to have one child of each gender. That is, processing starts with no children, successively adds a child of a random gender, and continues until the couple has at least one child of each gender. (You may want a husk procedure to start the process and also a kernel procedure for computing successive children.)

    2. Write a procedure couple-list that takes a parameter n and produces a list that shows the number of children in a simulation of n couples.

    3. Write a procedure couple-summary that takes a parameter n and computes the number of children for n couples and returns a list with the maximum, minimum, and average number of children for those n couples.

Generating 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 randomly create a password, taking advantage of Scheme's higher-order procedures:

    1. Write a procedure generate-char-template that provides a template for picking a character at random from a given string. The template takes a string as parameter and returns a procedure. This resulting procedure takes no parameters, but returns a random character from the template's original string as a result. Several examples follow:

      (define generate-lowercase-vowel (generate-char-template "aeiou"))
      (define generate-digit (generate-char-template "0123456789"))
      (define generate-uppercase-letter (generate-char-template "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
      (generate-lowercase-vowel)  ==> #\o
      (generate-lowercase-vowel)  ==> #\a
      (generate-lowercase-vowel)  ==> #\u
      (generate-digit)            ==> #\2
      (generate-digit)            ==> #\7
      (generate-uppercase-letter) ==> #\Q
      (generate-uppercase-letter) ==> #\B
      (generate-uppercase-letter) ==> #\Q

      Note: generate-char-template must work exclusively with strings and/or characters; no lists are allowed here.

    2. Use generate-char-template to define these procedures:

      • generate-vowel, a procedure that returns a random vowel (upper case or lower case)
      • generate-consonant, a procedure that returns a random consonant (upper case or lower case)
      • generate-digit as illustrated above
      • generate-punc, a procedure that returns a punctuation character at random, drawing from at least the characters :!,.*&^%$#@-+?><
    3. Write a higher-order procedure generate-elt that takes any number of procedures as parameters and returns a template for using those procedures to generate a string. Several examples follow:

      (define generate-syllable (generate-elt generate-consonant generate-vowel generate-consonant)
      (define generate-two-digits (generate-elt generate-digit generate-digit)
      (generate-syllable)   ==>  "BeD"
      (generate-syllable)   ==>  "cAR"
      (generate-syllable)   ==>  "QoJ"
      (generate-syllable)   ==>  "QUT"
      (generate-two-digits) ==>  "31"
      (generate-two-digits) ==>  "41"
      (generate-two-digits) ==>  "59"
    4. Write a higher-order procedure generate-pass-template that takes any number of procedures as parameters and returns a procedure to generate passwords from those parameter procedures. Several examples follow:

      (define gen-password (generate-pass-template generate-syllable generate-two-digits generate-punc generate-syllable)
      (gen-password)    ==> BeD31;Car
      (gen-password)    ==> QoJ41!QUT

      Note that the output of gen-password yields good choices for passwords. The passwords contain a range of letters, digits, and punctuation; the letters are arranged consonant-vowel-consonant (and thus are generally pronounceable); and all characters are chosen at random.

Accumulating Sequences
Parts of this problem are inspired by related assignments from my colleague, John Stone.

  1. Given a list of numbers, we can construct a new list, in which the ith number on the new list is the sum of the first i numbers on the original list. The resulting list is called a cumulative sequence for the original list. For example, given the sequence of square numbers,

        0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, ...,

    the corresponding sequence of cumulative totals:

        0, 1, 5, 14, 30, 55, 91, 140, 204, 285, 385, ... .

    This problem involves computing cumulative sequences, based on a variety of initial lists.

    1. Write a procedure cumulative-sequence that takes a list as parameter and that returns the corresponding sequence of cumulative totals.

    2. Write a higher-order procedure list-transform-template that takes a unary procedure proc and an integer starting-index as a parameters and that returns a unary procedure. The resulting procedure takes a list lst as its parameter and returns a new list, in which proc is applied to every element of lst, beginning at the starting-index. Elements of lst are retained unchanged on this resulting list. Here are a few examples:

      (define square-transform (list-transform-template square 0))
      (define square3-transform (list-transform-template square 3))
      (define odd-transform (list-transform-template odd? 4))
      (square-transform '(1 2 3 4 5 6 7 8 9 10))
           ==> (1 4 9 16 25 36 49 64 81 100)
      (square3-transform '(1 2 3 4 5 6 7 8 9 10))
           ==> (1 2 3 16 25 36 49 64 81 100)  ; apply square starting with 4 (in indexed position 3)
      (odd-transform '(1 2 3 4 5 6 7 8 9 10))
           ==> (1 2 3 4 #t #f #t #f #t #f)
    3. Write a higher-order procedure cumulative-trans-template that takes a unary procedure proc and an integer starting-index as a parameters and that returns a unary procedure. The resulting procedure takes a list lst as its parameter and returns a new list of cumulative sums:

      • Before the starting-index, cumulative sums are computed as above.
      • After the starting-index, proc is applied to each lst element before the term is added. Here are a few examples:
      (define cumulative-square-transform (cumulative-trans-template square 0))
      (define cumulative3-square-transform (cumulative-trans-template square 3))
      (define cumulative-odd-transform (cumulative-trans-template odd? 4))
      (cumulative-square-transform '(1 2 3 4 5 6 7 8 9 10))
           ==> (1 5 14 30 55 91 140 204 285 385)
      (cumulative-square3-transform '(1 2 3 4 5 6 7 8 9 10))
           ==> (1 3 6 22 47 83 132 196 277 377)  ; apply square starting with 4 (in index location 3)
      (cumulative-odd-transform '(1 2 3 4 5 6 7 8 9 10))
           ==> error ; results of odd? not numbers that can be added

    Try to make each procedure in this problem run as efficiently as possible.

Word-Find Puzzle

  1. This exercise is based on a programming problem by Marge Coahran.

    This problem asks you to write a program that solves a "word-find" puzzle similar to puzzles that can be found in newspapers and magazines. An example is given below.

    The input data for your program will be a 16 x 16 grid of characters (the puzzle board) followed by a list of words. The object of the puzzle is to search the puzzle board for the words in the word list. Words may appear in the puzzle board horizontally or vertically (but not diagonally). Horizontal words will run left to right; vertical words will run top to bottom. Words will not "wrap around" in either direction, so for example, a word could not occupy columns {15,16,1,2}. Each word will appear at most once in the puzzle board.

    An example data file is available at ~walker/153/problems/puzzleboard for your use, but your program should work on any input file that conforms to the following specifications.

    Puzzle Specifications

    The puzzle board will be given first. It will consist of a matrix of 16 x 16 upper-case letters, with a single space between each character on each row. Next the file will contain a list of upper-case words, each on a separate line, and each of which could fit within the puzzle board. The number of words is not specified, so your program should read until the end of the file is reached. There will be no blank lines anywhere in the file.

    Your program may either read the data using input re-direction or open a file for input. In either case, please do not print input prompts in your program.

    Your program should output a "key" to the word-find puzzle as shown in the example below. Essentially, the key is a copy of the puzzle board matrix that contains only the words which your program has found. All other characters of the board should be removed.

    Anti-hint: There are C library functions called strstr(), strchr(), and strrchr(), which you are NOT ALLOWED to use in this program. These functions would take away too much of your fun.

    Test Cases

    As part of your write up, please describe a set of cases that would be appropriate for testing this program. (Since designing these puzzles is non-trivial, you need not submit a puzzle of your own containing your tests, but describe what situations you would want to test.) It would also be wise of you to modify the example below if there are test cases missing from it, to allow you to thoroughly test your code.

    An (overly-simplified) list of test cases might look something like this:


    Consider the input:

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

    When given this input, the program should print:

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

Food Coop Ordering

  1. The Grinnell Food Coop facilitates member-farmer purchasing of produce. Farmers identify agricultural good that they can supply. Approximately each month, coop member place orders for those items, and the coop coordinates payment and delivery. Behind-the-scenes record keeping for orders id accomplished via an online system. This problem illustrates a few of the capabilities of this system. (Actual processing in this Web-based system is assisted by a data-driven system called a database, and details of databases are beyond the scope of this course. The purpose of this exercise is to highlight elements of common computing applications.)

    Order Table

    Central to the food-coop system is a collection of tables that contain information on farm produce and member orders. A simplified table of this information is available at ~walker/153/problems/food-order.

    In this file, the first line provides column titles; each subsequent line indicates details of a member's order. Within an order, the line is organized as follows:

    Write a C program that reads table data using input re-direction or open a file for input. (In either case, please do not print input prompts in your program.) The C program then should create totals for both coop members and farmers.

    Extra Credit

    Prepare an itemized bill for each coop member. That is, for each member, show

Doubly-Linked Lists

  1. Modify your program from the lab on doubly-linked-list to include two additional options:

    1. An option to sort the names on the list into ascending alphabetical order.

      Your sorting procedure should use an insertion sort that moves nodes. The sorting procedure may not deallocate space or allocate space for nodes, and names may not be copied from one node to another (even through an intermediate character array).

    2. An option to delete duplicates from the list, assuming the list is ordered.

      This procedure should use an iterative solution, with no more than 3 temporary pointers (including function parameters).

      This procedure should use a husk-and-kernel approach, in which the kernel is recursive. Other than parameters, the husk may have no local variables, and the kernel may have at most one local variable.

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

Simulation of Hi Ho! Cherry-O

  1. 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 a bird or 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 bird or dog and the number of cherries on the tree is 9 or 10, then the number of cherries on the tree goes to 10 (not higher).

    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 Scheme procedures;

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

Closest Contemporaries

  1. This problem involves two Scheme procedures:

    1. Write procedure closest-contemporary, as described in an exercise on closest contemporaries by John Stone.

    2. Write a procedure closet-contemp-template that takes a list of people as parameter and returns a unary procedure. The original list serves as the reference data involving triples (e.g., authors, birth dates, and years of death). The resulting unary procedure asks for an author/birth-year/death-year list as parameter and returns the closest contemporary of the parameter author appearing on the reference list.

      For example, suppose list-of-authors is defined as indicated in the "exercise #2" reference given above in Mr. Stone's exercise. Then the following sequences generates the result shown:

      (define example-contemp (closet-contemp-template list-of-authors))
      (example-contemp '("Bacon" 1561 1626)) ==> "Shakespeare"

    As with any procedure(s), you should include testing to show that your procedures work appropriately.

Determining the day of the week

  1. Write Scheme procedure day-of-the-week, as described in an exercise on determining the day of the week by John Stone.

Arithmetic Expressions

  1. Write two Scheme procedures, arithmetic-formula? and value-of-arithmetic-formula, as described in an exercise on arithmetic formulae by John Stone.

Conference Reviewers

  1. For many professional conferences, authors submit papers on their research. These papers are then sent to reviewers for comments, and the best papers are selected for presentation. A similar process is used for determining papers to appear in journals. This problem considers how reviewers might be selected.

    For a computer-related conference, organizers maintain a database of reviewers, together with a list of the subject areas these reviewers feel competent to judge. One possible structure for this database is a list of lists. File /home/walker/151s/labs/ defines Scheme variable directory that contains a fictitious version of such a database. The first part of this list of lists is:

    (define directory
     '(("Terry Clark" "Networks" "Distributed Systems" "Distributed Systems")
       ("Carol Walker" "Cryptography" "Software Design" "Multimedia"
       ("John McClelland" "Software Design" "Distributed Systems" "Networks"
             "Ethical/Social Issues" "Theory of Computation" "Algorithms")
       ("Lisa Dale" "Networks" "Distributed Systems" "Theory of Computation"
              "Ethical/Social Issues")
       ("Arnold Freeman" "Operating Systems" "Databases" "Networks"
              "Distributed Systems" "Architecture")
       ("Terry Barnes" "Networks" "Artificial Intelligence" "Cryptography"

    This entire list of lists may be loaded within a Scheme program with the statement:

    (load "/home/walker/151s/labs/")

    When a paper is submitted to the conference, the author specifies several related subject areas. In order to facilitate reviewing, the conference organizers wish to find reviewers whose expertise as many of the author-designated subject areas as possible.


    Define a Scheme procedure find-all-reviewers with the following properties

    To be on the resulting list of reviewers, an individual may have many interests beyond those indicated for the paper — as long as the paper's topics are all covered.

  1. Write a C program that generates the names of the numbers from zero to two hundred and prints them in alphabetical order.


File Analysis

  1. Write a procedure file-analysis that takes the name of a file as its 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.

A C Version of Scheme's MAP Procedure

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


    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.

This document is available on the World Wide Web as

created created 5 February 1997
last revised 4 May 2009
Valid HTML 4.01! Valid CSS!