;; The first three lines of this file were inserted by DrRacket. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-beginner-reader.ss" "lang")((modname 11.5.1) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ())))
; Worked exercise 11.5.1

(define MILES-PER-GALLON #i28)
(define PRICE-PER-GALLON 2.459)
(define MOTEL-PRICE-PER-NIGHT 40)
(define CAR-RENTAL-FIXED-FEE 10)
(define CAR-RENTAL-PER-DAY 29.95)
(define CAR-RENTAL-PER-MILE 0.10)
; gas-needed : number (miles) -> number
(check-within (gas-needed 0) 0 .01)
(check-within (gas-needed 28) 1 .01)
(check-within (gas-needed 56) 2 .01)
(check-within (gas-needed 77) 2.75 .01)
(check-within (gas-needed 358) 12.8 .01) ; actually, this fails because of arithmetic inaccuracy
(check-within (gas-needed 358) 12.8 .02) ; passes

(define (gas-needed miles)
  ; miles a number
  ; MILES-PER-GALLON a number
  (/ miles MILES-PER-GALLON)
  )

; cost-of-gallons : number (gallons) -> number
(check-within (cost-of-gallons 0) 0 .01)
(check-within (cost-of-gallons 1) 2.459 .01)
(check-within (cost-of-gallons 2) 4.918 .01)
(check-within (cost-of-gallons 2.75) 6.76225 .01)
(define (cost-of-gallons gallons)
  ; gallons number
  ; PRICE-PER-GALLON number
  (* gallons PRICE-PER-GALLON)
  )

; gas-cost : number (miles) -> number
(check-within (gas-cost 0) 0 .01)
(check-within (gas-cost 28) 2.459 .01) ; i.e. one gallon
(check-within (gas-cost 56) 4.918 .01) ; i.e. two gallons
(check-within (gas-cost 77) 6.76 .01) ; 2-3/4 gal; use calculator
(check-within (gas-cost 358) 31.44 .01) ; yecch; use calculator
(define (gas-cost miles)
  ; miles number
  (cost-of-gallons (gas-needed miles))
  )

; Assumes the number of days is a positive integer.
(check-expect (nights-in-motel 1) 0)
(check-expect (nights-in-motel 2) 1)
(check-expect (nights-in-motel 38) 37)
(define (nights-in-motel days)
  ; days a number
  (- days 1)
  )

; motel-cost : number (days) -> number
(check-expect (motel-cost 1) 0)
(check-expect (motel-cost 2) 40)
(check-expect (motel-cost 38) 1480)
(define (motel-cost days)
  ; days a number
  ; MOTEL-PRICE-PER-NIGHT a number
  ; (nights-in-motel days) a number
  (* MOTEL-PRICE-PER-NIGHT (nights-in-motel days))
  )

; rental-cost : number (miles) number (days) -> number
(check-expect (rental-cost 0 1) 39.95)
(check-expect (rental-cost 0 2) 69.90)
(check-expect (rental-cost 100 1) 49.95)
(check-expect (rental-cost 100 2) 79.90)
(check-expect (rental-cost 28 1) 42.75)
(check-expect (rental-cost 77 2) 77.60)
(check-expect (rental-cost 358 3) 135.65)
(define (rental-cost miles days)
  ; miles a number
  ; days a number
  ; CAR-RENTAL-FIXED-FEE a number
  ; CAR-RENTAL-PER-DAY a number
  ; CAR-RENTAL-PER-MILE a number
  ; (* days CAR-RENTAL-PER-DAY) a number
  ; (* miles CAR-RENTAL-PER-MILE) a number
  (+ (* days CAR-RENTAL-PER-DAY)
     (* miles CAR-RENTAL-PER-MILE)
     CAR-RENTAL-FIXED-FEE)
  )

; road-trip-cost : number (miles) number (days) -> number
(check-within (road-trip-cost 0 1) 39.95 .01) ; the gas and motels are 0
(check-within (road-trip-cost 0 2) 109.90 .01) ; gas still 0, motel $40
(check-within (road-trip-cost 28 1) 45.209 .01)
; $42.75 for car, $0 for motel, $2.459 for gas
(check-within (road-trip-cost 77 2) 124.36 .01)
; $77.60 for car, c. $6.76 for gas, $40 for motel
(check-within (road-trip-cost 358 3) 247.09 .01)
; $135.65 for car, c. $31.44 for gas, $80 for motel
(define (road-trip-cost miles days)
  ; miles a number
  ; days a number
  ; (gas-cost miles) a number
  ; (motel-cost days) a number
  ; (rental-cost miles days) a number
  (+ (gas-cost miles)
     (motel-cost days)
     (rental-cost miles days))
  )
