sicp-exercises/ex-2.rkt
2025-01-02 17:49:30 +03:00

89 lines
2.6 KiB
Racket

#lang racket
(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 (make-interval a b) (cons a b))
(define (add-interval a b)
(make-interval (+ (lower-bound a) (lower-bound b))
(+ (upper-bound a) (upper-bound b))))
;; 2.7
;; simple definitions.
(define upper-bound cdr)
(define lower-bound car)
;; 2.8
(define (interval-diff f a b)
(make-interval (- (lower-bound a) (upper-bound b))
(- (upper-bound a) (lower-bound b))))
;; 2.9 this one's just about reasoning, no programming, and I feel too lazy to explain
;; sorry.
;; 2.10 : simple 'nuff.
(define (div-interval x y)
(if (= (lower-bound y) (upper-bound y))
(error "WHY? WHY MUST YOU TORTURE ME SO?")
(mul-interval
x
(make-interval (/ 1.0 (upper-bound y))
(/ 1.0 (lower-bound y))))))
;; 2.11 : This one's also somewhat simple.
;; we ONLY need more than two multiplications
;; if BOTH intervals have different signs on their upper
;; and lower bounds. otherwise, naive logic works fine.
(define (mul-interval2 x y)
(define (different? n)
(and (< (lower-bound n) 0) (< (upper-bound n) 0)))
(if (and (different? x) (different? 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)))
(make-interval (* (lower-bound x) (lower-bound y))
(* (upper-bound x) (upper-bound y)))))
;; 2.12 : simple nuff.
(define (make-center-width c w)
(make-interval (- c w) (+ c w)))
(define (center i)
(/ (+ (lower-bound i) (upper-bound i)) 2))
(define (width i)
(/ (- (upper-bound i) (lower-bound i)) 2))
(define (make-center-percent c p)
(make-center-width c (* c (/ p 100))))
(define (percent i)
(* (/ (width i) 2) 100))
;; 2.13 & 2.14
(define (par1 r1 r2)
(div-interval (mul-interval r1 r2)
(add-interval r1 r2)))
(define (par2 r1 r2)
(let ((one (make-interval 1 1)))
(div-interval
one (add-interval (div-interval one r1)
(div-interval one r2)))))
(define A (make-interval 100 101))
(define B (make-interval 200 201))
(div-interval A A)
(div-interval (make-interval 1 1) A)
(div-interval B A)