diff --git a/ex-2-30.rkt b/ex-2-30.rkt index 0f793ba..67ba3c2 100644 --- a/ex-2-30.rkt +++ b/ex-2-30.rkt @@ -52,10 +52,71 @@ ;; 2.33 -(define (map p sequence) - (accumulate (lambda (x y) ⟨??⟩) nil sequence)) -(define (append seq1 seq2) - (accumulate cons ⟨??⟩ ⟨??⟩)) -(define (length sequence) - (accumulate ⟨??⟩ 0 sequence)) +;; this one kinda tripped me up for a long while, because +;; I'm used to using `reduce` for this kind of stuff (yeah +;; I used to do common lisp) and accumulate here is basically +;; reduce, but kind of wonky. +;; e.g. (reduce (λ (x y) ...) seq) is (kind of, not really) equivalent to +;; (accumulate (λ (x y) ...) (car seq) (cdr seq)) +;; not exactly equivalent, the order in which accumulate traverses +;; its list argument is also the reverse of reduce... but you get the idea. +;; +;; edit after 2.38: apparently racket also has both accumulate and reduce: +;; they're called foldr and foldl respectively. (though still a little different, +;; compared to reduce, the differences are mostly trivial) +(define (my-map p sequence) + (accumulate (lambda (x y) (cons (p x) y)) '() sequence)) +(define (my-append seq1 seq2) + (accumulate cons seq2 seq1)) +(define (my-length sequence) + (accumulate (λ (x y) (+ y 1)) 0 sequence)) + +;; 2.34 +;; first element of coefficient-sequence is the coefficient of x^0, then x^1 and so on. +(define (horner-eval x coefficient-sequence) + (accumulate (lambda (this-coeff higher-terms) + (+ (* higher-terms x) this-coeff)) + 0 + coefficient-sequence)) + +;; 2.35 +(define (count-leaves t) + (accumulate + 0 + (map (λ (x) (if (cons? x) + (count-leaves x) + 1)) + t))) + +;; 2.36 +(define (accumulate-n op init seqs) + (if (null? (car seqs)) + '() + (cons (accumulate op init (map car seqs)) + (accumulate-n op init (map cdr seqs))))) + +;; 2.37 yeah, I'm not good with matrix stuff. +(define (dot-product v w) + (accumulate + 0 (map * v w))) +(define (matrix-*-vector m v) + (map (λ (x) (dot-product x v)) m)) +(define (transpose mat) + (accumulate-n cons '() mat)) +(define (matrix-*-matrix m n) + (let ((cols (transpose n))) + (map (λ (v) (matrix-*-vector cols v)) m))) +;; not sure about matrix-*-matrix, I didn't bother to check +;; if it was correct + + +;; 2.38 (op a b) must strictly equal (op b a) +;; a.k.a the operation must be commutative. + +;; 2.39 +(define (reversel sequence) + (foldl (lambda (x y) (cons x y)) '() sequence)) +(define (reverser sequence) + (foldr (lambda (x y) (append y (list x))) '() sequence)) +;; reverser is kinda inefficient, has to traverse y for each x +;; has O(N^2) time complexity as a result and so I hate it. +;; compare it to reversel which is O(N)