Lecture 4, June 26

The lecture notes I post serve two purposes: to remind you of the topics we discussed and to provide any interesting code examples I did during lecture. I would describe these notes as an outline, not a summary, of what I talked about during lecture. You are not expected to be able to learn the material simply from examining these notes, nor is reading these notes a reasonable substitute for attending lecture.

Code

We spent this lecture practicing with structures.

#lang typed/racket

(require "../include/uchicago151.rkt")

(define-struct Spider
  ([num-legs : Nonnegative-Integer]
   [space-needed : Real]
   [age : Integer]))

(define-struct Elephant
  ([space-needed : Real]
   [age : Integer]))

(define-struct BoaConstrictor
  ([length : Real]
   [girth : Real]
   [age : Integer]))

(define-struct Armadillo
  ([name : String]
   [space-needed : Real]
   [age : Integer]))

(define-type Animal (U Spider Elephant BoaConstrictor Armadillo))

;(define-struct Zoo
;  ([spider-num-legs : Integer]
;   [spider-space-needed : Real]
;   [spider-age : Integer]
;   [elephant-space-needed : Real]
;   ....))

(define-struct Zoo
  ([spider : Spider]
   [elephant : Elephant]
   [boaconstrictor : BoaConstrictor]
   [armadillo : Armadillo]))

;(: template-function (Animal -> ....))
;(define (template-function animal)
;  (cond
;    [(Spider? animal) ...]
;    [(Elephant? animal) ...]
;    [(BoaConstrictor? animal) ...]
;    [(Armadillo? animal ...)]))


(: fits? (Animal Real -> Boolean))
(define (fits? animal volume)
  (cond
    [(Spider? animal) (>= volume (Spider-space-needed animal))]
    [(Elephant? animal) (>= volume (Elephant-space-needed animal))]
    [(BoaConstrictor? animal)
     (>= volume
         (* (BoaConstrictor-length animal)
            (* pi (sqr (/ (BoaConstrictor-girth animal) 2 pi)))))]
    [(Armadillo? animal) (>= volume (Armadillo-space-needed animal))]))

(: update-spider (Spider -> Spider))
(define (update-spider s)
  (make-Spider (Spider-num-legs s)
               (Spider-space-needed s)
               (+ 1 (Spider-age s))))
(: update-elephant (Elephant -> Elephant))
(define (update-elephant e)
  (make-Elephant (Elephant-space-needed e)
                 (+ 1 (Elephant-age e))))
(: update-boaconstrictor (BoaConstrictor -> BoaConstrictor))
(define (update-boaconstrictor b)
  (make-BoaConstrictor (BoaConstrictor-length b)
                       (BoaConstrictor-girth b)
                       (+ 1 (BoaConstrictor-age b))))
(: update-armadillo (Armadillo -> Armadillo))
(define (update-armadillo a)
  (make-Armadillo (Armadillo-name a)
                  (Armadillo-space-needed a)
                  (+ 1 (Armadillo-age a))))

; Example: (update-age (make-Spider 5 12 3))
;       -> (make-Spider 5 12 4)
(: update-age (Animal -> Animal))
; Increases the age of the animal by 1
(define (update-age animal)
  (cond
    [(Spider? animal)
     (update-spider animal)]
    [(Elephant? animal)
     (update-elephant animal)]
    [(BoaConstrictor? animal)
     (update-boaconstrictor animal)]
    [(Armadillo? animal)
     (update-armadillo animal)]))


(: update-all-ages (Zoo -> Zoo))
(define (update-all-ages zoo)
  (make-Zoo
   (update-spider (Zoo-spider zoo))
   (update-elephant (Zoo-elephant zoo))
   (update-boaconstrictor (Zoo-boaconstrictor zoo))
   (update-armadillo (Zoo-armadillo zoo))))

; Define a structure Point for representing a point in a 2D plane
; Points should have a x and a y

(define-struct Point
  ([x : Real]
   [y : Real]))

; Define a function dist that determines the distance between two points
; E.g. (dist (Point 1 2) (Point 4 6)) -> 5

(: dist (Point Point -> Real))
(define (dist p q)
  (sqrt (+ (sqr (- (Point-x p) (Point-x q)))
           (sqr (- (Point-y p) (Point-y q))))))


; Define a function pt-eq? that determines whether two points are equal.
; Two points are equal if and only if they have the same x and the same y

(: pt-eq? (Point Point -> Boolean))
(define (pt-eq? p q)
  (and (= (Point-x p)
          (Point-x q))
       (= (Point-y p)
          (Point-y q))))

; Define a structure Rect for representing rectangles.  Represent rectangles
; with their lower left and upper right corners using the Point structure above

(define-struct Rect
  ([ll : Point]
   [ur : Point]))

; Write a function valid-rect? that determines whether the first point in the
; rectangle is actually the lower left and the second is actually the upper right

(: valid-rect? (Rect -> Boolean))
(define (valid-rect? r)
  (and (> (Point-x (Rect-ur r))
          (Point-x (Rect-ll r)))
       (> (Point-y (Rect-ur r))
          (Point-x (Rect-ll r)))))

; Write a function rect-area that determines the area of a rectangle

(: rect-area (Rect -> Real))
(define (rect-area r)
  (* (- (Point-x (Rect-ur r))
        (Point-x (Rect-ll r)))
     (- (Point-y (Rect-ur r))
        (Point-y (Rect-ll r)))))

; Write a function inside? that determines whether a point lies inside a rectangle

(: inside? (Rect Point -> Boolean))
(define (inside? r p)
  (and (< (Point-x (Rect-ll r)) (Point-x p))
       (< (Point-x p) (Point-x (Rect-ur r)))
       (< (Point-y (Rect-ll r)) (Point-x p))
       (< (Point-y p) (Point-y (Rect-ur r)))))

; Write a function contained? that takes two rectangles as input and determines
; whether the first is entirely contained inside the second.  Hint: check if the
; lower left and upper right corners of the first are inside the second.

(: contained? (Rect Rect -> Boolean))
(define (contained? a b)
  (and (inside? b (Rect-ur a))
       (inside? b (Rect-ll a))))