typos
This commit is contained in:
parent
19d6f7a15a
commit
ff701abe7b
206
collects/realm/chapter2/source.rkt
Normal file
206
collects/realm/chapter2/source.rkt
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
#lang racket
|
||||||
|
|
||||||
|
(require rackunit rackunit/text-ui)
|
||||||
|
|
||||||
|
;; Play a Guess my Number game at the REPL.
|
||||||
|
;; Run program.
|
||||||
|
;; Pick a number X between <n> and <m>.
|
||||||
|
;; Evaluate
|
||||||
|
;; (start <n> <m>)
|
||||||
|
;; The program will respond with a number.
|
||||||
|
;; Use
|
||||||
|
;; (bigger)
|
||||||
|
;; and
|
||||||
|
;; (smaller)
|
||||||
|
;; to let it know what you think of the guess.
|
||||||
|
;; Watch how qiuckly the program guesses X.
|
||||||
|
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; ;
|
||||||
|
; ;
|
||||||
|
; ;;; ;;;
|
||||||
|
; ;; ;;
|
||||||
|
; ; ; ; ; ;;;; ;;; ;; ;;;
|
||||||
|
; ; ; ; ; ; ; ; ;; ;
|
||||||
|
; ; ; ; ; ; ; ; ;
|
||||||
|
; ; ; ; ;;;;;; ; ; ;
|
||||||
|
; ; ; ; ; ; ; ;
|
||||||
|
; ; ; ; ;; ; ; ;
|
||||||
|
; ;;; ;;; ;;;; ;; ;;;;;;; ;;; ;;;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
|
||||||
|
;; Example:
|
||||||
|
;; > (start 0 100) ; [0,100]
|
||||||
|
;; 50
|
||||||
|
;; > (bigger) ; [51,100]
|
||||||
|
;; 75
|
||||||
|
;; > (bigger) ; [76,100]
|
||||||
|
;; 88
|
||||||
|
;; > (smaller) ; [76,87]
|
||||||
|
;; 82
|
||||||
|
|
||||||
|
;; Number Number -> Number
|
||||||
|
;; Start a new game in [n,m] and make a guess.
|
||||||
|
;; > (start 0 100)
|
||||||
|
;; 50
|
||||||
|
(define (start n m)
|
||||||
|
(set! lower (min n m))
|
||||||
|
(set! upper (max n m))
|
||||||
|
(guess))
|
||||||
|
|
||||||
|
;; Lower and upper bounds on the number
|
||||||
|
(define lower 1)
|
||||||
|
(define upper 100)
|
||||||
|
|
||||||
|
;; -> Nuber Number
|
||||||
|
;; Guess half-way between lower and upper bounds.
|
||||||
|
;; > (begin (start 0 100) (guess))
|
||||||
|
;; 50
|
||||||
|
(define (guess)
|
||||||
|
(quotient (+ lower upper) 2))
|
||||||
|
|
||||||
|
;; -> Number
|
||||||
|
;; Lower the upper bound and guess again.
|
||||||
|
;; > (begin (start 0 100) (smaller))
|
||||||
|
;; 24
|
||||||
|
(define (smaller)
|
||||||
|
(set! upper (max lower (sub1 (guess))))
|
||||||
|
(guess))
|
||||||
|
|
||||||
|
;; -> Number
|
||||||
|
;; Raise the lower bound and guess again.
|
||||||
|
;; > (begin (start 0 100) (bigger))
|
||||||
|
;; 75
|
||||||
|
(define (bigger)
|
||||||
|
(set! lower (min upper (add1 (guess))))
|
||||||
|
(guess))
|
||||||
|
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; ;;;;;;; ;
|
||||||
|
; ; ; ; ;
|
||||||
|
; ; ; ; ;;; ;;;; ; ;;;;;;; ;;;; ;
|
||||||
|
; ; ; ; ; ; ; ;; ; ; ;;
|
||||||
|
; ; ; ; ; ; ;
|
||||||
|
; ; ;;;;;;; ;;;;; ; ;;;;;
|
||||||
|
; ; ; ; ; ;
|
||||||
|
; ; ; ; ; ; ; ; ; ;
|
||||||
|
; ;;;;; ;;;; ;;;;;; ;;;; ;;;;;;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
(module+ test
|
||||||
|
|
||||||
|
;; basic guesses
|
||||||
|
|
||||||
|
(check-equal? (guess) 50)
|
||||||
|
|
||||||
|
(check-equal? (start 0 100) 50)
|
||||||
|
|
||||||
|
(check-equal? (begin (start 0 100) lower) 0)
|
||||||
|
(check-equal? (begin (start 0 100) upper) 100)
|
||||||
|
(check-equal? (begin (start 0 100) (smaller)) 24)
|
||||||
|
(check-equal? (begin (start 0 000) (smaller)) 0)
|
||||||
|
(check-equal? (begin (start 0 100) (smaller) lower) 0)
|
||||||
|
(check-equal? (begin (start 0 100) (smaller) upper) 49)
|
||||||
|
(check-equal? (begin (start 0 100) (bigger)) 75)
|
||||||
|
(check-equal? (begin (start 0 000) (bigger)) 0)
|
||||||
|
|
||||||
|
;; testing a sequence of interactions with expected intermediate states
|
||||||
|
|
||||||
|
(test-begin (start 0 100)
|
||||||
|
(bigger)
|
||||||
|
(check-equal? lower 51)
|
||||||
|
(check-equal? upper 100)
|
||||||
|
(bigger)
|
||||||
|
(check-equal? lower 76)
|
||||||
|
(check-equal? upper 100)
|
||||||
|
(smaller)
|
||||||
|
(check-equal? lower 76)
|
||||||
|
(check-equal? upper 87))
|
||||||
|
|
||||||
|
;; doing it all over for negative numbers
|
||||||
|
|
||||||
|
(check-equal? (start -100 0) -50)
|
||||||
|
|
||||||
|
(check-equal? (begin (start -100 0) lower) -100)
|
||||||
|
(check-equal? (begin (start -100 0) upper) 0)
|
||||||
|
(check-equal? (begin (start -100 0) (smaller)) -75)
|
||||||
|
(check-equal? (begin (start -100 0) (smaller)) -75)
|
||||||
|
(check-equal? (begin (start -100 0) (smaller) lower) -100)
|
||||||
|
(check-equal? (begin (start -100 0) (smaller) upper) -51)
|
||||||
|
(check-equal? (begin (start -100 0) (bigger)) -24)
|
||||||
|
(check-equal? (begin (start -100 0) (bigger)) -24)
|
||||||
|
|
||||||
|
(test-begin (start -100 0)
|
||||||
|
(bigger)
|
||||||
|
(check-equal? lower -49)
|
||||||
|
(check-equal? upper 0)
|
||||||
|
(bigger)
|
||||||
|
(check-equal? lower -23)
|
||||||
|
(check-equal? upper 0)
|
||||||
|
(smaller)
|
||||||
|
(check-equal? lower -23)
|
||||||
|
(check-equal? upper -12))
|
||||||
|
|
||||||
|
|
||||||
|
;; ---------------------------------------------------------------------------
|
||||||
|
;; testing random properties of our functions
|
||||||
|
|
||||||
|
;; Property:
|
||||||
|
;; For all games starting in [n,m] after any number of moves,
|
||||||
|
;; lower <= upper.
|
||||||
|
(define (prop:ordered n m i)
|
||||||
|
(check-true
|
||||||
|
(begin (start n m)
|
||||||
|
(random-moves i)
|
||||||
|
(<= lower upper))))
|
||||||
|
|
||||||
|
;; Property:
|
||||||
|
;; For all games starting in [n,m], for any number of moves,
|
||||||
|
;; lower grows up, upper grows down, or they are equal.
|
||||||
|
(define (prop:monotonic n m i)
|
||||||
|
(check-true
|
||||||
|
(begin (start n m)
|
||||||
|
(for/and ([i (in-range i)])
|
||||||
|
(define l lower)
|
||||||
|
(define u upper)
|
||||||
|
(random-move)
|
||||||
|
(or (and (< l lower) (= u upper))
|
||||||
|
(and (= l lower) (> u upper))
|
||||||
|
(and (= l lower) (= u upper)))))))
|
||||||
|
|
||||||
|
;; Number -> Void
|
||||||
|
;; Move randomly n times.
|
||||||
|
(define (random-moves i)
|
||||||
|
(unless (zero? i)
|
||||||
|
(random-move)
|
||||||
|
(random-moves (sub1 i))))
|
||||||
|
|
||||||
|
;; -> Void
|
||||||
|
;; Move randomly once.
|
||||||
|
(define (random-move)
|
||||||
|
(if (zero? (random 2))
|
||||||
|
(smaller)
|
||||||
|
(bigger)))
|
||||||
|
|
||||||
|
;; property tests
|
||||||
|
(for ([i (in-range 1000)])
|
||||||
|
(prop:ordered (random 1000) (random 1000) (random 100))
|
||||||
|
(prop:monotonic (random 1000) (random 1000) (random 100)))
|
||||||
|
|
||||||
|
;; reset the boundaries to defaults
|
||||||
|
(start 1 100)
|
||||||
|
|
||||||
|
"all tests run")
|
Loading…
Reference in New Issue
Block a user