暇すぎて SICP を復習してきましたが、第二章もついに最終節になりました。9 月からプータローになるため、さらに復習が捗るかもしれません。いや、ゲームばっかやってるかもだけどwww*1
;;;;; 2.5.3 例:記号代数 (define (install-polynomial-package) ;; 内部手続き ;; 多項式型の表現 (define (make-poly variable term-list) (cons variable term-list)) (define (variable p) (car p)) (define (term-list p) (cdr p)) (define (variable? x) (symbol? x)) (define (same-variable? v1 v2) (and (variable? v1) (variable? v2) (eq? v1 v2))) ;; 項と項リストの表現 (define (the-empty-termlist) '()) (define (empty-termlist? term-list) (null? term-list)) (define (first-term term-list) (car term-list)) (define (rest-terms term-list) (cdr term-list)) (define (make-term order coeff) (list order coeff)) (define (order term) (car term)) (define (coeff term) (cadr term)) (define (adjoin-term term term-list) (if (=zero? (coeff term)) term-list (cons term term-list))) (define (add-terms L1 L2) (cond ((empty-termlist? L1) L2) ((empty-termlist? L2) L1) (else (let ((t1 (first-term L1)) (t2 (first-term L2))) (cond ((> (order t1) (order t2)) (adjoin-term t1 (add-terms (rest-terms L1) L2))) ((< (order t1) (order t2)) (adjoin-term t2 (add-terms L1 (rest-terms L2)))) (else (adjoin-term (make-term (order t1) (add (coeff t1) (coeff t2))) (add-terms (rest-terms L1) (rest-terms L2))))))))) (define (mul-terms L1 L2) (if (empty-termlist? L1) (the-empty-termlist) (add-terms (mul-term-by-all-terms (first-term L1) L2) (mul-terms (rest-terms L1) L2)))) (define (mul-term-by-all-terms t1 L) (if (empty-termlist? L) (the-empty-termlist) (let ((t2 (first-term L))) (adjoin-term (make-term (+ (order t1) (order t2)) (mul (coeff t1) (coeff t2))) (mul-term-by-all-terms t1 (rest-terms L)))))) (define (add-poly p1 p2) (if (same-variable? (variable p1) (variable p2)) (make-poly (variable p1) (add-terms (term-list p1) (term-list p2))) (error "Polys not in same var -- ADD-POLY" (list p1 p2)))) (define (mul-poly p1 p2) (if (same-variable? (variable p1) (variable p2)) (make-poly (variable p1) (mul-terms (term-list p1) (term-list p2))) (error "Polys not in same var -- MUL-POLY" (list p1 p2)))) ;; システムの他の部分とのインターフェース (define (tag p) (attach-tag 'polynomial p)) (put 'add '(polynomial polynomial) (lambda (p1 p2) (tag (add-poly p1 p2)))) (put 'mul '(polynomial polynomial) (lambda (p1 p2) (tag (mul-poly p1 p2)))) (put 'make 'polynomial (lambda (var terms) (tag (make-poly var terms)))) 'done) (define (make-polynomial var terms) ((get 'make 'polynomial) var terms)) ;;;;; (install-scheme-number-package) (install-scheme-real-package) (install-rational-package) (install-rectangular-package) (install-polar-package) (install-complex-package) (install-polynomial-package)
このコードを問題 2.86 の最後にくっつければ、ひとまず完成。
(本書に載ってるコードを打ち込んだだけという説もあるw)
ただし、install-*-package だけは一番最後に移動しよう。
;; (x^100 + 2x^2 + 1) + (x^10 + 5x^2) ;; make-term の部分は、order (次数) coeff (係数) の順で指定する。 ;; 間違えやすいので注意。 gosh> (add (make-polynomial 'x '((100 1) (2 2) (0 1))) (make-polynomial 'x '((10 1) (2 5)))) (polynomial x (100 1) (10 1) (2 7) (0 1)) ;; ===> x^100 + x^10 + 7x^2 + 1 ;; (x^2 + 1) * (x^3 + 4x + 5) gosh> (mul (make-polynomial 'x '((2 1) (0 1))) (make-polynomial 'x '((3 1) (1 4) (0 5)))) (polynomial x (5 1) (3 5) (2 5) (1 4) (0 5)) ;; ==> x^5 + 5x^3 + 5x^2 + 4x + 5
こんな風に多項式の演算ができる。
ゲーム漬けになっていなかったら、次回から問題を解いていきまーす。
*1:もうすぐスターフィールド来ちゃうからね