CS-105 Homework #2 Solutions

Exercise 5.19


(define (insert-and sent)
  (se (bl sent) 'and (last sent)))


Exercise 5.20

(define (middle-names name)
  (bf (bl name)))


Exercise 5.21

(define (query sent)
  (se (second sent)
      (first sent)
      (bf (bf (bl sent)))
      (word (last sent) '?)))

(define (second sent)
  (first (bf sent)))

Exercise 6.10

(define (sort2 sent)
  (if (<= (first sent) (second sent))
      sent
      (se (second sent) (first sent))))

(define (second sent)
  (first (bf sent)))


Exercise 6.11

(define (valid-date? m d y)
  (cond ((< y 0) #f)
	((has-31-days? m) (within? d 1 31))
	((has-30-days? m) (within? d 1 30))
	((= 2 m) (if (leap-year? y)
		     (within? d 1 29)
		     (within? d 1 28)))
	(else #f)))

(define (has-31-days? m)
  (member? m '(1 3 5 7 8 10 12)))

(define (has-30-days? m)
  (member? m '(4 6 9 11)))

(define (within? num low high)
  (and (<= num high)
       (>= num low)))

(define (leap-year? y)
  (if (divisible? y 100)
      (divisible? y 400)
      (divisible? y 4)))

(define (divisible? num divider)
  (= 0 (remainder num divider)))


Exercise 6.12
Here is a bare-bones version of plural.

(define (plural wd)
  (cond ((ends-in-vowel-and-y? wd) (word wd 's))
	((ends-in? wd 'y) (word (bl wd) 'ies))
	((ends-in? wd 'x) (word wd 'es))
	(else (word wd 's))))

(define (ends-in? wd letter)
  (equal? (last wd) letter))

(define (ends-in-vowel-and-y? wd)
  (and (ends-in? wd 'y)
       (vowel? (last (bl wd)))))

(define (vowel? letter)
  (member? letter '(a e i o u)))


Exercise 6.13

(define (greet name)
  (cond ((equal? name '(stanley livingston)) '(dr livingston i presume?))
	((equal? (first name) 'dr) (if (member? (last name) '(jr sr))
				       (se '(hello dr) (last (bl name)))
				       (se '(hello dr) (last name))))
	((member? (first name) '(queen king)) (se '(hello your majesty)))
	(else (se 'hello (first name)))))


Exercise 6.14
Here is the version that works up to days only. You can extend it all the way up to centuries and beyond.

(define (describe-time secs)
  (cond ((> secs 86400) (se (exact->inexact (/ secs 86400)) 'days))
	((= secs 86400) '(one day))
	((> secs 3600) (se (exact->inexact (/ secs 3600)) 'hours))
	((= secs 3600) '(one hour))
	((> secs 60) (se (exact->inexact (/ secs 60)) 'minutes))
	((= secs 60) '(one minute))
	((> secs 1) (se secs 'seconds))
	((= secs 1) '(one second))
	(else 'huh?)))

The procedure exact->inexact simply converts something like (/ secs 60) from the fractional form to the corresponding (inexact) decimal form. The same can be achieved by writing (/ secs 60.0).
Behfar Bastani-Booshehri
Last modified: Fri Nov 6 11:45:25 CST 1998