diff --git a/ex-2_77-97.scm b/ex-2_77-97.scm index 733cd43..a3e56a8 100644 --- a/ex-2_77-97.scm +++ b/ex-2_77-97.scm @@ -770,6 +770,8 @@ (put 'adjoin-term 'dense adjoin-term-dense) (define (the-empty-termlist) (tag-sparse '())) + (define (empty-termlist t) + (attach-tag (type-tag t) '())) (define (rest-terms term-list) (let ((term-type (type-tag term-list)) (terms (contents term-list))) @@ -839,6 +841,56 @@ (error "Polys not in same var -- MUL-POLY" (list p1 p2)))) + (define (div-poly p1 p2) + (if (same-variable? (variable p1) (variable p2)) + (make-poly (variable p1) + (div-terms (term-list p1) + (term-list p2))) + (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. + + (define (div-terms L1 L2) + (if (empty-termlist? L1) + (list L1 L2) + (let ((t1 (first-term L1)) + (t2 (first-term L2))) + (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)))))))) + (define (=zero?-poly p) (define (=zero?-terms terms) (cond @@ -855,6 +907,8 @@ (lambda (p1 p2) (tag (mul-poly p1 p2)))) (put 'sub '(polynomial polynomial) (lambda (p1 p2) (tag (sub-poly p1 p2)))) + (put 'div '(polynomial polynomial) + (lambda (p1 p2) (div-poly p1 p2))) (put '=zero? '(polynomial) =zero?-poly) (put 'make 'poly-sparse (lambda (var terms) (tag (make-poly-sparse var terms)))) @@ -893,8 +947,16 @@ (make-poly-dense 'x '((200 4) (101 8) (2 4)))) -(display "\nex-2.91\n") +(display "\nex-2.91 - divide\n") -;(display "\nex-2.92\n") +(define p1 (make-poly-dense 'x '((5 1) (0 -1)))) +(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) + +(display "\nex-2.92\n") ;(display "\nex-2.93\n")