SICPを読む(57) 問題 2.37 - 2.39
どうやら僕のSICPリーディング速度はかなり遅いらしい(汗
回りが凄い人達だらけなので、圧倒されないようにマイペースで行こうと思う。
問題 2.37
ベクトル演算の問題。
行列があんま得意じゃない。つうか数学全般的に。
(define v '(1 2 3)) (define w '(4 5 6)) (define m '((1 2 3) (4 5 6) (7 8 9))) (define n '((9 8 7) (6 5 4) (3 2 1))) (define (dot-product v m) (fold + 0 (map * v m))) (dot-product v w) ; 32 (define (matrix-*-vector m v) (map (cut dot-product v <>) m)) (matrix-*-vector m v) ; (14 32 50) (define (transpose mat) (accumulate-n cons '() mat)) (transpose m) ; ((1 4 7) (2 5 8) (3 6 9)) (define (matrix-*-matrix m n) (let ((cols (transpose n))) (map (cut matrix-*-vector cols <>) m))) (matrix-*-matrix m n) ; ((30 24 18) (84 69 54) (138 114 90))
(map * v m)という強烈な技があったとは・・・。
問題 2.38
fold_left(fold),fold_rightの順番について。
紙の上で計算して、答合わせした。
まず割り算。
(define l '(1 2 3)) (fold-right / 1 l) ; 3/2 (fold / 1 l) ; 3/2 (/ 1 (/ 2 (/ 3 1))) ; 3/2 (/ 3 (/ 2 (/ 1 1))) ; 3/2
アレ?答えが同じになった?!オカシイ。
と思ったら、lのlengthが奇数の時は答えが同じ。偶数の時は答えが逆数になる。
ひっかけ問題かよ!!
リストの場合。
(fold-right list '() l) ; (1 (2 (3 ()))) (fold list '() l) ; (3 (2 (1 ())))
入れ子のリストができあがる。
どのような並びに対しても同じ値を生じるためにopが満たすべき性質は?という設問。
上の実験結果から、
(op a b) = (op b a)が成り立つ時にはリストも同値となる。
foldの扱いには注意。
問題 2.39
reverseをfold_right,fold_leftで作る。
2.39 (define (reverse sequence) (fold-right (lambda (x y) (append y (list x))) '() sequence)) (define (reverse sequence) (fold cons '() sequence))
何度もやってきたので慣れてきたかも。