Lab 6 - Abstraction and natural number recursion
Purpose In this lab we will practice recognizing similarities in function definitions and in data definitions and how to avoid them. This lab also has some fun with natural number recursion.
- Work in pairs
 - Change roles often!
 - Follow the design recipe for every problem.
 
Abstraction
Sometimes when we solve problems, we find that the solution to one problem
looks a lot like the solution to another one. Check out the following functions
and data definition. From now on we will leave out the definition for lists,
and use the [List-of X] notation.
;; A [List-of Number] is one of ;; -- empty ;; -- (cons Number [List-of Number]) ;; lon-add2 : [List-of Number] -> [List-of Number] ;; Add two (2) to each element of the given list of numbers (define (lon-add2 lon) (cond [(empty? lon) empty] [else (cons (+ (first lon) 2) (lon-add2 (rest lon)))])) ;; lon-add5 : [List-of Number] -> [List-of Number] ;; Add five (5) to each element of the given list of numbers (define (lon-add5 lon) (cond [(empty? lon) empty] [else (cons (+ (first lon) 5) (lon-add5 (rest lon)))]))
Is it clear what each function does? You are hopefully asking "Why would you do that?!" since they are almost exactly the same.
- 
Write a function named 
lon-add-nthat abstracts both of the functions above, taking an extra argument, which is the number to be added to each element. - 
Rewrite both 
lon-add2andlon-add5using your more general function, and write a few tests for each to be sure they work as expected. 
;; A [List-of String] is one of ;; -- empty ;; -- (cons String [List-of String])
- 
Write a function named 
starts-with-catthat consumes a [List-of String] and constructs a list of those strings that start with "cat". - 
Write a function named 
starts-with-dogthat consumes a [List-of String] and constructs a list of those strings that start with "dog". - 
Write a function named 
starts-withthat abstracts both of the functions above, taking an extra argument, which is the substring to be found in each element. - 
Rewrite both 
starts-with-catandstarts-with-dogusing your more general function, and write a few tests for each to be sure they work as expected. 
Recursion over natural numbers
A recursive data structure we use very often in programming is the collection of natural numbers:
;; A Nat (natural number) is one of: ;; - 0 ;; - (add1 Nat) ;; ;; 0 predicate: zero? ;; ;; (add1 n) predicate: positive? ;; (add1 n) accessor: sub1
- 
What is the template for 
Nat? 
In the following exercises we will redefine some built-in arithmetic
functions to get practice writing recursive functions over Nats, so don't simply reuse the built-in functions.
- 
Design a function 
nat-even?that returnstrueif the givenNatis even.You may only use
sub1(and possiblynot). E.g., do not useeven?,odd?,modulo, etc. - 
Design a function 
doublethat doubles the givenNat. Again, you may only useadd1andsub1(anddoubleof course). - 
Design a function 
down-fromthat takes aNatnand returns the list ofNats counting down fromn. For example,(down-from 3) = (list 3 2 1 0). - 
Design a function 
repeatthat takes aNatnand aStringsand returns a list that repeatssntimes. For example,(repeat "buffalo" 8) = (list "buffalo" "buffalo" "buffalo" "buffalo" "buffalo" "buffalo" "buffalo" "buffalo"). Do not usemake-list! (though it's good to know about) - 
Design a function 
nat+that takes twoNats and computes their sum. (Use recursion, not the built-in+function.) - 
Design a function 
nat*that takes twoNats and computes their product. (Again use recursion, not the built-in*function, though you may use yournat+now.) - 
Challenge: Design a function 
sqwarethat squares the givenNat(Note the intended name misspelling!), WITHOUT usingnat*! You may useadd1,sub1,double, andnat+(andsqwareof course). 
Concentric rings in the World
Some basic setup:
(require 2htdp/image) (require 2htdp/universe) (define width 400) (define height 400)In this animation, a
World is a collection of Rings, each of which has a
size and a location.
; A World is a [listof Ring] ; A Ring is a (make-ring Nat Posn) (define-struct ring (size center))
- 
Design a 
grow-ringfunction that increases aRing's size by 1. - 
Design a little 
draw-ringfunction that takes aNatras input and simply returns an image of a circle with radiusr. (We'll make this more interesting later.) - 
Design a 
place-ringfunction that draws aRinginto the givenSceneat theRing's location. (Usedraw-ringhere so that we can modify it later to change the animation.) - 
Design a 
drawfunction that renders aWorldas aSceneby drawing all theRings in their correct locations. - 
Design a 
mousefunction that, when the mouse is clicked, adds a 0-sizeRingto theWorldat the location of the click. - 
Design a 
tickfunction that grows all theRings in theWorldusinggrow-ring. - 
Now let's redesign the 
draw-ring : Nat -> Imagefunction. Instead of making an image of a solid circle, let's make concentric rings of many circles. We can achieve this by overlaying many circles of increasing sizes: Natural number recursion should serve you well here…(overlay
)
=

 
Put it all together and see what you get:
(big-bang empty (on-tick tick .25) (to-draw draw) (on-mouse mouse))