[plt-scheme] Teaching Scheme
That again, more carefully thought-out, with comments,
; door-open? : integer -> boolean
; Tells whether a given door is open at the end of the experiment.
; Since no pass larger than the door number can possibly affect it, we'll only run that many passes.
(define (door-open? door)
(doh? door door))
; doh?, short for door-open-helper : integer integer -> boolean
; First parameter is the number of the door you're interested in.
; Second parameter is the number of the last pass you want to do.
(define (doh? door pass)
(cond [(= pass 0) true] ; on pass 0, make everything open
[(= (remainder door (+ pass 1)) pass) ; if door number is 1 less than a multiple of (pass+1), ...
(not (doh? door (- pass 1)))] ; ... flip it
[else (doh? door (- pass 1))])) ; otherwise don't
; print-doors : list-of-boolean -> output, 1 line per list element
(define (print-doors doors)
(for ((door-num (in-range (length doors)))
(open? doors))
(printf "Door #~a is ~a.~n"
door-num
(if open? "open." "closed."))))
; Note that I've replicated the bug in the C program that prints an extra period on each line.
; print-doors-up-to : integer -> output
(define (print-doors-up-to n)
(print-doors (build-list n door-open?)))
; To print the status of the first 75 doors, type
(print-doors-up-to 75)
; Note that this is the only place that we've mentioned any number other than 0 or 1.
; If the problem were changed to be 300 doors and 300 passes, the C program would
; have to be changed in 4 places (or a symbolic constant would have to be introduced
; with #define ); we can simply call print-doors-up-to with a different argument. Of course,
; one COULD write a C program to take in the number of doors as an argument, but
; depending on the compiler, one might need to use malloc and pointers to get an array
; whose size isn't known until run-time.
; The C code isn't particularly well-structured: I would move the printing code into a separate
; function, so I could compute at one time and print at another without recomputing. I've
; done basically the same thing in Scheme:
(define 400-doors (build-list 400 door-open?))
..
(print-doors 400-doors)
..
(print-doors 400-doors)
Stephen Bloch
sbloch at adelphi.edu