;; homework 4 cs 1101 ;; Problem 1 ;; a bid is a struct ;; (make-bid string number) (define-struct bid (name amount)) (define bid1 (make-bid "jane" 1200)) (define bid2 (make-bid "dick" 100)) (define bid3 (make-bid "sally" 50)) ;; an item is a struct ;; (make-item string bid number) (define-struct item (description high-bid hours)) (define CAR (make-item "car" bid1 2)) (define DESK (make-item "desk" bid2 23)) (define BOOK (make-item "rare book" bid3 5)) ;; an auction is a list-of-item ;; a list-of-item is either ;; empty, or ;; (cons item list-of-item) (define AUCTION (cons CAR (cons DESK (cons BOOK empty)))) ;; Problem 2 ;;; bid-template: bid ... -> ... ;;; ... ;(define (bid-template a-bid ...) ; (bid-name a-bid) ; (bid-amount a-bid)) ; ; ;;; item-template: item ... -> ... ;;; ... ;(define (item-template an-item ...) ; (item-description an-item) ; (bid-template (item-high-bid an-item)) ; (item-hours an-item)) ; ; ;;; auction-template: auction ... -> ... ;;; ... ;(define (auction-template an-auction ...) ; (cond [(empty? an-auction) ... ] ; [(cons? an-auction) (item-template (first an-auction)...) ; (auction-template (rest an-auction) ...)])) ;; Problem 3 ;; place-bid: string number item -> item OR false ;; consumes the name of a bidder, the amount he wants to bid, and the item to bid on, and produces ;; either an item or false. If the amount to bid is greater than the current high bid amount, ;; the function produces an item with the new high bid information. ;; Otherwise, the function produces false. (define (place-bid name amount item-wanted) (cond [(bigger-bid? amount (item-high-bid item-wanted)) (make-item (item-description item-wanted) (make-bid name amount) (item-hours item-wanted))] [else false])) ;; test cases (check-expect (place-bid "kelly" 95 CAR) false) (check-expect (place-bid "kelly" 1300 CAR) (make-item "car" (make-bid "kelly" 1300) 2)) (check-expect (place-bid "kelly" 1200 CAR) false) ;; bigger-bid?: number bid -> boolean ;; consumes an amount to bid and a bid. If the amount is greater than the current high bid amount, ;; return true, else false (define (bigger-bid? amt a-bid) (> amt (bid-amount a-bid))) (check-expect (bigger-bid? 1300 bid1) true) (check-expect (bigger-bid? 1200 bid1) false) (check-expect (bigger-bid? 500 bid1) false) ;; Problem 4 ;; total-owed: string auction -> number ;; consumes a person's name and an auction and produces the total amount the person owes for items ;; she has won (define (total-owed name an-auction) (cond [(empty? an-auction) 0] [(cons? an-auction) (+ (amt-of-won-items name (first an-auction)) (total-owed name (rest an-auction)))])) ;; tests (check-expect (total-owed "kelly" AUCTION) 0) ;; kelly has no bids in list (check-expect (total-owed "sally" AUCTION) 0) ;; sally has a bid, but time still left (check-expect (total-owed "sally" (cons CAR (cons DESK (cons BOOK (cons (make-item "chair" (make-bid "sally" 30) 0) (cons (make-item "belt" (make-bid "sally" 10) 0) empty)))))) 40) ;; helper ;; amt-of-won-items: string item -> number ;; consumes a name and an item. If the name matches the name of the high-bidder of the item, ;; and if the number of hours left to bid is 0, the function returns the amount of the bid. ;; Otherwise, the function returns 0. (define (amt-of-won-items name an-item) (cond [(and (string=? name (bid-name (item-high-bid an-item))) (= (item-hours an-item) 0)) (bid-amount (item-high-bid an-item))] [else 0])) ;; test helper (check-expect (amt-of-won-items "kelly" CAR) 0) ;; name doesn't match high bid (check-expect (amt-of-won-items "jane" CAR) 0) ;; name matches high bid, but still time left (check-expect (amt-of-won-items "bill" (make-item "boots" (make-bid "bill" 34) 0)) 34) ;; Problem 5 ;; winning-items: string auction -> auction (list-of-item) ;; consumes the name of a person and an auction and produces a list of all items for ;; which the named person currently has the highest bid (define (winning-items name an-auction) (cond [(empty? an-auction) empty ] [(cons? an-auction) (cond [(bidder-name=? name (first an-auction)) (cons (first an-auction)(winning-items name (rest an-auction)))] [else (winning-items name (rest an-auction))])])) (check-expect (winning-items "kelly" AUCTION) empty) (check-expect (winning-items "jane" AUCTION) (cons CAR empty)) (check-expect (winning-items "jane" (cons CAR (cons DESK (cons BOOK (cons (make-item "jewels" bid1 3) empty))))) (cons CAR (cons (make-item "jewels" bid1 3) empty))) ;; bidder-name=?: string item -> boolean ;; consumes a name and an item and produces true if the name matches the name of the high ;; bidder for the item (define (bidder-name=? name an-item) (string=? name (bid-name (item-high-bid an-item)))) ;; test (check-expect (bidder-name=? "kelly" CAR) false) (check-expect (bidder-name=? "jane" CAR) true) ;; Problem 6 ;; hour-passed: auction -> auction ;; consumes an auction and produces an auction in which the hours left on each biddable item ;; has been decreased by one. If the number of hours left is zero, the number of hours remain ;; at zero (define (hour-passed an-auction) (cond [(empty? an-auction) empty] [(cons? an-auction) (cons (decrease-time (first an-auction)) (hour-passed (rest an-auction)))])) ;; test cases (check-expect (hour-passed empty) empty) ;; an auction with no 0-hours-remaining items (check-expect (hour-passed AUCTION) (cons (make-item "car" bid1 1) (cons (make-item "desk" bid2 22) (cons (make-item "rare book" bid3 4) empty)))) ;; an auction that has an item with 0 hours remaining (check-expect (hour-passed (cons (make-item "car" bid1 1) (cons (make-item "desk" bid2 0) (cons (make-item "rare book" bid3 4) empty)))) (cons (make-item "car" bid1 0) (cons (make-item "desk" bid2 0) (cons (make-item "rare book" bid3 3) empty)))) ;; helper ;; decrease-time: item -> item ;; consumes an item and produces an item with the hour remaining decreased by one. ;; If the hours remaining is zero, it stays at zero (define (decrease-time an-item) (make-item (item-description an-item) (item-high-bid an-item) (cond [(> (item-hours an-item) 0) (- (item-hours an-item) 1)] [else 0]))) ;; tests (check-expect (decrease-time CAR) (make-item "car" bid1 1)) (check-expect (decrease-time (make-item "desk" bid2 0)) (make-item "desk" bid2 0)) ;; Problem 7 ;; bid-cheap-cars: string auction -> auction ;; consumes a name and an auction and produces an auction such that all cars in the auction with high bids of $700 or less are now bid $1000 by the named person (define (bid-cheap-cars name an-auction) (cond [(empty? an-auction) empty ] [(cons? an-auction) (cons (target-item name (first an-auction)) (bid-cheap-cars name (rest an-auction)))])) ;; test cases (check-expect (bid-cheap-cars "kelly" empty) empty) ;; an auction with no cheap cars (check-expect (bid-cheap-cars "kelly" AUCTION) AUCTION) ;; an auction with cheap cars (one below $700, one at $700) (check-expect (bid-cheap-cars "david" (cons (make-item "car" bid1 2) (cons (make-item "car" (make-bid "john" 500) 5) (cons DESK (cons BOOK (cons (make-item "car" (make-bid "terry" 700) 12) empty)))))) (cons (make-item "car" bid1 2) (cons (make-item "car" (make-bid "david" 1000) 5) (cons DESK (cons BOOK (cons (make-item "car" (make-bid "david" 1000) 12) empty)))))) ;; target-item: string item -> item ;; consumes a name and an item and returns an item. If the item is a car with a high bid of $700 or less, the car that's returned has a new high bid of $1000 by the named person. ;; Otherwise the function returns the item unchanged. (define (target-item name an-item) (cond [(and (string=? "car" (item-description an-item)) (cheap-bid? (item-high-bid an-item)) )(make-item "car" (make-bid name 1000) (item-hours an-item))] [else an-item])) ;; tests (check-expect (target-item "dave" CAR) CAR) (check-expect (target-item "dave" DESK) DESK) (check-expect (target-item "dave" (make-item "car" (make-bid "kerry" 300) 12)) (make-item "car" (make-bid "dave" 1000) 12)) ;; cheap-bid?: bid -> boolean ;; consumes a bid and produces true if the amount of the bid is $700 or less (define (cheap-bid? a-bid) (<= (bid-amount a-bid) 700)) (check-expect (cheap-bid? (make-bid "harry" 600)) true) (check-expect (cheap-bid? (make-bid "harry" 700)) true) (check-expect (cheap-bid? (make-bid "harry" 800)) false) ;; Problem 8 ;; expiring-within: auction number -> auction ;; consumes an auction and a number and produces a list of all items that expire within ;; the given number of hours (define (expiring-within an-auction hours) (cond [(empty? an-auction) empty ] [(cons? an-auction) (cond [(item-expiring? (first an-auction) hours) (cons (first an-auction) (expiring-within (rest an-auction) hours))] [else (expiring-within (rest an-auction) hours)])])) (check-expect (expiring-within empty 12) empty) ;; no items expiring (check-expect (expiring-within AUCTION 24) AUCTION) ;; items expiring (below and at boundary condition) (check-expect (expiring-within AUCTION 5) (cons CAR (cons BOOK empty))) ;; item-expiring?: item number -> boolean ;; consumes an item and a number of hours and produces true if the item is expiring within ;; the given number of hours (define (item-expiring? an-item hours) (<= (item-hours an-item) hours)) (check-expect (item-expiring? CAR 5) true) (check-expect (item-expiring? CAR 2) true) (check-expect (item-expiring? CAR 1) false)