#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