From 44d861d14d3597f7e32b8a8512263e9edf15a235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tina=20=C5=A0filigoj?= Date: Tue, 30 Apr 2024 19:22:40 +0200 Subject: [PATCH] zapiski 2. srecanje --- sicp_1_2.md | 52 ++++++++++++ sicp_1_2.scm | 217 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 sicp_1_2.md create mode 100644 sicp_1_2.scm diff --git a/sicp_1_2.md b/sicp_1_2.md new file mode 100644 index 0000000..e4035e6 --- /dev/null +++ b/sicp_1_2.md @@ -0,0 +1,52 @@ +# Ch. 1.2: Procedures and the Processes They Generate + +## Vzorci evolucije procesov + +procedura: vzorec lokalne evolucije računalniškega procesa + +Kaj pa lahko rečemo o globalnih vzorcih? + +### 1.2.1 Linearna rekurzija in iteracija + +razlika med rekurzivno proceduro in rekurzivnim procesom: + +* rekurzivna procedura v Lisp-u odraža princip, da se pri klicanju procedure sklicuje na samo proceduro +* rekurziven proces opisuje obliko evolucije računskega postopka + +Rekurzivni procesi: + +* procedura kliče samo sebe, dokler ni dosežen robni pogoj (aplikativni red) +* pri tem mora interpreter v spominu ohranjati zapis o potrebnih izvedbah procedure --> zaradi tega prostorska zahtevnost O(n) +* to se imenuje veriga preloženih operacij (? chain of deferred operations) +* ko se funkcija kliče na vhodu, ki ustreza robnim pogojem, se nato v nasprotnem vrstnem redu funkcija aplicira na vhodno vrednost in izvede --> časovna zahtevnost O(n) +* klasičen primer: fakulteta $$n!$$; rekurzivna definicija: $$n! = n(n-1)!$$ + +Iterativni procesi: + +* stanje procedure je enolično opisano na vsakem koraku: spremenljivke stanja +* poleg tega obstaja enoličen predpis za pripisovanje novih (posodobljenih) vrednosti spremenljivkam stanja po vsaki izvedbi procedure +* prostorska zahtevnost je tako O(1) - stanje je vsakič shranjeno v istem številu spremenljivk +* časovna zahtevnost je O(n) + +Razlike: + + +* tudi pri iterativnih procesih procedura kliče sama sebe, vendar je razlika v postopku izvajanja; medtem ko se mora rekurzivni proces zaradi pomnenja verige preloženih operacij izvesti v celoti, lahko iterativni proces na katerikoli točki prekinemo in nato nadaljujemo na podlagi vrednosti spremenljivk stanja ob prekinitvi +* v tem primeru govorimo o repni rekurziji (slovarček); zanke (while, for, ...) v ostalih jezikih so tako samo posebne sintaktične oblike repne rekurzije + + +### 1.2.2 Drevesna rekurzija + +* pri linearni rekurziji vsak korak vsebuje en klic procedure +* če se na posameznem koraku procedura kliče večkrat (korak je odvisen od večih prejšnjih vrednosti), je struktura procesa drevesna +* eksponentna časovna zahtevnost: O(exp(n)) +* linearna prostorska zahtevnost: O(n) - v spominu moramo na vsakem koraku ohraniti samo vrednosti v vozliščih na prejšnjem nivoju globine drevesa +* klasični primer: Fibonaccijeva števila; $$Fib(n) = Fib(n-1) + Fib(n-2)$$ + + + + + + + + diff --git a/sicp_1_2.scm b/sicp_1_2.scm new file mode 100644 index 0000000..39224cf --- /dev/null +++ b/sicp_1_2.scm @@ -0,0 +1,217 @@ +#lang scheme + + +( define a 3) +( define b ( + a 1 ) ) +(+ 2 ( if (> b a) b a) ) + +(* ( cond (( > a b) a) +((< a b ) b) +( else - 1 ) ) +(+ a 1 ) ) + + +(/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 4 5))))) (* 3 (- 6 2) (- 2 7))) + + + + + + +( define ( a-plus-abs-b a b) +(( if ( > b 0 ) + - ) a b) ) + +(a-plus-abs-b 5 -4) + + + +;; 1.9 +;; 1. primer: rekurziven +;; (+ 4 5) = inc((inc(inc(inc(5)))) = inc((inc(inc(6))) = inc((inc(7)) = inc(8) = 9 +;; 2. primer: iterativen +;; (+ 4 5): +;; (+ 3 6) +;; (+ 2 7) +;; (+ 1 8) +;; (+ 0 9) +;; 9 + +;; 1.10 + +( define (A x y) +( cond ((= y 0 ) 0 ) +(( = x 0 ) ( * 2 y)) +((= y 1 ) 2 ) +( else (A ( - x 1 ) +( A x ( - y 1 ) ) ) ) ) ) + +(A 1 10 ) +(A 2 4) +(A 3 3) + + +(define (fib n) +( cond (( = n 0 ) 0) +(( = n 1) 1 ) +( else ( + ( fib ( - n 1 ) ) +( fib ( - n 2 ) ) ) ) ) ) + +(fib 10) + +;; 1.11 + +(define (f-rec n) +( cond (( < n 3 ) n) +( else ( + (f-rec ( - n 1 )) (* 2 (f-rec (- n 2))) (* 3 (f-rec (- n 3))))))) + + +(f-rec 6) + + + +( define (fib2 n) +( fib-iter 1 0 n) ) + +( define ( fib-iter a b count ) +( if (= count 0 ) +b +( fib-iter (+ a b) a ( - count 1 ) ) ) ) + + +(fib2 10) + + +( define (f2 n) +( f-iter n (if (< n 2) n 2)) ) + +( define ( f-iter max-count sum) +( if (< max-count 3 ) +max-count +(+ (f-iter (- max-count 1) sum) (* 2 (f-iter (- max-count 2) sum )) (* 3 (f-iter (- max-count 3) sum ))))) +;;( f-iter (+ (- count 1) (* 2 (- count 2)) (* 3 (- count 3))) (- count 1)))) + + +(f2 6) + + +;; 1.12 +(define (pascal r c) + (if (or (= r 0) (= c 1) (= c r)) + 1 + (+ (pascal (- r 1) c) (pascal (- r 1) (- c 1))))) + +;;(pascal 5 3) + +;; 1.13 done + +;; 1.14 +( define ( count-change amount ) +( cc amount 5 ) ) + +( define ( cc amount kinds-of-coins ) +( cond (( = amount 0) 1 ) +(( or (< amount 0 ) ( = kinds-of-coins 0 ) ) 0 ) +( else (+ ( cc amount +( - kinds-of-coins 1 ) ) +( cc ( - amount +( first-denomination kinds-of-coins ) ) +kinds-of-coins ) ) ) ) ) +(define ( first-denomination kinds-of-coins) +( cond (( = kinds-of-coins 1 ) 1) +(( = kinds-of-coins 2 ) 5) +(( = kinds-of-coins 3) 10 ) +(( = kinds-of-coins 4) 25 ) +(( = kinds-of-coins 5 ) 50) ) ) + +( count-change 11) + + +(define (square x) (* x x)) + +( define ( even? n) +(= (remainder n 2 ) 0 ) ) + +( define ( fast-expt b n) +( cond ( (= n 0 ) 1 ) +( ( even? n ) ( square ( fast-expt b ( / n 2 ) ) ) ) +( else ( * b ( fast-expt b ( - n 1 ) ) ) ) ) ) + +(fast-expt 2 5) + +;; 1.16 +( define ( fast-exp-iter n b a ) +( if (= n 0 ) +a +(if (even? n) (fast-exp-iter ( / n 2 ) (square b) a ) ( * b ( fast-exp-iter ( - n 1 ) (* a b) a ) ) ) ) ) + +(fast-exp-iter 10 2 1 ) + +;; 1.17 + +;; iz knjige +(define (mult a b) +(if (= b 0) +0 +(+ a (mult a (- b 1 ) ) ) ) ) + +(mult 3 4) + +;; naloga +(define (double x) (+ x x)) +(define (halve x) (/ x 2)) ;; a bi to moralo biti kako drugace; zakaj uporabljam deljenje pri implementaciji mnozenja s sestevanjem + +( define ( fast-mult a b) +( cond ( (= b 0 ) 0 ) +( ( even? b ) ( double ( fast-mult a (halve b) ) ) ) +( else ( + a ( fast-mult a ( - b 1 ) ) ) ) ) ) + +(fast-mult 8 7) + +;; 1.18 + +( define ( fast-mult-iter b a c) +( if (= b 0 ) +0 +(if (even? b) (fast-mult-iter (halve b) (double a) c ) ( + a ( fast-mult-iter ( - b 1 ) a c ) ) ) ) ) + +(fast-mult-iter 18 10 0 ) + +;; 1.21 + +( define ( smallest-divisor n) +( find-divisor n 2 ) ) +( define (find-divisor n test-divisor) +( cond (( > ( square test-divisor) n) n) +(( divides? test-divisor n) test-divisor) +(else ( find-divisor n (+ test-divisor 1 ) ) ) ) ) +( define (divides? a b ) +(= (remainder b a) 0 ) ) + +(smallest-divisor 19999) + +( define (prime? n) +(= n ( smallest-divisor n) ) ) + + + +;; 1.22 + +(define (runtime) (current-milliseconds)) ;; brez tega error: runtime: unbound identifier in: runtime + +(define (timed-prime-test n) +(newline) +(display n) +(start-prime-test n (runtime))) +(define (start-prime-test n start-time) +(if (prime? n) +(report-prime (- (runtime) start-time)) -1)) +(define (report-prime elapsed-time) +(display "***" ) +(display elapsed-time)) + +(timed-prime-test 87178291199) ;; 35742549198872617291353508656626642567 + +;; https://en.wikipedia.org/wiki/List_of_prime_numbers + +;; 1.26 +;; ker se s klicanjem (/ exp 2) v navadnem mnozenju parameter exp ne razpolovi v naslednjem koraku ? \ No newline at end of file