CS 1321X - Sample Third Quiz

CS 1321X - Sample Third Quiz


This is the third midterm exam that was given to CS1321X students in
Fall 2002.  

CS 1321X
Quiz 3    Fall 2002

There are 100 points possible on this exam.  You have 80 minutes to complete 
it and turn it in.  Put only what you want to be graded on the front sides 
of the pages, and use the back sides of the pages as scratch paper.  If you 
run out of room on the front side of the page, you can put part of your 
answer on the back of that same page, but make sure you note on the front 
of the page that there's stuff to be graded on the back.  And please strive 
for legibility, because we don't give credit for stuff we can't read.  And 
in case you've forgotten, the programming language we use here is Scheme.  


1.  (10 points)  Consider the following two functions:

(define (square-lst lst)
  (cond [(null? lst) ()]
        [else (cons (square (car lst)) 
                    (square-lst (cdr lst)))]))

(define (cube-lst lst)
  (cond [(null? lst) ()]
        [else (cons (cube (car lst))
                    (cube-lst (cdr lst)))]))

Notice that these two functions have a common control structure that guides 
the recursion.  Abstract out this common control structure by writing the 
my-map function  (using Scheme) described in class and in your posted lecture 
notes.  Then redefine square-lst and cube-lst using your newly-created my-map 
function.  (In other words, write three functions:  my-map, square-lst, and 
cube-lst.  The new square-lst and cube-lst functions should have the same 
functionality as their namesakes above, but they should use your new my-map 
function to do the work.)


2.  (10 points)  What's the difference between "pass by value" and "pass by 
reference" parameter passing?  When, and why, does Scheme sometimes look like 
it uses "pass by value" and other times it looks like it uses "pass by 
reference"?


3.  (10 points)  Given a choice between using recursion or traditional 
iteration in some programming task, what do you gain and what do you give 
up when choosing iteration over recursion?  


4.  (10 points)  Describe precisely what the lambda function does.  In your 
description, give a step-by-step explanation how the following code is 
evaluated:

(define square
  (lambda (x) (* x x)))





Below is part of the state space for a ripping good game of hexapawn.  At the 
top is the current state of the game, which shows that white has made an 
opening move by pushing a pawn forward to the center of the board.  The next 
level below that shows all three of black's possible responses, and below 
that you see the moves that white could make in response:

                                            W W -
                                            - - W     current state (after white's opening move)
                                            B B B
                                           /  |  \
                                      /       |       \
                                 /            |            \
                            /                 |                 \
                       /                      |                      \
                  /                           |                           \
             /                                |                                \
        W W -                               W W -                               W W -   black's three
        B - W                               - B W                               - - B   possible moves
        - B B                               B - B                               B - B
        / | \                               /   \                               / | \
      /   |   \                           /       \                           /   |   \
    /     |     \                       /           \                       /     |     \
  /       |       \                   /               \                   /       |       \
W - -   W - -   W W -               - W -           - W -               - W -   W - -   W - -   white's
W - W   B W W   B - -               W B W           - W W               W - B   - W B   - - W   possible
- B B   - B B   - W B               B - B           B - B               B - B   B - B   B - B   replies


_____   _____   _____               _____           _____               _____   _____   _____


Pretend you're a minimaxing, hexapawn-playing Scheme program that is 
controlling the black pawns, and your static board evaluation function is 
as follows:

  The function returns a +10 if the board is such that black wins.  
  It returns a -10 if white wins.  If neither side has won, the 
  function returns the number of black pawns with clear paths in front 
  of them minus the number of white pawns with clear paths in front of 
  them PLUS the result of counting the number of black pawns on the 
  board and subtracting the number of white pawns.  It's the same 
  function that we discussed in class and in the notes.

5a.  (10 points):  Apply your static evaluation function to each of the 
bottom-level boards and write the value that your function would assign 
to each board below that board in the spaces provided in that diagram up 
there.  (There are 8 values to compute.)

5b.  (10 points):  On that same diagram, show which values would be 
propagated upward by your minimax component.  Then clearly indicate which 
move should be made by black, according to the minimax strategy.

5c.  (10 points):  If you generated the state space above in a depth-first, 
left-to-right fashion and applied the static board evaluation function to 
the bottom-level boards as they were generated, you might be able to use 
alpha-beta pruning to reduce some of the work.  If alpha-beta pruning is 
applicable, check here _____ and draw an X through any bottom-level board 
that you wouldn't need to generate.  If alpha-beta pruning is not applicable, 
then check here _____ and explain below or on the back of this page why it 
isn't applicable.


6.  (10 points)  A game called "Last One Loses" is played as follows:  
Two players, A and B, alternate in removing one, two, or three pennies 
from a stack initially containing nine pennies.  The player who picks up 
the last penny loses.  Player A always moves first.  In the space below, 
draw the directed graph representation of the state space (or problem space) 
for Last One Loses.  Then, using this graph representation, show that B can 
always win if bonehead mistakes are avoided.  (You don't need to draw parts 
of the graph that you've already drawn elsewhere; just reuse appropriate 
parts of the graph by drawing pointers from and to the right places.  
This will make more sense after you start drawing, I hope.)


7.  (10 points):  Use your knowledge of Scheme and do to create a function 
called factorial which when given a non-negative integer N, returns the 
factorial of N.  (There are helpful hints about do toward the end of 
this quiz.)


8.  (10 points):  Use your knowledge of Scheme, vectors, and do (and the 
factorial function from the previous problem) to create a function called 
fact-vector which is given a non-negative integer N as a parameter and 
returns a vector of the length N+1 filled with the first N+1 factorial 
values.  (There are helpful hints about do and vectors toward the end 
of this quiz.)  For example:

> (fact-vector 0)
#1(1)
> (fact-vector 1)
#2(1)
> (fact-vector 2)
#3(1 1 2)
> (fact-vector 3)
#4(1 1 2 6)
> (fact-vector 4)
#5(1 1 2 6 24)
> (fact-vector 5)
#6(1 1 2 6 24 120)


Hints on do:

Scheme provides you with one slightly complicated iterative form.
It's just called "do", and it looks like this:


 (do (([var-1] [init-expr-1] [update-expr-1])
      ([var-2] [init-expr-2] [update-expr-2])
                   :
                   :
      ([var-n] [init-expr-n] [update-expr-n]))
     ([test-expr] [action-expr-1] ... [action-expr-m])
                   :
         [zero or more expressions]
                   :
                                )

Here's how "do" works:

1.   each [var-i] is bound to its corresponding [init-expr-i]
     (in "parallel", just like with "let"---that is, there's
     no guarantee of the order the bindings are completed,
     so don't encode dependencies of any kind in this part
     of the "do" form).

2.   [test-expr] is evaluated. If the result is non-#f, then
     the [action-expr-1] through [action-expr-m] are evaluated
     in left-to-right fashion. The "do" form returns the value
     of [action-expr-m] and the iteration is terminated. If
     there are no action expressions, what the "do" form
     returns is unspecified (!).

3.   if evaluating [test-expr] returns #f, then execute the
     body of code.

4.   when the body of code has been executed, update each
     [var-i] by binding it to the value obtained by evaluating
     the corresponding [update-expr-i]. The [update-expr-i]
     are optional, so if it's not there, then the various
     [var-i] are never changed. Also, these bindings are done
     automatically by "do", so there's no need to include your
     own "set!" in the update expressions. Finally, these
     updates, as well as the initializations, are done in
     an unspecified order, so you can't count on any
     dependencies (i.e., this happens before that). You
     can however count on some protection in that Scheme binds
     the variables to fresh locations, does the updates to
     those fresh locations, and then binds the updated values
     to the variable.

5.   go to 2


Hints on vectors:

>  (define x (vector 10 100 90 50 45))

>  x
#5(10 100 90 50 45)

>  (define y (make-vector 6))

>  y
#6(0)

>  (define y (make-vector 6 'foo))

>  y
#6(foo)

>  (vector-ref x 2)
90

>  (vector-length x)
5

>  (vector-set! x 4 65)

>  x
#5(10 100 90 50 65)

>  (vector-set! x 2 '(foo bar))

>  x
#5(10 100 (foo bar) 50 65)

>  (vector-ref x 5)
vector-ref: index 5 out of range [0, 4] for vector: #5(10 100 (foo bar) 50 65)



Copyright (c) 2003 by Kurt Eiselt.  All rights reserved, with 
the exception of stuff that belongs to somebody else.

Last revised: November 11, 2003