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.

• Print the program (with your name, etc. at the start, following instruction 1 above).
• Print the results of all appropriate test runs. Write your name in pencil or pen on your output.
• Double check that your program listing corresponds with your output.
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 walker@cs.grinnell.edu 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.
• Omission of any of instruction may yield 0 points for the supplemental problem.
• The versions of the paper copies of the program(s) and output and the electronic copy must match. In particular, if the program(s) could not have produced the output, the matter will be considered academic dishonesty. Thus, by the rules of the college, all evidence must be turned over to the Committee on Academic Standing for investigation.

Deadlines:

• Deadlines for required supplemental problems (1-8) are shown on the online schedule.
• Problems are due at the start of a class (e.g., 9:00 am on Monday, Tuesday, Wednesday, or Friday). Problems submitted after the start of the class are considered late.
• When considering deadlines for an assignment, the submission time will be considered the latter of the time the paper was turned in and the time of the e-mail sent.
• There will be a 25% penalty for each class day a problem is late. Thus, a problem printed or e-mailed at 9:05 am on a Monday will be considered late and subject to a 25% penalty.)
• Supplemental problems numbered 8 or above (available for extra credit) may be submitted any time before 5:00 pm on the last Friday of classes. Submissions after this deadline will not be graded.

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.

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.

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:

• uppercase letters
• lowercase letters
• digits
• punctuation (considered to be anything not a letter or a digit)

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.

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:

• include a horizontal word
• include a vertical word

### Example

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
THEORY
STRING
ARRAY
APPLE
GRINNELL
COMPUTER
PHYSICS
CALCULUS
ALGEBRA
TIGER
SCHEME
NETWORK
PROGRAM
HOUSE
EQUATION
MEMORY
SLEEP
LOGIC
SYSTEM
PIANO
```

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
```
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:

• Columns 1-7 contain an order number
• Columns 8-18 contain the username of the member
• Columns 19-33 contain the name of an item
• Columns 34-44 contain the unit for sales (e.g., pound, quart)
• Columns 45-51 contain the unit price of the item
• Columns 52-62 contain the quantity the member wishes to order
• Columns 63-69 indicate whether the member has paid for the item or not
• Columns 70 and beyond indicate the farmer producing the item

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.

• For each coop member, print the member's name, the total cost of that person's order, and the amount that person has actually paid.
• The coop members should be listed in alphabetical order.
• For each farmer, print the farm's name and the total cost of the orders for that farmer.
• The farms should be listed in alphabetical order.

#### Extra Credit

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

• the member's name
• the name of each item ordered
• the quantity of each item ordered
• the total cost for that item
• the overall cost of the full order
• the amount that person has actually paid
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%.

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;

• 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 DrScheme's random 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. 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.

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

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

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/reviewer-directory.ss 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"
"Algorithms")
("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"
"Architecture")
...
)
)
```

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

```
(load "/home/walker/151s/labs/reviewer-directory.ss")
```

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.

#### Problem

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

• the procedure takes zero or more parameters that contain names of subject areas.
• the procedure returns a list of names of all reviewers that have listed all subject areas identified by the paper.

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.

Notes:

• All numbers should be written as lower-case names.
• The program should be as compact as possible and utilize logic rather than brute force. (For example, a program consisting of 200 printf statements will earn very little credit.)
• The program should run efficiently. (For example, few points will be given for a program utilizing a bubble sort.)
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.

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.

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

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

```http://www.cs.grinnell.edu/~walker/courses/153.sp09/suppl-prob.shtml
```

 created created 5 February 1997 last revised 4 May 2009