Last active
August 30, 2021 05:45
-
-
Save yanfeng42/f7c39ff33a15f1b385a6063d119db791 to your computer and use it in GitHub Desktop.
sicp 2.11 没有完全符合要求的答案
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; (define (mul-interval x y) | |
; (let ((p1 (* (lower-bound x) (lower-bound y))) | |
; (p2 (* (lower-bound x) (upper-bound y))) | |
; (p3 (* (upper-bound x) (lower-bound y))) | |
; (p4 (* (upper-bound x) (upper-bound y))) | |
; ) | |
; (make-interval (min p1 p2 p3 p4) (max p1 p2 p3 p4)) | |
; ) | |
; ) | |
; 分组依据: 端点和零点关系. | |
(define (mul-interval-2 x y) | |
(let ((lower-x (lower-bound x)) | |
(upper-x (upper-bound x)) | |
(lower-y (lower-bound y)) | |
(upper-y (upper-bound y)) | |
) | |
(cond ((and (>= lower-x 0) (> lower-y 0)) | |
(make-interval (* lower-x lower-y) (* upper-x upper-y))) | |
((and (>= lower-x 0) (< upper-y 0)) | |
(make-interval (* upper-x lower-y) (* lower-x upper-y))) | |
((and (>= lower-x 0) (>= upper-y 0)) | |
(make-interval (* upper-x lower-y) (* upper-x upper-y))) | |
((and (< upper-x 0) (> lower-y 0)) | |
(make-interval (* lower-x upper-y) (* upper-x lower-y))) | |
((and (< upper-x 0) (< upper-y 0)) | |
(make-interval (* upper-x upper-y) (* lower-x lower-y))) | |
((and (< upper-x 0) (>= upper-y 0)) | |
(make-interval (* lower-x upper-y) (* lower-x lower-y))) | |
((and (>= upper-x 0) (> lower-y 0)) | |
(make-interval (* lower-x upper-y) (* upper-x upper-y))) | |
((and (>= upper-x 0) (< upper-y 0)) | |
(make-interval (* upper-x lower-y) (* lower-x lower-y))) | |
((and (>= upper-x 0) (>= upper-y 0)) | |
; 如何只 乘两次? 都穿越零点, 应该绕不开4次乘法吧??? -- 从数据角度分析, 不可能绕过. -- 看遍社区答案, 没有能绕过去的. http://community.schemewiki.org/?sicp-ex-2.11 | |
(make-interval (min (* lower-x upper-y) (* upper-x lower-y)) (max (* lower-x lower-y) (* upper-x upper-y)))) | |
) | |
) | |
) | |
; 辅助函数. | |
(define (equal-interval? x y) | |
(and (= (lower-bound x) (lower-bound y)) (= (upper-bound x) (upper-bound y))) | |
) | |
; test case. | |
(define (mul-interval-test) | |
(let ((x (make-interval 1 9)) (y (make-interval 2 8))) | |
(if (not (equal-interval? (mul-interval x y) (mul-interval-2 x y))) | |
(error "fail!" x y) | |
) | |
) | |
(let ((x (make-interval 1 9)) (y (make-interval -2 -8))) | |
(if (not (equal-interval? (mul-interval x y) (mul-interval-2 x y))) | |
(error "fail!" x y) | |
) | |
) | |
(let ((x (make-interval 1 9)) (y (make-interval -2 8))) | |
(if (not (equal-interval? (mul-interval x y) (mul-interval-2 x y))) | |
(error "fail!" x y) | |
) | |
) | |
(let ((x (make-interval -1 9)) (y (make-interval 2 8))) | |
(if (not (equal-interval? (mul-interval x y) (mul-interval-2 x y))) | |
(error "fail!" x y) | |
) | |
) | |
(let ((x (make-interval -1 9)) (y (make-interval -2 -8))) | |
(if (not (equal-interval? (mul-interval x y) (mul-interval-2 x y))) | |
(error "fail!" x y) | |
) | |
) | |
(let ((x (make-interval -1 9)) (y (make-interval -2 8))) | |
(if (not (equal-interval? (mul-interval x y) (mul-interval-2 x y))) | |
(error "fail!" x y) | |
) | |
) | |
(let ((x (make-interval -1 -9)) (y (make-interval 2 8))) | |
(if (not (equal-interval? (mul-interval x y) (mul-interval-2 x y))) | |
(error "fail!" x y) | |
) | |
) | |
(let ((x (make-interval -1 -9)) (y (make-interval -2 -8))) | |
(if (not (equal-interval? (mul-interval x y) (mul-interval-2 x y))) | |
(error "fail!" x y) | |
) | |
) | |
(let ((x (make-interval -1 -9)) (y (make-interval -2 8))) | |
(if (not (equal-interval? (mul-interval x y) (mul-interval-2 x y))) | |
(error "fail!" x y) | |
) | |
) | |
"All Pass!" | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
问题中的 “每种情况所需的乘法都不超过2次”, 无法满足. 社区答案, 大致看了下, 也无法满足.
特殊的场景在于: 两个区间, 都刚好是 跨域 零点的 区间.