scheme - How can I check to make sure that only positive values are in final list? -
my question deals the difference of 2 bags. bag consists of pairs include value , cardinality of value. having trouble checking whether pair valid, , can added final list. example if run following:
(diff '((1 5) (2 2) (3 4) (4 8) (5 4)) '((2 3) (4 3) (6 2)))
the correct answer should ((1 5) (3 4) (4 5) (5 4))
getting ((1 5) (2 -1) (3 4) (4 5) (5 4))
. ideas on how check negative cardinalities. appreciated.
(define (diff bag1 bag2) (cond ((null? bag1) '()) ((null? bag2) '()) ((eq? (car(car bag1)) (car(car bag2))) (cons (cons (car(car bag1)) (cons (- (car(cdr(car bag1))) (car(cdr(car bag2)))) '())) (diff (cdr bag1) (cdr bag2)))) (else (cond ((member? (car(car bag1)) bag1) (cons (car bag1) (diff (cdr bag1) bag2))))))) (define (member? x bag) (cond ((null? bag) #f) (else (or(eq?(car(car bag)) x) (member? x (cdr bag))))))
since seem want keep pairs bag1 cardinality bigger cardinality corresponding pair in bag2, should change cond clause test
(eq? (car(car bag1)) (car(car bag2)))
to 2 clauses
((and (eq? (car (car bag1)) (car (car bag2))) (> (car (cdr (car bag1))) (car (cdr (car bag2))))) ;; difference > 0: substract (cons (cons (car(car bag1)) (cons (- (car(cdr(car bag1))) (car(cdr(car bag2)))) '())) (diff (cdr bag1) (cdr bag2)))) ((eq? (car (car bag1)) (car (car bag2))) ;; difference <= 0: skip (diff (cdr bag1) (cdr bag2)))
further improvements possible. e.g.
(else (cond ((member? (car(car bag1)) bag1) (cons (car bag1) (diff (cdr bag1) bag2)))))))
can simplified to
(else (cons (car bag1) (diff (cdr bag1) bag2)))))
Comments
Post a Comment