Problem set 11: Generative recursion
This assignment is due on Wednesday, November 20 at 11:59pm. Submit it using Handin as assignment ps11. Corrections can be presented until Friday, December 13.
This problem set builds on the skills that we introduced in Lectures 2−9, 11−19 and 23−25. To encourage you to review those lectures, your grade on this assignment will be capped by your grade on those lectures. You can resubmit lecture exercises at any time.
Remember to follow (and when necessary, adapt) the design recipe for each function. In particular, every type mentioned in a signature must be introduced by a data definition, except for these well-known types: Number, Image, String, Color, Boolean, KeyEvent, MouseEvent, Posn, Anything, NaturalNumber, ListOfNumbers, 1String, [ListOf X], [NEListOf X]. When you write a generative recursive function, you must provide a termination argument. A termination argument must explain why the function eventually stops; it is not enough to say only when the function stops.
1 Generating brackets
In many games (such as basketball, baseball, and euchre), two teams play against each other to see which team wins and which team loses. A tournament for such a game is a competition where many teams play against each other many times until a single team is declared the champion. Before a tournament begins, we usually make a plan that specifies which team plays against which other team at each game. Then, immediately after each game happens, it is common to eliminate the team that lost, so the loser does not play any more games and can no longer be the champion. The winner stays in the tournament and plays more games according to the plan. Eventually, a single team remains that has never lost, and that team is the champion.
Such a plan is called a bracket. In this section, you will design functions to generate a bracket before the tournament and to determine the champion after the tournament.
; A Bracket is one of: ; - Team ; - (make-bracket Bracket Bracket) (define-struct bracket [left right]) ; A Team is String
(define bracket1 (make-bracket "Bucknell" "Michigan St")) (define bracket2 (make-bracket "TCU" (make-bracket "Syracuse" "Arizona St"))) (define bracket3 (make-bracket bracket1 bracket2))
(check-expect (odds teams3) teams1) (check-expect (odds empty ) empty ) (check-expect (evens teams3) teams2) (check-expect (evens empty ) empty )
(check-expect (odds (list "a" "b" "c" "d")) (list "b" "d")) (check-expect (evens (list "a" "b" "c" "d")) (list "a" "c"))
(check-expect (generate-bracket teams3) bracket3)
; An Outcome is one of: ; - Team ; - (make-outcome Outcome Winner Outcome) (define-struct outcome [left winner right]) ; A Winner is one of: ; - "left" ; - "right"
(define outcome3 (make-outcome (make-outcome "Bucknell" "left" "Michigan St") "right" (make-outcome "TCU" "left" (make-outcome "Syracuse" "left" "Arizona St"))))
Hint: Follow the template for processing an Outcome.
(check-expect (fake-outcome bracket3) outcome3)
2 Generating fractals
; A Trip is [ListOf Step] ; A Step is one of: ; - (make-draw Number) ; - (make-turn Number) ; - (make-fork Trip) ; *Interpretation*: angle is how many degrees to turn left (counterclockwise) (define-struct draw [distance]) (define-struct turn [angle]) (define-struct fork [child])
(check-expect (repeat 5 (list (make-draw 25) (make-turn -30))) (list (make-draw 25) (make-turn -30) (make-draw 25) (make-turn -30) (make-draw 25) (make-turn -30) (make-draw 25) (make-turn -30) (make-draw 25) (make-turn -30)))
(check-expect (generate-spiral 64) (list (make-draw 64) (make-turn -30) (make-draw 48) (make-turn -30) (make-draw 36) (make-turn -30) (make-draw 27) (make-turn -30) (make-draw 20.25) (make-turn -30) (make-draw 15.1875) (make-turn -30) (make-draw 11.390625) (make-turn -30) (make-draw 8.54296875) (make-turn -30) (make-draw 6.4072265625) (make-turn -30) (make-draw 4.805419921875) (make-turn -30) (make-draw 3.60406494140625) (make-turn -30) (make-draw 2.7030487060546875) (make-turn -30) (make-draw 2.027286529541015625) (make-turn -30) (make-draw 1.52046489715576171875) (make-turn -30) (make-draw 1.1403486728668212890625) (make-turn -30) (make-draw 0.855261504650115966796875))) (check-expect (generate-spiral 0.6) (list (make-draw 0.6)))
a 1/3-as-big Koch curve,
a 60-degree left turn,
a 1/3-as-big Koch curve,
a 120-degree right turn,
a 1/3-as-big Koch curve,
a 60-degree left turn, and
a 1/3-as-big Koch curve.
(check-expect (generate-koch 0.6) (list (make-draw 0.6))) (check-expect (generate-koch 1.8) (list (make-draw 0.6) (make-turn 60) (make-draw 0.6) (make-turn -120) (make-draw 0.6) (make-turn 60) (make-draw 0.6))) (check-expect (generate-koch 5.4) (list (make-draw 0.6) (make-turn 60) (make-draw 0.6) (make-turn -120) (make-draw 0.6) (make-turn 60) (make-draw 0.6) (make-turn 60) (make-draw 0.6) (make-turn 60) (make-draw 0.6) (make-turn -120) (make-draw 0.6) (make-turn 60) (make-draw 0.6) (make-turn -120) (make-draw 0.6) (make-turn 60) (make-draw 0.6) (make-turn -120) (make-draw 0.6) (make-turn 60) (make-draw 0.6) (make-turn 60) (make-draw 0.6) (make-turn 60) (make-draw 0.6) (make-turn -120) (make-draw 0.6) (make-turn 60) (make-draw 0.6)))
(check-expect (generate-tree 2) (list (make-draw 2) (make-fork (list (make-turn 20) (make-draw 1) (make-fork (list (make-turn 20) (make-draw 0.5))) (make-turn -30) (make-draw 0.75))) (make-turn -30) (make-draw 1.5) (make-fork (list (make-turn 20) (make-draw 0.75))) (make-turn -30) (make-draw 1.125) (make-fork (list (make-turn 20) (make-draw 0.5625))) (make-turn -30) (make-draw 0.84375))) (check-expect (generate-tree 1) (list (make-draw 1) (make-fork (list (make-turn 20) (make-draw 0.5))) (make-turn -30) (make-draw 0.75))) (check-expect (generate-tree 0.6) (list (make-draw 0.6)))
3 Challenge
Make a function that generates this fractal:
Hint: Design two mutually recursive functions, one that generates all the images on the left below, and another that generates all the images on the right below. We’ve colored the lines drawn by the first function in red and by the second function in blue, but you don’t need to do that.