#lang racket
;;;;;;;;;;
;; 2.17 ;;
;;;;;;;;;;
;; I believe it's customary with Racket to use first instead of car and rest
;; instead of cdr.
(define (my-last-pair lst)
(define rest-of-list (rest lst))
(if (empty? rest-of-list)
lst
(my-last-pair rest-of-list)))
(define lst (list 1 2 3 4))
(my-last-pair lst)
;; '(4)
;;;;;;;;;;
;; 2.18 ;;
;;;;;;;;;;
(define (my-reverse lst)
(define (iter old-lst new-lst)
(if (empty? old-lst)
new-lst
(iter (rest old-lst) (cons (first old-lst) new-lst))))
(iter lst empty))
(my-reverse lst)
;; '(4 3 2 1)
;;;;;;;;;;
;; 2.19 ;;
;;;;;;;;;;
(define us-coins (list 50 25 10 5 1))
(define uk-coins (list 100 50 20 10 5 2 1 0.5))
(define (cc amount coin-values)
(cond [(= amount 0) 1]
[(or (< amount 0) (no-more? coin-values)) 0]
[else
(+ (cc amount
(except-first-denomination coin-values))
(cc (- amount
(first-denomination coin-values))
coin-values))]))
(define (first-denomination coin-values)
(first coin-values))
(define (except-first-denomination coin-values)
(rest coin-values))
(define (no-more? coin-values)
(empty? coin-values))
(cc 100 us-coins)
;; 292
(cc 100 (my-reverse us-coins))
;; 292
(cc 100 (shuffle us-coins))
;; 292
;; I don't think re-ordering the list of coin values affects the final answer.
;; The validity of the recursion does not depend on the order of the
;; denominations.
;;;;;;;;;;
;; 2.20 ;;
;;;;;;;;;;
(define (my-filter predicate? items)
(cond [(empty? items) empty]
[(predicate? (first items))
(cons (first items)
(my-filter predicate? (rest items)))]
[else (my-filter predicate? (rest items))]))
(define (same-parity x . ys)
(define (same-parity-as-x? y)
(= (remainder (- x y) 2) 0))
(cons x (my-filter same-parity-as-x? ys)))
(same-parity 1 2 3 4 5 6 7)
;; '(1 3 5 7)
(same-parity 2 3 4 5 6 7)
;; '(2 4 6)
;;;;;;;;;;
;; 2.21 ;;
;;;;;;;;;;
(define (square-list items)
(if (empty? items)
empty
(cons (sqr (first items))
(square-list (rest items)))))
(define (my-map proc items)
(if (empty? items)
empty
(cons (proc (first items))
(my-map proc (rest items)))))
(define (new-square-list items)
(map sqr items))
(square-list (list 1 2 3 4))
;; '(1 4 9 16)
(new-square-list (list 1 2 3 4))
;; '(1 4 9 16)
;;;;;;;;;;
;; 2.22 ;;
;;;;;;;;;;
;; cons'ing up a new list by cdr'ing down an old list processes the elements in
;; last-in-first-out order. So everything is reversed. It's like a stack where
;; cons is the push and car/cdr is the pop.
;; Reversing the arguments does not work because you can't cons a list onto an
;; element.
;;;;;;;;;;
;; 2.23 ;;
;;;;;;;;;;
(define (my-for-each proc items)
(cond [(empty? items) (void)]
[else
(proc (first items))
(my-for-each proc (rest items))]))
(my-for-each displayln (list 57 321 88))
;; 57
;; 321
;; 88
Comments