;; 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-intermediate-reader.ss" "lang")((modname hw3-solutions) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ()))) ;; Homework 3 ;; CS 1101 C-term 12 ;; Problem 1 ;; an ad is a struct ;; Here's how to make an ad: ;; (make-ad boolean string number number boolean symbol number) (define-struct ad (political? name duration production-cost national? time-of-day repetitions)) ;; a list-of-ad is one of ;; empty ;; (cons ad list-of-ad) ;; examples of data (define Romney (make-ad true "Romney" 60 250000 true 'P 60)) (define Cocopuffs (make-ad false "Coco Puffs" 30 100000 true 'D 15)) (define Warren (make-ad true "Warren" 30 50000 false 'P 50)) (define Jeep (make-ad false "Jeep" 30 300000 true 'P 100)) (define Chamwow (make-ad false "Cham-wow" 15 10000 true 'O 20)) (define all-ads (cons Romney (cons Cocopuffs (cons Warren (cons Jeep (cons Chamwow empty)))))) (define politicos (cons Romney (cons Warren empty))) (define product-ads (cons Cocopuffs (cons Jeep (cons Chamwow empty)))) ;; Problem 2 ;;; ad-template: ad ... -> ... ;;; ... ;(define (ad-template an-ad ...) ; (ad-political? an-ad) ; (ad-name an-ad) ; (ad-duration an-ad) ; (ad-production-cost an-ad) ; (ad-national? an-ad) ; (ad-time-of-day an-ad) ; (ad-repetitions an-ad)) ; ;;; loa-template: list-of-ad ... -> ... ;;; ... ;(define (loa-template aloa ...) ; (cond [(empty? aloa) ] ; [(cons? aloa) (ad-template (first aloa) ...) ; (loa-template (rest aloa) ...)])) ;; Problem 3 ;; count-political-ads: list-of-ad -> number ;; consumes a list of ads and produces the number of ads in the list that are political (define (count-political-ads aloa) (cond [(empty? aloa) 0 ] [(cons? aloa) (cond [(ad-political? (first aloa)) (+ 1 (count-political-ads (rest aloa)))] [else (count-political-ads (rest aloa))])])) ;; test cases (check-expect (count-political-ads all-ads) 2) (check-expect (count-political-ads politicos) 2) (check-expect (count-political-ads product-ads) 0) (check-expect (count-political-ads empty) 0) ;; Problem 4 ;; any-ads-for? : list-of-ad string -> boolean ;; consumes a list of ads and a string representing a product name or politician's name, and produces a boolean. ;; The function returns true if the list contains any ads for the given product or politician. (define (any-ads-for? aloa name) (cond [(empty? aloa) false ] [(cons? aloa) (or (ad-for? (first aloa) name) (any-ads-for? (rest aloa) name))])) ;; ad-for?: ad string -> boolean ;; consumes an ad and the name of a product or politician, and produces true if the ad is for the given product or politician (define (ad-for? an-ad name) (string=? name (ad-name an-ad))) ;; test (check-expect (ad-for? Romney "Romney") true) (check-expect (ad-for? Romney "Chamwow") false) ;; test cases (check-expect (any-ads-for? all-ads "Toyota") false) (check-expect (any-ads-for? all-ads "Warren") true) (check-expect (any-ads-for? empty "Chamwow") false) ;; Problem 5 ;; primetime-ads: list-of-ad -> list-of-ad ;; consumes a list of ads and produces a list of all the ads occurring in primetime (define (primetime-ads aloa) (cond [(empty? aloa) empty] [(cons? aloa) (cond [(primetime-ad? (first aloa)) (cons (first aloa) (primetime-ads (rest aloa)))] [else (primetime-ads (rest aloa))])])) ;; primetime-ad?: ad -> boolean ;; consumes an ad and produces true if the ad is aired in primetime (define (primetime-ad? an-ad) (symbol=? 'P (ad-time-of-day an-ad))) ;; test cases (check-expect (primetime-ad? Romney) true) (check-expect (primetime-ad? Chamwow) false) (check-expect (primetime-ads all-ads) (cons Romney (cons Warren (cons Jeep empty)))) (check-expect (primetime-ads politicos) politicos) (check-expect (primetime-ads (cons Cocopuffs (cons Chamwow empty))) empty) (check-expect (primetime-ads empty) empty) ;; Problem 6 ;; politicians-sponsoring-ads: list-of-ad -> list-of-string ;; consumes a list of ads and produces a list of strings. The list that is produced contains the names of the politicians who have political ads ;; (it's OK if the resulting list contains duplicate names). (define (politicians-sponsoring-ads aloa ) (cond [(empty? aloa) empty ] [(cons? aloa) (cond [(ad-political? (first aloa)) (cons (ad-name (first aloa)) (politicians-sponsoring-ads (rest aloa)))] [else (politicians-sponsoring-ads (rest aloa))])])) ;; test cases (check-expect (politicians-sponsoring-ads all-ads) (cons "Romney" (cons "Warren" empty))) (check-expect (politicians-sponsoring-ads politicos) (cons "Romney" (cons "Warren" empty))) (check-expect (politicians-sponsoring-ads product-ads) empty) (check-expect (politicians-sponsoring-ads empty) empty) ;; Problem 7 (define COST-NATIONAL 100000) (define COST-LOCAL 5000) (define DAY-PERCENT 0.8) (define OFF-PERCENT 0.5) ;; air-cost: ad -> number ;; consumes an ad and produces the cost of airing the ad (define (air-cost an-ad) (* (cond [(symbol=? 'D (ad-time-of-day an-ad)) DAY-PERCENT] [(symbol=? 'O (ad-time-of-day an-ad)) OFF-PERCENT] [else 1.0]) (cond [(ad-national? an-ad) (primetime-cost COST-NATIONAL an-ad)] [else (primetime-cost COST-LOCAL an-ad)]))) ;; test cases (check-expect (air-cost Romney) 12000000) ;; national primetime (check-expect (air-cost Cocopuffs) 1200000) ;; national daytime (check-expect (air-cost Warren) 250000) ;; local primetime (check-expect (air-cost Chamwow) 500000) ;; national off-time (check-expect (air-cost (make-ad false "Alpo" 15 10000 false 'D 20)) 40000 ) ;; local daytime (check-expect (air-cost (make-ad false "Alpo" 15 10000 false 'O 20)) 25000 ) ;; local off-time ;; primetime-cost: number ad -> number ;; consumes the base cost of a 30-second ad, and the ad, ;; and produces the cost the ad in primetime (define (primetime-cost base an-ad) (* base (/ (ad-duration an-ad) 30) (ad-repetitions an-ad))) ;; test cases for helper (check-expect (primetime-cost 100 Romney) 12000) ;; Problem 8 ;; campaign-air-cost: list-of-ad string -> number ;; consumes a list of ads and the name of a politician, and produces the total air-cost of all political ads for that politician. (define (campaign-air-cost aloa name) (cond [(empty? aloa) 0 ] [(cons? aloa) (cond [(political-ad-for-candidate? (first aloa) name) (+ (air-cost (first aloa)) (campaign-air-cost (rest aloa) name))] [else (campaign-air-cost (rest aloa) name)])])) ;; test cases (check-expect (campaign-air-cost all-ads "Warren") 250000) (check-expect (campaign-air-cost empty "Warren") 0) (check-expect (campaign-air-cost all-ads "Brown") 0) ;; political-ad-for-candidate?: ad string -> boolean ;; consumes an ad and the name of a politiciana and returns true if the ad is a political ad for the named politician (define (political-ad-for-candidate? an-ad name) (and (string=? name (ad-name an-ad)) (ad-political? an-ad))) ;; test cases for helper (check-expect (political-ad-for-candidate? Romney "Romney") true) (check-expect (political-ad-for-candidate? Warren "Romney") false) (check-expect (political-ad-for-candidate? (make-ad false "Romney" 60 250000 true 'P 60) "Romney") false) ;; Problem 9 ;; total-ad-cost: ad -> number ;; consumes an ad and produces the total cost of the ad. The total cost is the sum of the cost of producing the ad and the cost of airing the ad. (define (total-ad-cost an-ad) (+ (ad-production-cost an-ad) (air-cost an-ad))) ;; test cases (check-expect (total-ad-cost Romney) 12250000) ;; Problem 10 ;; expensive-ads: list-of-ad number -> list-of-ad ;; consumes a list of ads and a number. The function produces a list of those ads for which the total ad cost exceeds the given number. (define (expensive-ads aloa limit) (cond [(empty? aloa) empty ] [(cons? aloa) (cond [(> (total-ad-cost (first aloa)) limit) (cons (first aloa) (expensive-ads (rest aloa) limit))] [else (expensive-ads (rest aloa) limit)])])) ;; test cases (check-expect (expensive-ads empty 1000) empty) (check-expect (expensive-ads all-ads 500000) (cons Romney (cons Cocopuffs (cons Jeep (cons Chamwow empty))))) (check-expect (expensive-ads all-ads 100) all-ads) (check-expect (expensive-ads all-ads 15000000) empty)