Skip to content

Instantly share code, notes, and snippets.

@yanfeng42
Last active August 30, 2021 05:45
Show Gist options
  • Save yanfeng42/f7c39ff33a15f1b385a6063d119db791 to your computer and use it in GitHub Desktop.
Save yanfeng42/f7c39ff33a15f1b385a6063d119db791 to your computer and use it in GitHub Desktop.
sicp 2.11 没有完全符合要求的答案
; (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!"
)
@yanfeng42
Copy link
Author

问题中的 “每种情况所需的乘法都不超过2次”, 无法满足. 社区答案, 大致看了下, 也无法满足.

特殊的场景在于: 两个区间, 都刚好是 跨域 零点的 区间.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment