;; MIDTERM SOLUTIONS
;;
;; PROBLEM ONE.
;; FIRST PART.
;;
;; DEFINE FUNCTION (eval-poly p v)
;; Eval polynomial p at value v for x
;;
;; Examples
;; (eval-poly '(1 1 1) 3) -> 13
;; (eval-poly '(2 6) 2) -> 14
;; (eval-poly '(3 5 7) 1) -> 15
;;
;; HINT
;; You can write EVAL-POLY using the structure of the
;; polynomial. But to do so, you need to come up with a mathematical
;; expression relating the polynomial represented by p to the
;; polynomial represented by (cdr p).
(define (eval-poly p x)
(cond [(null? p) 0]
[else (+ (car p) (* x (eval-poly (cdr p) x)))]))
;; SECOND PART.
;;
;; DEFINE FUNCION (add-poly p1 p2)
;; Add two polynomials
;;
;; Examples
;; (add-poly '(3 5 7) '(2 6)) -> '(5 11 7)
;; (add-poly '(2 6) '(3 5 7)) -> '(5 11 7)
;;
;; HINT
;; You can also write add-poly using the structure of the
;; polynomial. Here the "trick" is that the polynomials do not have to
;; be the same length.
(define (add-poly p1 p2)
(cond [(null? p1) p2]
[(null? p2) p1]
[else (cons (+ (car p1) (car p2))
(add-poly (cdr p1) (cdr p2)))]))
;; THIRD PART.
;;
;; DEFINE FUNCTION (diff-poly p)
;;
;; Differentiate polynomial p with respect to its variable x
;;
;; Examples
;; (diff-poly '(3 5 7)) -> '(5 14 0)
;; (diff-poly '(1 0 1 4)) -> '(0 2 12 0)
;;
;; HINT
;; You should again write diff-poly directly using the structure
;; of the polynomial. You will have to rely on the same mathematical
;; view of the polynomial you developed for eval-poly: how does
;; the polynomial represented by p relate to the polynomial
;; represented by (cdr p)? Your answer will then involve the
;; product rule and add-poly.
(define (diff-poly p)
(cond [(null? p) '()]
[else (add-poly (cdr p)
(cons 0 (diff-poly (cdr p))))]))
;; PART FOUR
;; DEFINE FUNCTION (diff-aux p n)
;;
;; Diff-aux returns polynomial r such that
;; derivative of x^n * p is x^(n-1) * r
;;
;; Examples
;; (diff-aux '(0 1 4) 1) -> '(0 2 12)
;; (diff-aux '(1 4) 2) -> '(2 12)
;; (diff-aux '(4) 3) -> '(12)
(define (diff-aux p n)
(cond [(null? p) '()]
[else (cons (* n (car p)) (diff-aux (cdr p) (+ n 1)))]))
;; DEFINE FUNCTION (diff-poly2 p)
;;
;; Differentiate polynomial p,
;; using diff-aux.
;;
;; Examples
;; (diff-poly2 '(3 5 7)) -> '(5 14)
;; (diff-poly2 '(1 0 1 4)) -> '(0 2 12)
(define (diff-poly2 p)
(if (null? p)
'()
(diff-aux (cdr p) 1)))
;; PROBLEM 2
;; PROGRAMS AND XML
(require (lib "ssax.ss" "ssax"))
;; UFO IN A NUTSHELL
;; - moves the spacecraft one parsec forward along the x axis.
;; - moves the spacecraft one parsec back along the x axis.
;; - moves the spacecraft one parsec forward along the y axis.
;; - moves the spacecraft one parsec back along the y axis.
;; - moves the spacecraft one parsec forward along the z axis.
;; - moves the spacecraft one parsec back along the z axis.
;; - instantly returns the spacecraft to the
;; origin, position '(0 0 0).
;; ... - runs the embedded \textbf{UFO}
;; program two times in succession.
;; DEFINE FUNCTION (eval-step step start)
;;
;; return the position that the ufo gets to by carrying out
;; ufo-action step from the position start.
;;
;; HINTS
;; A couple hints: if you use a let to define
;; x, y, and z, your code will be much
;; cleaner. The fact that the step may be
;; twice means that eval-step and the next
;; function, eval-program, will be MUTUALLY
;; RECURSIVE...each will call the other.
(define (eval-step step start)
(let ((act (car step))
(x (list-ref start 0))
(y (list-ref start 1))
(z (list-ref start 2)))
(cond [(eq? act 'east) (list (+ x 1) y z)]
[(eq? act 'west) (list (- x 1) y z)]
[(eq? act 'north) (list x (+ y 1) z)]
[(eq? act 'south) (list x (- y 1) z)]
[(eq? act 'up) (list x y (+ z 1))]
[(eq? act 'down) (list x y (- z 1))]
[(eq? act 'home) (list 0 0 0)]
[(eq? act 'twice)
(eval-program (cdr step)
(eval-program (cdr step) start))]
[else (error "No such instruction")])))
;; DEFINE FUNCTION (eval-program steps start)
;;
;; return the position that the ufo gets to by carrying out
;; each of the steps in the list steps in order, starting from
;; position start.
(define (eval-program steps start)
(cond [(null? steps) start]
[else
(eval-program (cdr steps)
(eval-step (car steps) start))]))
;; DEFINE FUNCTION (eval-ufo struct)
;;
;; If struct is the SXML representation of a UFO file, this function
;; returns the position that the embedded program unit leaves
;; the ufo at, if it starts at the origin.
(define (eval-ufo struct)
(eval-program (cdadr struct) (list 0 0 0)))
;; This is an extra utility function for testing.
(define (eval-file str)
(eval-sxml
(ssax:xml->sxml
(open-input-file str)
'())))
;; PROBLEM 3
;;
;; COMMENT THESE FUNCTIONS
;;
;; HINT
;; Remember: you can test your hypotheses by interacting with Scheme.
;; Here are some places to get started: for what x will
;; (are-all-elts? number? x) be true? for what x will
;; (are-all? list? x) be true?
;; FUNCTION (are-all? pred? here)
;;
;; Say a COMPONENT of a complex list structure is
;; any value nested anywhere inside. To be more
;; precise, we can define a component recursively.
;; Any value is a component of itself. And if L
;; is a list, than any component of an element of L
;; is a component of L.
;;
;; ARE-ALL? takes a boolean function PRED? and a
;; Scheme value HERE as arguments, and
;; returns TRUE if PRED? returns TRUE
;; on all the components of HERE and FALSE otherwise.
;;
;; For example, (are-all? list? here) returns true
;; if all the components of HERE are lists---in other
;; words, if HERE can be written in Scheme using
;; only (nested) parentheses.
(define (are-all? pred? here)
(and (pred? here)
(if (pair? here) (are-all-elts? pred? here) #t)))
;; FUNCTION (are-all-elts? pred? here)
;;
;; This is a helper function for are-all?
;; It takes a boolean function PRED? and a LIST HERE
;; as arguments, and returns TRUE if PRED? is true of
;; all the components of the elements of HERE.
(define (are-all-elts? pred? here)
(if (pair? here)
(and (are-all? pred? (car here))
(are-all-elts? pred? (cdr here)))
#t))
;; FUNCTION
;;
;; Tests if NODE is an acceptable element
;; in a kind of lame definition of a binary
;; tree, where nodes are either numbers (leaves)
;; or internal nodes with a number and two trees
;; as children.
(define (ok-in-tree? node)
(or (number? node)
(and (pair? node)
(= (length node) 3)
(number? (car node)))))
;; FUNCTION (is-binary t)
;;
;; Tests if T is a binary tree,
;; in other words, if T is a list structure
;; all of whose components are valid nodes.
;; Implemented using are-all? and ok-in-tree?
(define (is-binary? t)
(are-all? ok-in-tree? t))