; Scheme and the Art of Programming
; Chapter 6
; -- Exercise 6.1
; Define a predicate substring? with two parameters, sstr and strng,
; that tests whether the string sstr is a substring of strng.
(define (substring? sstr strng)
(cond
((> (string-length sstr) (string-length strng)) #f)
((string=? sstr (substring strng 0 (string-length sstr))) #t)
(else (substring? sstr (substring strng 1 (string-length strng))))))
(substring? "s a s" "This is a string.")
; Value: #t
(substring? "ringer" "This is a string.")
; Value: #f
(substring? "" "This is a string")
; Value: #t
; -- Exercise 6.2
; Define a procedure string-reverse that takes a string as its
; argument and returns a string that is the given string with
; its characters in reverse order.
(define (substring-ref strng n) (substring strng n (+ n 1)))
(define (string-reverse strng)
(if (= 0 (string-length strng)) ""
(string-append (string-reverse (substring strng 1 (string-length strng)))
(substring-ref strng 0))))
(string-reverse "Jack and Jill")
; Value: "lliJ dna kcaJ"
(string-reverse "mom n dad")
; Value: "dad n mom"
(string-reverse "")
; Value: ""
; -- Exercise 6.3
; Define a predicate palindrome? that tests whether a given
; string is a palindrome.
(define (palindrome? strng) (string=? strng (string-reverse strng)))
(palindrome? "able was I ere I saw elba")
; Value: #t
(palindrome? "mom and dad")
; Value: #f
; -- Exercise 6.4
; An example of the use of implicit begins in cond clauses is below:
(define writeln
(lambda data
(for-each display data)
(newline)))
; Safe recursive programs contain a terminating condition which
; eventually halts the computation. No one has, as yet been
; able to demonstrate that mystery is safe. Nor has a positive
; integer argument been found for which mystery is unsafe.
(define mystery
(lambda (pos-int)
(letrec ((helper
(lambda (n count)
(cond
((= n 1)
(newline)
(writeln "It took " count " steps to get to 1."))
((even? n)
(writeln count ". We divide " n " by 2.")
(helper (/ n 2) (+ count 1)))
((odd? n)
(writeln count ". We multiply " n " by 3 and add 1.")
(helper (+ (* n 3) 1) (+ count 1)))))))
(helper pos-int 0))))
(mystery 9)
; 0. We multiply 9 by 3 and add 1.
; 1. We divide 28 by 2.
; 2. We divide 14 by 2.
; 3. We multiply 7 by 3 and add 1.
; 4. We divide 22 by 2.
; 5. We multiply 11 by 3 and add 1.
; 6. We divide 34 by 2.
; 7. We multiply 17 by 3 and add 1.
; 8. We divide 52 by 2.
; 9. We divide 26 by 2.
;10. We multiply 13 by 3 and add 1.
;11. We divide 40 by 2.
;12. We divide 20 by 2.
;13. We divide 10 by 2.
;14. We multiply 5 by 3 and add 1.
;15. We divide 16 by 2.
;16. We divide 8 by 2.
;17. We divide 4 by 2.
;18. We divide 2 by 2.
; -- Exercise 6.5
; Write an interactive program that prompts for a number
; and then prints out the square and the square root of
; that number.
(define (display-root)
(display "Please enter a number: ")
(let
((number (read)))
(display "Square = ")(display (* number number))(newline)
(display "Square root = ") (display (sqrt number)) (newline)))
; -- Exercise 6.6
; Write a program that prompts for an amount of money, and
; tells the user how this amount is made up of 100 dollar,
; 20 dollar, 10 dollar and 1 dollar bills and of quarters,
; dimes, nickels, and pennies.
(define (display-change)
(display "For what amount do you want change? $")
(let
((money (read)))
(letrec
((hundreds (floor (/ money 100)))
(twenties (floor (/ (- money (* hundreds 100)) 20)))
(tens (floor (/ (- money (+ (* hundreds 100) (* twenties 20))) 10)))
(ones (remainder money 10)))
(display "Hundreds: ") (display hundreds) (newline)
(display "Twenties: ") (display twenties) (newline)
(display "Tens: ") (display tens) (newline)
(display "Ones: ") (display ones) (newline))))
; -- Exercise 6.7
; A Reverand Zeller developed a formula to compute the day
; of the week for any given day of the Gregorian Calendar.
; The input to the algorithm is specified in the following
; manner:
; m is the month of the year, with March as m = 1. January
; and February are months 11 and 12 of the previous year.
; d is the day of the month.
; y is the year of the century.
; c is the previous century.
(define (day-of-week m d y c)
(letrec
((A (floor (/ (- (* 13 m) 1) 5)))
(B (floor (/ y 4)))
(C (floor (/ c 4)))
(D (- (+ A B C d y) (* 2 c)))
(R (remainder (/ D 7))))
(cond
((= R 1) (display "Monday"))
((= R 2) (display "Tuesday"))
((= R 3) (display "Wednesday"))
((= R 4) (display "Thursday"))
((= R 5) (display "Friday"))
((= R 6) (display "Saturday"))
((= R 7) (display "Sunday")))))