## CS 307: Final Exam Study Guide

### Bring your Student ID to the exam.

Hailperin, Ch. 15. Class notes: all.

### Vocabulary:

All terms defined in the back of the class notes.

### Scheme Tutor:

There are some final lessons to help you to prepare for this exam. You should do them, but this should not be turned in and will not be graded.

### Previous Material:

The Final Exam will be comprehensive and will include all material from the two midterm study guides.

### Lisp Topics:

• Lisp representation of data, programs, mathematical expressions, sets.
• Recursion: with a counter, with a test, on a list, on a binary tree. Be sure to review the design patterns for recursive functions.
• Iteration: over lists, vectors. Mapping and iteration functions.
• List structure: be able to translate between box diagrams and parenthesized notation.
• Destructive operations on list structures.

### Lisp Functions:

You should know the following Lisp functions. Be able to give the result for a simple call to each function.

• Arithmetic:
```+      -      *      /     max     min     abs     modulo
gcd    lcm    expt   exp   sqrt    sin     cos     tan
atan   asin   acos   log
```

• Control:
```begin      if           cond       case
do         dotimes      dolist     while
map        for-each     every      some
```

• Special:
```define      let      let*     quote
eval        apply    set!     lambda
```

• List Structure:
```null?       pair?       list?
cons        list        append    reverse
length      memq        memv      member
assq        assv        assoc     list-tail
list-ref    copy-tree   subst     sublis
set-car!    set-cdr!    nconc     nreverse
```

• Sets:
```subset?    intersection    union    set-difference    subset
```

• Predicates and Logical:
```and         or         not        eq?       eqv?      equal?
=           <=         <          <=        >         zero?
positive?   negative?  odd?       even?     number?   integer?
rational?   real?      complex?   boolean?  symbol?
```

• Characters:
```char-alphabetic?    char-numeric?      char-whitespace?   char>?
char-upper-case?    char-lower-case?   char=?             char=?            char-ci=?          char-ci?           char-ci<=?         char-ci>=?         char?
char-upcase         char-downcase      char->integer
integer->char
```

• Strings:
```string?         string=?       string?
string<=?       string>=?      string-ci=?     string-ci?     string-ci<=?   string-ci>=?    string->symbol
string-append   make-string    string-length   string
string-ref      string-set!    string->list    list->string
string-fill!    string-copy    substring       symbol->string
```

• Vectors:
```vector?         make-vector      vector         vector-ref
vector-set!     vector-length    vector->list   list->vector
vector-fill!
```

• Input/Output:
```write                display               newline
open-input-file      close-input-file      input-port?
open-output-file     close-output-file     output-port?
```

### Lisp Programs:

The final exam will require writing several Lisp programs. The following ground rules will apply:

• You may write a single function or multiple functions, as you wish.

• No error checking is required. You may assume that the input is as specified in the problem statement. If a problem requires looking up a value in an association list, you may assume that each needed value is present in the association list.

• Your program must handle the general case, not just the example input. The example is just that: one example of a possible input. An input that is a list may have an arbitrary length; an input that is a tree may be of arbitrary size.

Here are some examples from previous exams:

• Write Scheme function(s) that will translate a Scheme expression into an English phrase. Assume that the expression may contain functions + - * / sin cos; if the expression has two operands, conjoin them with ``and''. Example:
```   (exp->english '(+ (sin x) (cos y)))

==>   (the sum of the sine of x and the cosine of y)
```

• Write a Scheme program to calculate GPA from a list of sublists, (course grade). Grades are letters, with A worth 4 grade points, B 3 grade points, etc. Assume that the list is non-empty and that each course counts the same. Example:
```   (gpa '((cs307 a) (psy301 c)))

==>  3.0
```

• Write a function (pay hours rates) where the data formats are: hours = ((name hours-worked) ...) rates = ((name hourly-wage) ...). For each entry in hours, look up the corresponding hourly wage in the list rates (order is arbitrary), multiply hours worked and hourly wage to get pay, and print name and pay. Example:
```   (pay '((smith 3)) '((jones 4.50) (smith 6.00)))

==>   prints:  smith 18.0
```

• Write function(s) (total items prices) that will compute the total cost of a list of things that are purchased. items is a list of sub-lists, items = ((dept item number) ...) giving the department, name of item, and number of that item that were purchased. prices is a list of item prices by department, prices = ((dept (item price) ...) ...). Example:
```   (total '((clothing jeans 3)
(hardware wrench 2))
'((hardware (saw 9.95) (wrench 4.00))
(clothing (socks 2.50) (jeans 19.95))))
==>   67.85       [remember to multiply by number of items]
```

• Write a function (ngreater tree m) that will return the number of numbers greater than m that appear in the given tree. Example:
```   (ngreater '(+ (* 88 x) (+ 3 7) (/ 17 z))
5)
==>   3
```

• Write a function (deriv e var) that finds the derivative of expression e with respect to a variable var. Assume that the expression e may contain constants (numbers), variables (symbols), and the binary operators + and *. Use these rules, where d/dx is derivative with respect to x:
```   d/dx(x) = 1  (derivative of x with respect to x is one)
d/dx(v) = 0  (derivative of any variable v other than x
with respect to x is zero)
d/dx(c) = 0  (derivative of a constant is zero)
d/dx(u + v) =  d/dx(u) + d/dx(v)
d/dx(u * v) =  u * d/dx(v) + v * d/dx(u)
```
Note that in the last two cases you must make new list structure (a new formula) as the result. Examples:
```   (deriv 'x 'x)         ==>  1
(deriv 'y 'x)         ==>  0
(deriv  5 'x)         ==>  0
(deriv  '(+ x 3) 'x)  ==>  (+ 1 0)
(deriv  '(+ (* x 3) 7) 'x)
==>  (+ (+ (* x 0) (* 3 1)) 0)
```

• Write a recursive function (english code) that will translate Scheme code into English. Assume that the Scheme code can contain expressions using binary operators + - * / = and Scheme functions set! and if. Examples:
```   (english 'x)  ==>  (x)
(english '(+ x 7))  ==>  (the sum of x and 7)
(english '(if (= (+ i j) 3) (set! k 7)))
==>  (if the sum of i and j equals 3 then set k to 7)
```

• Write a function deep-reverse that will reverse not only the top level of a list, but also any sub-lists it may contain, recursively. Example:
```(deep-reverse '(((a b) c) d))  ==>  (d (c (b a)))
```

• The genetic code is carried by DNA molecules. DNA is composed of matched base pairs, where bases are represented by the letters C, G, A, or T. C is always paired with G, and A is always paired with T. We will represent a DNA fragment as a list of the base letters of one side of the DNA helix.

The complement of a DNA sequence is a sequence of the complementary letters (A-T, C-G) of the given sequence. Write a function (complement dna) to compute the complement of a given string. Use auxiliary functions if you wish. Example:

```(complement '(a a a g t g c))  ==>  (t t t c a c g)
```

• A DNA sequence codes for a sequence of amino acids that make up a protein. Each 3 letters of DNA code for one amino acid. Write a function (protein dna codes) to compute the sequence of amino acids specified by a DNA string. Assume (define codes '(((A A A) Phe) ((A T A) Tyr) ((G T G) His)...) gives the 3 DNA bases, followed by an abbreviation of the amino acid for which they code, for all 3-base sequences. Example:
```(protein '(a a a g t g a t a) codes)  =  (Phe His Tyr)
```

• A restriction enzyme is a molecule that will bind to a particular sequence of DNA bases, then cut the DNA at that point. Write a function (restrict dna enzyme) that returns a list of numbered locations at which a given dna string would be cut by a given enzyme. If the enzyme matches the front part of the dna, that would be location 0, etc. Both the dna and the enzyme may be of arbitrary length. Example:
```(restrict '(g t g a a a g t g a t a) '(t g a))  =  (1 7)
-----       -----
0 1 2 3 4 5 6 7 8 9 10
```

• One way to determine a long DNA sequence is to break it into shorter pieces, find the sequences of the pieces, and then re-assemble the pieces based on areas where they overlap with the same codes. Write function(s) (dnamatch one two) to compute the first location at which the back part of list one matches the front part of list two (return #f if no match).
```Example:  (dnamatch '(a a a g t g c) '(t g c g t g))  =  4
0 1 2 3 4 5 6    -----
```
(The sequence t g c matches beginning at position 4.)

• Write a function (combine one two) that will produce a combined DNA list given two lists that match as above. You may use dnamatch in writing this function.
```Example:  (combine '(a a a g t g c)
'(t g c g t g))
=  (a a a g t g c g t g)
```

• Write a function (evalexp expr vals) to interpret (evaluate) an arithmetic expression. expr is an expression that may contain operators + - * /; - may be binary or unary. vals is an association list containing the values of variables. Note: for this problem, you may not use the functions sublis or eval; write an interpreter instead. Example:
```(evalexp '(+ a (* 3 b)) '((a . 7) (b . 8)))  =  31
```

• A holiday mobile is either an ornament or a structure (left ornament right) where left and right are mobiles and ornament is an ornament. The weights of ornaments are given by an association list, weights.
• Write a function (weight mobile weights) to compute the weight of a mobile. Example:
```(weight '((star ball star) star ball)
'((ball . 4) (star . 2)))     =  14
```

• Write a function (balanced mobile weights) to determine whether a mobile is balanced. A mobile is balanced if its left and right parts weigh the same and both of them are balanced. Example:
```(balanced '((star ball star) ball bell)
'((ball . 4) (star . 2) (bell . 8)))   =  #t
```
• Write function(s) (wlt scores) to determine the number of wins, losses, and ties given a list of game scores, each of which is (home-score opponent-score).
```Example:  (wlt '((14 7) (10 10) (21 24) (17 7)))
=  (2 1 1)         [2 wins, 1 loss, 1 tie]
```
• Write a function (evens tree) that returns the product of all the even numbers in tree (which may contain some non-numbers).
```Example:  (evens '(a (2 3 4) (b (5 6))))  =  48
```
• A robot mouse is to find a path through a maze. Each junction in the maze is either #t (the exit from the maze, which is the goal), #f (a wall blocking the mouse), or a list (left center right) of junctions. Write function(s) (mouse maze) to find a path through the maze. A path is a list of directions for the mouse (left, center, or right).
```Example:  (mouse '((#f #f #t) #f (#f #f #f))) = (left right)
```
• A stack machine is a kind of computer CPU that uses a stack for its internal storage. Write function(s) to simulate a stack machine: (sm instructions memory). memory is an association list ((variable value) ...). Use a list called stack, initialized to empty list, for the internal stack. instructions is a list of instructions:
```  (pushn n)  put the number n onto the front of the stack
(pushv v)  put the value of the variable v onto stack
(add)      remove the top two elements from the stack,
add them, and put the result back on the stack
(mul)      multiply (as above)
```
Return the top value on the stack.
```Example:  (sm '((pushv x) (pushn 7) (mul)) '((x 3)))  =  21
```
• Write function(s) (code e) to generate code for the stack machine from an arithmetic expression e using operators + and *. For variables or numbers, generate the appropriate push instruction; otherwise, generate code for operands first, then generate the appropriate operation.
```Example:  (code 'x)  =  ((pushv x))
(code '(+ x 3))  =  ((pushv x) (pushn 3) (add))
(code '(* a (+ b 3)))
=  ((pushv a) (pushv b) (pushn 3) (add) (mul))
```
• Write function(s) (backchain goal rules facts) to try to prove a goal given a set of rules and facts. facts is an association list ((var value) ...) that tells which variables are known to be true or false. rules is a list of rules of the form (conclusion premise1 ... premisen); each rule states that the conclusion is true if all of the premises are true. backchain should work as follows: if the goal is known to be #t or #f based on the list facts, return that value. Otherwise, try rules to see if some rule has the goal as conclusion and has premises that are true (using backchain).
```Example:  (backchain 'a '() '((a #t)))  =  #t
(backchain 'a '((a b)) '((b #t)))  =  #t
(backchain 'a '((a b c) (c d)) '((b #t) (d #t))) = #t
[the rules are "a is true if b and c are true",
"c is true if d is true"]
```
• Write a function (ship order inventory) that creates a shipping list from an order and an inventory. Both order and inventory are lists ((item quantity) ...). Return a list of what was ordered, but without items that do not appear in the inventory list, and limiting the number shipped to the number actually in inventory.
Example:
```(ship '((widgets 2) (gizmos 7) (thingies 14))
'((thingies 12) (widgets 5) (grommets 3)))
=>  ((widgets 2) (thingies 12))
```

• Write a function (limit tree m) that makes a copy of the tree, but replaces any number greater than m by m.
Example:
```           (limit '((9 to (5)) (spirit (of 76))) 7)
=>    ((7 to (5)) (spirit (of 7)))
```

• A secret formula is composed of binary operators and operands in Scheme notation. To protect a secret formula, write a function (encrypt formula keylist) that exchanges the operands of an operator if the element of keylist is a 1 but leaves the order unchanged if it is a 0. The first element of keylist applies to the top level of the formula, etc.
Example:
```          (encrypt '(* (+ (/ a b) c) (- d (+ e f))) '(1 0 1))
=>  (* (- d (+ f e)) (+ (/ b a) c))
```

• Write function(s) (starmatch pattern input) that match a pattern list against an input list. The pattern list may contain a single *, which matches any number of symbols in the input list; the other symbols in the pattern and input lists must be equal. If the pattern matches, return the sublist of symbols that matches the *; otherwise, return #f.
Example:
```          (starmatch '(i feel * today)
'(i feel wild and crazy today))
=>  (wild and crazy)
```

• Write a psychiatrist program (doctor input patterns) that responds to a patient's input using patterns. Use starmatch to find a pattern whose input part matches; if no pattern matches, return '(tell me more). Insert the matching words into the output part of the pattern. To make the output sound correct, you must invert pronouns: replace I with you, my with your, myself with yourself.
Example:
```          (doctor '(i argued with my mother today)
'( ... ((i argued with * today)
(what did * say))...) )
=>  (what did your mother say)
```

• Electric power distribution in Cons City is structured as a binary tree. When lightning causes power outages, the power company collects outage reports into a tree structure (name lhs rhs) where name is a substation and lhs and rhs are subtrees or individual customers. Customers are #f if power is reported to be off, or #t otherwise. The power company wants to find the highest node that has failed and send a repair crew to fix it. A node has failed if both of its subtrees have failed, or if one or both customers below a bottom-level node are without power. Assuming all outages are due to a single substation failure and there are enough outage reports to identify it using the above rules, write a function (failure tree) to return the name of the top failing node, or #f if no failure.
Example:
```  (failure '(a (b #t #t) (d (e #f #f) (f #t #f))))
=>  d
```

• An explorer wishes to retrieve a prize from a cave. A cave is either a number > 0, representing the value of a prize, or a list (dist cave1 ... caven) where dist is the distance to the next junction and cave1 ... caven are the prizes or sub-caves accessible from the junction. The explorer cannot go deeper in the cave than the amount of rope available. Write a program (prize cave rope) that returns the maximum prize that the explorer can obtain.
Example:
```   (prize '(20 (10 5) (20 (10 100) 50) (20 40)) 45)
=>  50
```

• A database relation is a list of field names and values, ((field value) ...). Write an interpreter (check relation test) to evaluate a test for a relation. A test may use binary operators and, or, =, or >, or the unary operator not; the operator = should be interpreted as equal? in Scheme. A symbol within a test has the value of that field in the relation. An item (quote value) within a relation yields the specified value. Note: For this problem, you may not use eval or sublis; write an interpreter instead.
Example:
```     (check '((name john) (age 27) (sex m) (major cs))
'(and (= sex 'm) (> age 21)) )
=>  #t
```

• Write a function (query database test), where database is a list of relations, that returns a list of all relations that satisfy the test. You may use check as above.
Example:
``` (query '(((name john) (sex m))
((name jill) (sex f)))
'(= sex 'f))
=>  (((name jill) (sex f)))
```

### Java Programs:

You should know how to write a simple Java program. Examples:
• Write a Java function to find the average of an array of numbers.
• Assume that an Employee object contains fields for the employee's name, salary, and boss, among other things. The boss field is a reference to the object for the employee's boss, or null for the president of the company. Write a Java function public static long level (Employee e) that determines the level of an employee in the company: the president has level 1, her subordinates have level 2, etc.
• Translate the following Scheme statements into equivalent Java statements:
• (set! x (vector-ref v i))
• (if (> i 7) (set! j (+ j 1)))
• (while (< i 3) (display i) (set! i (1+ i)))
• (dotimes (i 7) (set! sum (+ sum (vector-ref v i))))
• (set! y (* 8 (sin x)))
• (set! x (+ y 2))
• (set! y (* (exp (- x)) (sin x)))
• (dotimes (j 3) (vector-set! v j 0.0))
• (while (< i 7) (set! i (+ i 1)))
• (if (> i 3) (display (vector-ref x i)))