HtDP Solution Set | Section 11 |
Problem 1 (Solution): ;; A Nat is a natural number
;sub : Nat Nat -> Number
; subtracts the second number from the first without using -
(define (sub n s)
(cond
[(zero? s) n]
[else (sub1 (sub n (sub1 s)))]))
#| Tests |#
(sub 5 0)
"should be" 5
(sub 6 4)
"should be" 2
(sub 0 7)
"should be" -7
Problem 2 (Solution): #|
A list-of-nat is one of
empty, or
(cons Nat list-of-nat)
|#
;mod-list : Nat Nat -> list-of-nat
; return list of Nat between 0 to N that are not
; evenly divisible by the 2nd number, produces an
; error if the second number is zero
(define (mod-list n d)
(cond
[(zero? d) (error 'mod-list "divisor cannot be zero")]
[else (mod-list-help n d)]))
;mod-list-help : Nat Nat(!= 0) -> list-of-nat
(define (mod-list-help n d)
(cond
[(zero? n) empty]
[else (cond
[(zero? (modulo n d)) (mod-list-help (sub1 n) d)]
[else (cons n (mod-list-help (sub1 n) d))])]))
(mod-list 1 1)
"should be" empty
(mod-list 8 2)
"should be" (cons 7 (cons 5 (cons 3 (cons 1 empty))))
Problem 3 (Solution): #|
A list-of-posn is one of
empty, or
(cons Posn list-of-posn)
|#
; diag2 : Nat -> list-of-posn
(define (diag2 n)
(cond
[(zero? n) empty]
[else (cons (location n) (diag2 (sub1 n)))]))
; Nat -> Posn
; compute location of an object at time t if is at START and moves at VELOCITY
(define (location t)
(add START (mul t VELOCITY)))
; Nat Posn -> Posn
(define (mul t p)
(make-posn (* t (posn-x p)) (* t (posn-y p))))
;add-posns: Posn Posn -> Posn
; return sum of two Posns
(define (add p1 p2)
(make-posn (+ (posn-x p1) (posn-x p2)) (+ (posn-y p1) (posn-y p2))))
(define START (make-posn 0 0))
(define VELOCITY (make-posn 3 4))
#| Tests |#
(add (make-posn 1 1) (make-posn 2 2))
"should be" (make-posn 3 3)
(mul 2 VELOCITY)
"should be" (make-posn 6 8)
(location 0)
"should be" START
(location 1)
"should be" VELOCITY
(location 2)
"should be" (make-posn 6 8)
(diag2 2)
"should be" (cons (make-posn 6 8) (cons (make-posn 3 4) empty))
Problem 4 (Solution): #|
A list-of-sym is one of
empty, or
(cons sym list-of-sym)
A list-of-list-of-sym is one of
empty, or
(cons list-of-sym list-of-list-of-sym)
|#
;bm : Nat Nat sym -> list-of-list-of-sym
; produce a list containing n lists each of which contain m copies of s
(define (bm n m s)
(cond
[(zero? n) empty]
[else (cons (bm-helper m s) (bm (sub1 n) m s))]))
;bl : Nat symbol -> list-of-symbol
; produce a list containing n copies of s
(define (bm-helper n s)
(cond
[(zero? n) empty]
[else (cons s (bm-helper (sub1 n) s))]))
(bm-helper 0 'a) "should be" empty
(bm-helper 1 'a) "should be" (cons 'a empty)
(bm-helper 2 'a) "should be" (cons 'a (cons 'a empty))
(bm 0 0 'a)
"should be" empty
(bm 1 0 'a)
"should be" (cons empty empty)
(bm 0 1 'a)
"should be" empty
(bm 1 1 'a)
"should be" (cons (cons 'a empty) empty)
(bm 2 1 'a)
"should be" (cons (cons 'a empty) (cons (cons 'a empty) empty))
(bm 1 2 'a)
"should be" (cons (cons 'a (cons 'a empty)) empty)
(bm 2 2 'a)
"should be"
(cons (cons 'a (cons 'a empty))
(cons (cons 'a (cons 'a empty))
empty))
Problem 5 (Solution): ; Nat -> true
; draw a balloon n times, with the location depending on n
(define (balloons n)
(cond
[(zero? n) true]
[else (and (clear-balloon n)
(draw-balloon (sub1 n))
(sleep-for-a-while .1)
(balloons (sub1 n)))]))
; Nat -> true
(define (clear-balloon n)
(and (clear-solid-disk (make-posn 100 (* n 5)) RADIUS 'red)
(clear-solid-line (make-posn 100 (+ (* n 5) RADIUS))
(make-posn 100 (+ (* n 5) RADIUS LENGTH))
'black)))
; Nat -> true
(define (draw-balloon n)
(and (draw-solid-disk (make-posn 100 (* n 5)) RADIUS 'red)
(draw-solid-line (make-posn 100 (+ (* n 5) RADIUS))
(make-posn 100 (+ (* n 5) RADIUS LENGTH))
'black)))
(define RADIUS 20)
(define LENGTH 80)
;; Tests
(start 300 300)
(balloons 10)