<< Previous exercise (2.88) | Index | Next exercise (2.90) >>
;; an even shorter solution to achieve the same result (define (first-term term-list) (make-term (- (length term-list) 1) (car term-list))) (define (adjoin-term term term-list) (cond ((=zero? term) term-list) ((equ? (order term) (length term-list)) (cons (coeff term) term-list)) (else (adjoin-term term (cons 0 term-list)))))
In adjoin-term, we need to use =zero? on (coeff term), not on term. And equ? is not necessary because the we are comparing just two ordinary numbers.
Here is the fixed code:
(define (first-term term-list) (make-term (- (length term-list) 1) (car term-list))) (define (adjoin-term term term-list) (cond ((=zero? (coeff term)) term-list) ((= (order term) (length term-list)) (cons (coeff term) term-list)) (else (adjoin-term term (cons 0 term-list)))))
We don't need to change much. Also, since adjoin-term is properly used in add-term and mul-term, I don't think we have to change it drastically like some people did.
;; List the term, and find the order (define (first-term term-list) (list (car term-list) ; first term (- 1 (length term-list)))) ; order is length-1 (we index polynomials from 0) ;; Slightly modified to cons the coeff instead of the actual term (define (adjoin-term term term-list) (let ((coeff-of-term (coeff term))) (if (=zero? coeff-of-term) term-list (cons coeff-of-term term-list))))
It is probably me, but none of the solution above worked for me.
meteorgan's solution has bracketing errors and even after fixing them there seems to be logical errors.
hattivat uses =zero? directly on term which does not work because add-terms calls adjoin-term on regular terms, i.e. one that have coeff and order.
Finally, Marisa's solution runs, but creates false results for my tests.
The following code worked for me when I added it to the poly-package from the book. Note that not considering zero terms would yield invalid results for multiplication.
(define (first-term term-list) (make-term (- (length term-list) 1) (car term-list))) (define (adjoin-term term term-list) (let ((coeff-term (coeff term)) (order-term (order term)) (length-terms (length term-list))) (cond ((= order-term length-terms) (cons coeff-term term-list)) ((< order-term length-terms) (error "Cannot adjoin lower-order term to terms")) (else (cons coeff-term (adjoin-term (make-term (- order-term 1) 0) term-list))))))
Kaihao has the best solution....
...but it's still wrong!
To see why: compare the results of Kaihao's code with the book's sparse code:
;; computation: second term of x^3 + x ;; book sparse (first-term (rest-terms '((3 1) (1 1)))) ;; -> (1 1), i.e. 'x' ;; buggy dense (first-term (rest-terms '(1 0 1 0))) ;; -> (2 0), i.e. '0x^2'
We should not get different answers when switching data representations! The issue is the padded zeroes. To fix, one must maintain the invariant that term-lists must have non-zero leading terms. You only have to modify rest-terms to achieve this:
(define (rest-terms term-list)
(define (trim-leading-zeroes l)
(cond ((null? l) '())
((not (= 0 (car l))) l)
(else (trim-leading-zeroes (cdr l)))))
(trim-leading-zeroes (cdr term-list)))
Ergomaniac strikes again!
LisScheSic
It should use (list (- (length term-list) 1) (car term-list)) for the book order implementation.