数式を少し改良しました。
(define (sort-sum-values lis) (let ((num (apply + (filter number? lis))) (vals (filter symbol? lis))) (if (= num 0) (sort vals) (append `(,num) (sort vals))))) (define (sort-product-values lis) (let ((num (apply * (filter number? lis))) (vals (filter symbol? lis))) (if (= num 1) (sort vals) (append `(,num) (sort vals))))) (define (opti-sum a1 a2) (cond ((and (sum? a1) (sum? a2)) (append '(+) (sort-sum-values (append (cdr a1) (cdr a2))))) ((sum? a1) (append '(+) (sort-sum-values (append (cdr a1) `(,a2))))) ((sum? a2) (append '(+) (sort-sum-values (append `(,a1) (cdr a2))))) (else (list '+ a1 a2)))) (define (opti-product a1 a2) (cond ((and (product? a1) (product? a2)) (append '(*) (sort-product-values (append (cdr a1) (cdr a2))))) ((product? a1) (append '(*) (sort-product-values (append (cdr a1) `(,a2))))) ((product? a2) (append '(*) (sort-product-values (append `(,a1) (cdr a2))))) (else (list '* a1 a2))))
これを追加
(define (make-sum a1 a2) (cond ((=number? a1 0) a2) ((=number? a2 0) a1) ((and (number? a1) (number? a2)) (+ a1 a2)) (else (opti-sum a1 a2)))) (define (make-product m1 m2) (cond ((or (=number? m1 0) (=number? m2 0)) 0) ((=number? m1 1) m2) ((=number? m2 1) m1) ((and (number? m1) (number? m2)) (* m1 m2)) (else (opti-product m1 m2))))
make-sum と make-product はこんな風に直します。
改良前
gosh> (inverse-matrix '((1 0 0) (a 1 0) (b c 1))) ((1 0 0) ((* -1 a) 1 0) ((+ (* -1 b) (* (* -1 a) (* -1 c))) (* -1 c) 1))
改良後
gosh> (inverse-matrix '((1 0 0) (a 1 0) (b c 1))) ((1 0 0) ((* -1 a) 1 0) ((+ (* -1 b) (* a c)) (* -1 c) 1))
前よりはだいぶ良くなりました。