5.9 KiB
5.9 KiB
Zapiski in vaje #6 srečanja programerskega bralnega krožka SICP
Teme
Grajenje abstrakcij s podatki
Prvo poglavje, v katerem smo operirali s preprostimi števili, drugo poglavje nadgrajuje s podatkovnimi struktura oz. kombiniranjem podatkovnih objektov v sestavljene podatkovne modele.
Torej ustvarili bomo podatkovne abstrakcije in definirali funkcije ki lahko operirajo nad njimi. Preprost primer je recimo racionalno število, ki ga sestavlja par števca in imenovalca.
(define (ustvari-rac s i)
(cons s i))
(define (stevec x) (car x))
(define (imenovalec x) (cdr x))
(define (izpisi-rac x)
(newline)
(display (stevec x))
(display "/")
(display (imenovalec x)))
(define polovica (ustvari-rac 1 2))
(izpisi-rac polovica)
(izpisi-rac (ustvari-rac 6 3))
Uporabimo funkcijo za najvecji skupni imenovlec, da poenostavimo recimo 6/3 v 2/1.
(define (gcd a b)
(if (= b 0)
a
(gcd b (remainder a b))))
(define (ustvari-rac s i)
(let ((g (gcd s i)))
(cons (/ s g) (/ i g))))
(izpisi-rac (ustvari-rac 6 3))
vaje
2.1 bolji ustvari-rac
(define (ustvari-rac s i)
(cons
(if (< i 0)
(* -1 s)
s)
(abs i)))
2.2 polovica daljice
(define make-point cons)
(define x-point car)
(define y-point cdr)
(define make-segment cons)
(define (print-point p)
(newline)
(display "(")
(display (x-point p))
(display ",")
(display (y-point p))
(display ")"))
(define (avg a b) (/ (+ a b) 2))
(define start-segment car)
(define end-segment cdr)
(define (midpoint-segment s)
(let ((start (start-segment s))
(end (end-segment s)))
(make-point (avg (x-point start) (x-point end))
(avg (y-point start) (y-point end)))))
2.3 obseg in ploscina kvadra
;; Dolzina in sirina
(define (ploscina-kvadra k)
(* (car k) (cdr k)))
(define (obseg-kvadra k)
(* 2 (+ car k) (cdr k)))
(define make-kvader cons)
2.4 Proceduralna reprezantacija parov
(define (cons x y)
(lambda (m) (m x y)))
(define (car z)
(z (lambda (p q) p)))
;; kaksen je cdr?
(define (cdr z)
(z (lambda (p q) q)))
(list
(cons 10 12)
(car (cons 10 12))
(cdr (cons 10 12)))
'(#<procedure 7f3e1bf08dc0 at <unknown port>:10:2 (m)> 10 12)
2.5 aritmeticni par v stevilu
(define (cons a b)
(* (expt 2 a) (expt 3 b)))
(define (car p)
(if (= 0 (modulo p 2))
(+ 1 (car (/ p 2)))
0))
(define (cdr p)
(if (= 0 (modulo p 3))
(+ 1 (cdr (/ p 3)))
0))
(list
(cons 12 41)
(car (cons 12 41))
(cdr (cons 12 41)))
149393393160891541106688 | 12 | 41 |
2.6 churchova števila
(define zero (lambda (f) (lambda (x) x)))
(define (add-1 n)
(lambda (f) (lambda (x) (f ((n f) x)))))
(define one
(lambda (f) (lambda (x) (f (((lambda (f) (lambda (x) x)) f) x)))))
(define two
(lambda (f) (lambda (x) (f ((one f) x)))))
;; pokrajsano
(define one
(lambda (f) (lambda (x) (f x))))
(define two
(lambda (f) (lambda (x) (f (((lambda (f) (lambda (x) (f x))) f) x)))))
;; @TODO hmm kaj se zgodi tu vmes koristnega za razumevanje?
(define two
(lambda (f) (lambda (x) (f (f x)))))
2.7 Racunanje z intervali (z napako)
(define (add-interval x y)
(make-interval (+ (lower-bound x) (lower-bound y))
(+ (upper-bound x) (upper-bound y))))
(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 (div-interval x y)
(mul-interval x
(make-interval (/ 1.0 (upper-bound y))
(/ 1.0 (lower-bound y)))))
(define (make-interval a b) (cons a b))
(define upper-bound cdr)
(define lower-bound car)
(list
(add-interval
(make-interval 3 4)
(make-interval 5 8))
(mul-interval
(make-interval 5 6)
(make-interval 8 10)))
((8 . 12) (40 . 60))
2.8 odstevanje intervala
(define (make-interval a b) (cons a b))
(define upper-bound cdr)
(define lower-bound car)
(define (sub-interval a b)
(make-interval (- (lower-bound a) (upper-bound b))
(- (upper-bound a) (lower-bound b))))
(list
(sub-interval (make-interval 10 12)
(make-interval 3 7)))
((3 . 9))
2.9 srednja vrednost in napaka
Sestevanje in odstevanje je isto pri intervalu od-do kot srednja-vrednost napaka
(define (make-priblizek vrednost napaka) (cons vrednost napaka))
(define vrednost car)
(define napaka cdr)
(define (add-priblizek a b)
(make-priblizek (+ (vrednost a) (vrednost b))
(+ (napaka a) (napaka b))))
(define (sub-priblizek a b)
(make-priblizek (- (vrednost a) (vrednost b))
(+ (napaka a) (napaka b))))
(define (mul-priblizek a b)
(make-priblizek (* (vrednost a) (vrednost b))
()))
(list
"vsota in razlika je preprosta"
(add-priblizek (make-priblizek 8 3)
(make-priblizek 4 1))
(sub-priblizek (make-priblizek 8 3)
(make-priblizek 4 1))
"pri mnozenju in deljenju pa je \"sirina\" (napaka) odvisna tudi od vrednosti")
;; TODO napisi funkcije za mnozenje in deljenje
#+RESULTS: