SICP 問題 2.46(frameを構成するための各種手続きを定義する)
問題
原点からある点へ向かう二次元のベクタ v は x 座標と y 座標からなる対で表現できる。構成子 make-vect と、対応する選択子 xcor-vect と ycor-vect を作り、ベクタのデータ抽象を実装せよ。その選択子と構成子を使い、ベクタの加算、減算、スカラーによる乗算:
の演算を実行する手続き add-vect、sub-vect、及び scale-vect を実装せよ。
(x_1, y_1) + (x_2, y_2) = (x_1 + x_2, y_1 + y_2)
(x_1, y_1) - (x_2, y_2) = (x_1 - x_2, y_1 - y_2)
s・(x, y) = (s・x, s・y)
解答
前やったようなやつだな。多分 SICP じゃ3次元は出てこんだろうし、cons でやっちまおう。
;構成子 (define (make-vect x y) (cons x y)) ;x 選択子 (define (xcor-vect v) (car v)) ;y 選択子 (define (ycor-vect v) (cdr v))
続いてベクタの各種演算を。
;ベクタの抽象化 (define (op-vect op v_1 v_2) (let ((x_1 (xcor-vect v_1)) (y_1 (ycor-vect v_1)) (x_2 (xcor-vect v_2)) (y_2 (ycor-vect v_2))) (make-vect (op x_1 x_2) (op y_1 y_2)))) ;ベクタ加算 (define (add-vect v_1 v_2) (op-vect + v_1 v_2)) ;ベクタ減算 (define (sub-vect v_1 v_2) (op-vect - v_1 v_2)) ;スカラー乗算 (define (scale-vect s v) (op-vect * (make-vect s s) v))
スカラー演算は無駄な処理をするハメになってるけどまぁいいっしょ。性能求められてるわけじゃないし。
では実験。
おっけ〜。
gosh> (define v_1 (make-vect 5 7))
v_1
gosh> (define v_2 (make-vect 2 9))
v_2
gosh> (xcor-vect v_1)
5
gosh> (xcor-vect v_2)
2
gosh> (ycor-vect v_1)
7
gosh> (ycor-vect v_2)
9
gosh> (add-vect v_1 v_2)
(7 . 16)
gosh> (sub-vect v_1 v_2)
(3 . -2)
gosh> (scale-vect 3 v_1)
(15 . 21)
gosh> (scale-vect 3 v_2)
(6 . 27)
gosh>