From 164757c7393fb52f0a1374f5c562ba3f1e93a52b Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Sun, 29 Nov 2020 22:30:30 -0500 Subject: [PATCH] Implement 2.91 division --- ex-2_77-97.scm | 86 +++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/ex-2_77-97.scm b/ex-2_77-97.scm index a3e56a8..8f0e73f 100644 --- a/ex-2_77-97.scm +++ b/ex-2_77-97.scm @@ -609,13 +609,17 @@ (error "Polys not in same var -- ADD-POLY" (list p1 p2)))) + (define (negate-term term) + (make-term (order term) (negate (coeff term)))) + + (define (negate-terms terms) + (map negate-term terms)) + (define (sub-poly p1 p2) - (define (negate-term term) - (make-term (order term) (negate (coeff term)))) (if (same-variable? (variable p1) (variable p2)) (make-poly (variable p1) (add-terms (term-list p1) - (map negate-term (term-list p2)))) + (negate-terms (term-list p2)))) (error "Polys not in same var -- ADD-POLY" (list p1 p2)))) @@ -778,7 +782,8 @@ (attach-tag term-type (cdr terms)))) (define (empty-termlist? term-list) (null? (contents term-list))) - (define (make-term order coeff) (list order coeff)) + (define (make-term order coeff) + (list order coeff)) (define (order term) (car term)) (define (coeff term) (cadr term)) @@ -843,53 +848,48 @@ (define (div-poly p1 p2) (if (same-variable? (variable p1) (variable p2)) - (make-poly (variable p1) - (div-terms (term-list p1) - (term-list p2))) + (let ((result (div-terms (term-list p1) (term-list p2))) + (var (variable p1))) + (list + (tag (make-poly var (car result))) + (tag (make-poly var (cadr result))))) (error "Polys not in same var -- MUL-POLY" (list p1 p2)))) -; Division can be performed via long division. That is, divide the highest-order -; term of the dividend by the highest-order term of the divisor. The result is -; the first term of the quotient. Next, multiply the result by the divisor, -; subtract that from the dividend, and produce the rest of the answer by -; recursively dividing the difference by the divisor. Stop when the order of the -; divisor exceeds the order of the dividend and declare the dividend to be the -; remainder. Also, if the dividend ever becomes zero, return zero as both -; quotient and remainder. -; -; We can design a div-poly procedure on the model of add-poly and mul-poly. The -; procedure checks to see if the two polys have the same variable. If so, -; div-poly strips off the variable and passes the problem to div-terms, which -; performs the division operation on term lists. Div-poly finally reattaches the -; variable to the result supplied by div-terms. It is convenient to design -; div-terms to compute both the quotient and the remainder of a division. -; Div-terms can take two term lists as arguments and return a list of the -; quotient term list and the remainder term list. -; -; dividend -; -------- -; divisor -; -; Complete the following definition of div-terms by filling in the missing -; expressions. Use this to implement div-poly, which takes two polys as arguments -; and returns a list of the quotient and remainder polys. - + ; Division can be performed via long division. That is, divide the + ; highest-order term of the dividend by the highest-order term of the + ; divisor. The result is the first term of the quotient. Next, multiply the + ; result by the divisor, subtract that from the dividend, and produce the + ; rest of the answer by recursively dividing the difference by the divisor. + ; Stop when the order of the divisor exceeds the order of the dividend and + ; declare the dividend to be the remainder. Also, if the dividend ever + ; becomes zero, return zero as both quotient and remainder. (define (div-terms L1 L2) + (define (negate-term t) + (make-term (order t) (negate (coeff t)))) + (define (negate-terms terms) + (let ((term-type (type-tag terms)) + (term-list (contents terms))) + (cons term-type (map negate-term term-list)))) (if (empty-termlist? L1) (list L1 L2) - (let ((t1 (first-term L1)) - (t2 (first-term L2))) + (let ((t1 (first-term L1)) ; dividend + (t2 (first-term L2))) ; divisor (if (> (order t2) (order t1)) (list (empty-termlist L2) L1) (let ((new-c (div (coeff t1) (coeff t2))) (new-o (- (order t1) (order t2))) (new-term (make-term (- (order t1) (order t2)) (div (coeff t1) (coeff t2))))) - ; XXX: continue here - (let ((rest-of-result (div-terms (empty-termlist L1) L2))) - (list (adjoin-term new-term (car rest-of-result)) - (cadr rest-of-result)))))))) + (let ((new-dividend (add-terms + L1 + (negate-terms + (mul-terms + (adjoin-term new-term (empty-termlist L1)) + L2))))) + (let ((rest-of-result (div-terms new-dividend L2))) + (list (adjoin-term new-term (car rest-of-result)) + (cadr rest-of-result))))))))) (define (=zero?-poly p) (define (=zero?-terms terms) @@ -953,10 +953,10 @@ (define p2 (make-poly-dense 'x '((2 1) (0 -1)))) (assert (mul p1 p1) (make-poly-dense 'x '((10 1) (5 -2) (0 1)))) (assert (mul p1 p2) (make-poly-dense 'x '((7 1) (5 -1) (2 -1) (0 1)))) -(display p1) (newline) -(display p2) (newline) -(display (div p1 p2)) (newline) +(let ((result (div p1 p2))) + (assert (car result) (make-poly-dense 'x '((3 1) (1 1)))) + (assert (cadr result) (make-poly-dense 'x '((1 1) (0 -1))))) + (display "\nex-2.92\n") -;(display "\nex-2.93\n")