sicp/zapiski/g1smo/1_1_zapiski_vaje.org

410 lines
10 KiB
Org Mode
Raw Normal View History

2024-04-19 02:17:45 +02:00
#+TITLE: Zapiski #1 srečanja programerskega bralnega krožka SICP
2024-04-19 03:22:29 +02:00
#+AUTHOR: Jurij
2024-05-29 18:39:50 +02:00
#+OPTIONS: toc:nil num:nil author tex:dvisvgm
2024-04-19 02:17:45 +02:00
* Zanimivi izseki
** str. 9
#+BEGIN_QUOTE
Every reader should ask himself periodically "Toward what end, toward what end?" — but do not ask it too often lest you pass up the fun of programming for the constipation of bittersweet philosophy.
#+END_QUOTE
#+begin_quote
Lisp is a survivor, having been in use for about a quarter of a century.
#+end_quote
2024-05-29 18:39:50 +02:00
2024-04-19 02:17:45 +02:00
** str. 11
#+begin_quote
It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures.
#+end_quote
2024-05-29 18:39:50 +02:00
2024-04-19 02:17:45 +02:00
** str. 18
#+begin_quote
Thus, programs must be written for people to read, and only incidentally for machines to execute.
#+end_quote
2024-05-29 18:39:50 +02:00
2024-04-19 02:17:45 +02:00
** str. 19
#+begin_quote
Underlying our approach to this subject is our conviction that "computer science" is not a science and that its significance has little to do with computers.
#+end_quote
2024-05-29 18:39:50 +02:00
2024-04-19 02:17:45 +02:00
** str. 27
#+begin_quote
Finally, we would like to acknowledge the support of the organizations that have encouraged this work over the years, including support from Hewlett-Packard, made possible by Ira Goldstein and Joel Birnbaum, and support from DARPA, made possible by Bob Kahn.
#+end_quote
Bob Kahn je mdr. soavtor protokolov TCP in IP, pionir omreževanja. V DARPA postal kasneje direktor IPTO (Informational Processing Techniques Office), kjer je ustanovil milijardo-dolarski projekt Strategic Copmuting Initiative, največjo investicijo ameriške federalne vlade v računalništvo ever ('83 do '93) - razvijali so proizvodnjo čipov in umetne inteligence. Ustrašili so se japoncev, podobno kot v 50ih sovjetov.
Po DARPA ustanovil CNRI (corporation for national research initiatives), neprofitno organizacijo kjer je delal tudi guido van rossum (avtor pythona). Tam so izdali python verzije 1.3 do 1.6 ter GNU mailman.
Preko očeta v sorodu s fizikom Hermanom Kahnom, ki je napisal knjigo o tem kako bi amerika lahko zmagala nuklearno vojno in postal inspiracija za dr. Strangelove-a v znanem Kubrickovem filmu. Ustanovil je Hudson institut, konzervativni think tank ki je začel pri premišljevanju hladnovojnih scenarijev in se razširil na polja ekonomije, zdravstva, šolstva in gemblanja. Delal je tudi v RAND korporaciji, močnem hladnovojnem inštitutu, vpletenem v vietnamsko vojno, iraško vojno, danes pa kuri "AI apokaliptični" scenarij.
** str. 77
Stoy 1977
2024-05-29 18:39:50 +02:00
2024-04-19 02:17:45 +02:00
* Vaje
** 1.1 Kaj vrnejo izrazi?
2024-05-29 18:39:50 +02:00
#+begin_src scheme
(+ 5 3 4)
#+end_src
10
#+begin_src scheme
(- 9 1)
#+end_src
8
#+begin_src scheme
(/ 6 2)
#+end_src
3
#+begin_src scheme
(+ (* 2 4) (- 4 6))
#+end_src
6
#+begin_src scheme
(define a 3)
#+end_src
#nil
#+begin_src scheme
(define b (+ a 1))
#+end_src
#nil
#+begin_src scheme
(+ a b (* a b))
#+end_src
19
#+begin_src scheme
(= a b)
#+end_src
#f
#+begin_src scheme
(if (and (> b a) (< b (* a b)))
b
a)
#+end_src
4
#+begin_src scheme
(cond ((= a 4) 6)
((= b 4) (+ 6 7 a))
(else 25))
#+end_src
16
#+begin_src scheme
(+ 2 (if (> b a) b a))
#+end_src
6
#+begin_src scheme
(* (cond ((> a b) a)
((< a b) b)
(else -1))
(+ a 1))
#+end_src
16
2024-04-30 19:20:40 +02:00
2024-04-19 02:17:45 +02:00
** 1.2 Pretvori izraz v prefix obliko
2024-05-29 18:39:50 +02:00
\begin{equation}
\frac{5+4+(2-(3-(6+\frac{4}{5}))) }{3(6-2)(2-7)}
\end{equation}
2024-04-19 02:17:45 +02:00
#+begin_src scheme :exports both
(/ (+ 5 4
(- 2
(- 3
(+ 6
2024-05-29 18:39:50 +02:00
4/5))))
2024-04-19 02:17:45 +02:00
(* 3
(- 6 2)
(- 2 7)))
#+end_src
#+RESULTS:
: -43/180
2024-05-29 18:39:50 +02:00
** 1.3 določi postopek, ki prejme 3 števila kot argumente in vrne vsoto kvadratov večjih dveh
2024-04-19 02:17:45 +02:00
2024-04-21 17:36:07 +02:00
#+begin_src scheme :exports both :results table
2024-04-19 02:17:45 +02:00
(define (vsota-vecjih-kvadratov a b c)
(cond ((<= a b c) (+ (* b b) (* c c)))
((<= b a c) (+ (* a a) (* c c)))
(else (+ (* b b) (* a a)))))
;; ^ NAROBE! <= primerja vse tri stevilke, ne prvo z drugima dvema oz. ostalimi
(define (+kvadrat a b) (+ (* a a) (* b b)))
(define (vsota-vecjih-kvadratov2 a b c)
(if (>= a b)
(if (>= b c)
(+kvadrat a b)
(+kvadrat a c))
(if (>= a c)
(+kvadrat a b)
(+kvadrat b c))))
2024-04-21 17:36:07 +02:00
(list
2024-05-29 18:39:50 +02:00
'("Pričakovano" 85 41 164 89)
2024-04-21 17:36:07 +02:00
(list "Funkcija1"
(vsota-vecjih-kvadratov 6 1 7)
(vsota-vecjih-kvadratov 3 4 5)
(vsota-vecjih-kvadratov 8 10 2)
(vsota-vecjih-kvadratov 3 8 5))
(list "Funkcija2"
(vsota-vecjih-kvadratov2 6 1 7)
(vsota-vecjih-kvadratov2 3 4 5)
(vsota-vecjih-kvadratov2 8 10 2)
(vsota-vecjih-kvadratov2 3 8 5)))
2024-04-19 02:17:45 +02:00
#+end_src
#+RESULTS:
2024-04-21 17:36:07 +02:00
| Pricakovano | 85 | 41 | 164 | 89 |
| Funkcija1 | 85 | 41 | 164 | 73 |
| Funkcija2 | 85 | 41 | 164 | 89 |
2024-04-30 19:20:40 +02:00
** 1.4 Opis procedure
#+begin_src scheme
(define (a-plus-abs-b a b)
((if (> b 0) + -) a b))
#+end_src
Izraz ~if~ vrne funkcijo ~+~ ali ~-~ , glede na to, ali je argument ~b~ večji ali manjši od 0.
2024-05-29 18:39:50 +02:00
Če je ~b~ manjši od 0, ga odšteje od ~a~, sicer pa ga prišeje. Zato je rezultat funkcije ekvivalenten vsoti ~a~ in absolutnega ~b~.
2024-04-30 19:20:40 +02:00
** 1.5 Aplikativni red in normalni red evalvacije
#+begin_src scheme
(define (p) (p))
(define (test x y)
(if (= x 0)
0
y))
;; Evalvira:
(test 0 (p))
#+end_src
2024-05-29 18:39:50 +02:00
Če interpreter deluje po aplikativnem zaporedju, bo najprej evalviral argumente. Ker je drugi argument postopek, ki v neskončnost vrača vrednost klica samega sebe, se bo program zaciklal oz. zmrznil.
Če pa interpreter deluje po normalnem zaporedju, bo pa začel izvajat postopek pred evalvacijo argumentov, le-te pa šele ko jih potrebuje. Tako bo, ~if~ stavek prepoznal ekvivalenco ~x~ in ~0~ ter vrnil ~0~.
Klic takšne funkcije torej preveri ali interpreter deluje po aplikativnem ali normalnem zaporedju.
Guile scheme deluje po aplikativnem redu (in se zacikla). Normalni red pa lahko "simuliramo", če proceduro definiramo kot macro, z ~define-case~. Klic macroja se ne zacikla.
#+begin_src scheme :exports both
(define-macro (test-m x y)
(if (= x 0)
0
y))
(test-m 0 (p))
#+end_src
#+RESULTS:
: 0
** 1.6 Novi if
Imamo nov ~if~, ~new-if~.
#+begin_src scheme
(define (new-if predicate then-clause else-clause)
(cond (predicate then-clause)
(else else-clause)))
#+end_src
Kaj se zgodi, če ga uporabimo za računanje kvadratnih korenov?
#+begin_src scheme
(define (sqrt-iter guess x)
(new-if (good-enough? guess x)
guess
(sqrt-iter (improve guess x)
x)))
#+end_src
Navaden ~if~ je v bistvu makro in deluje po normalnem zaporedju. Ker je ~new-if~ definiran kot procedura, mora zaradi aplikativnega zaporedja najprej evalvirati argumente. Zato se zacikla oz. zamrzne.
** 1.7 good-enough? ni dovolj dober?
#+begin_src scheme
(define (average x y)
(/ (+ x y) 2))
(define (improve guess x)
(average guess (/ x guess)))
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x)
x)))
(define (sqrt x)
(sqrt-iter 1.0 x))
#+end_src
Pri premajhnih številih ~good-enough?~ prehitro "odneha" in dobimo slab približek, pri prevelikih številih pa "predolgo vztraja", saj ne potrebujemo tako natančnega približka. Boljša rešitev s precej elegance je, recimo, primerjava s promilom ~x~ namesto 0.001.
#+begin_src scheme
(define (good-enough? guess x)
(< (abs (- (square guess) x)) (* 0.001 x)))
#+end_src
2024-04-30 19:20:40 +02:00
2024-05-29 18:39:50 +02:00
** 1.8 kubični koren
2024-04-30 19:20:40 +02:00
2024-05-29 18:39:50 +02:00
Formula za izboljšanje približka ~y~ kubičnemu korenu ~x~ je
\begin{equation}
\frac{x/y^{2}+2y}{3}
\end{equation}
2024-04-30 19:20:40 +02:00
2024-05-29 18:39:50 +02:00
Postopek: TODO
2024-05-29 18:34:27 +02:00
** 1.10 Ackermannov postopek
Sledeči postopek je Ackermannov:
#+begin_src scheme
(define (A x y)
(cond ((= y 0) 0)
((= x 0)
(* 2 y))
((= y 1) 2)
(else (A (- x 1)
(A x (- y 1))))))
#+end_src
Kakšni so rezultati sledečih izrazov?
2024-05-29 21:56:50 +02:00
- ~(A 1 10)~
2024-05-29 18:34:27 +02:00
2024-05-29 21:56:50 +02:00
#+begin_src scheme
2024-05-29 18:34:27 +02:00
(A 1 10)
(A 0 (A 1 9))
(A 0 (A 0 (A 1 8)))
(A 0 (A 0 (A 0 (A 1 7))))
(A 0 (A 0 (A 0 (A 0 (A 1 6)))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 1 5))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 1 4)))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 1 3))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 1 2)))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 1 1))))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 2)))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 4))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 8)))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 16))))))
(A 0 (A 0 (A 0 (A 0 (A 0 32)))))
(A 0 (A 0 (A 0 (A 0 64))))
(A 0 (A 0 (A 0 128)))
(A 0 (A 0 256))
(A 0 512)
1024
2024-05-29 21:56:50 +02:00
#+end_src
2024-05-29 18:34:27 +02:00
2024-05-29 21:56:50 +02:00
- ~(A 2 4)~
2024-05-29 18:34:27 +02:00
2024-05-29 21:56:50 +02:00
#+begin_src scheme
2024-05-29 18:34:27 +02:00
(A 2 4)
(A 1 (A 2 3))
(A 1 (A 1 (A 2 2)))
(A 1 (A 1 (A 1 (A 2 1)))
(A 1 (A 1 (A 1 2)))
(A 1 (A 1 (A 1 2)))
(A 1 (A 1 (A 0 (A 1 1)))
(A 1 (A 1 (A 0 2)))
(A 1 (A 1 (A 0 2)))
(A 1 (A 1 4))
(A 1 (A 0 (A 1 3)))
(A 1 (A 0 (A 0 (A 1 2))))
(A 1 (A 0 (A 0 (A 0 (A 1 1)))))
(A 1 (A 0 (A 0 (A 0 2))))
(A 1 (A 0 (A 0 4)))
(A 1 (A 0 8))
(A 1 16)
(A 0 (A 1 15))
(A 0 (A 0 (A 1 14))
...
(A 0 (A 0 (A 1 14))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 1))))))))))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 2)))))))))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 4))))))))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 8)))))))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 16))))))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 32)))))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 64))))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 128)))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 256))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 512)))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 1024))))))
(A 0 (A 0 (A 0 (A 0 (A 0 2048)))))
(A 0 (A 0 (A 0 (A 0 4096))))
(A 0 (A 0 (A 0 8192)))
(A 0 (A 0 16384))
(A 0 32768)
65536
2024-05-29 21:56:50 +02:00
#+end_src
2024-05-29 18:34:27 +02:00
2024-05-29 21:56:50 +02:00
- ~(A 3 3)~
#+begin_src scheme
2024-05-29 18:34:27 +02:00
(A 3 3)
(A 2 (A 3 2))
(A 2 (A 2 (A 3 1)))
(A 2 (A 2 2))
(A 2 (A 1 (A 2 1)))
(A 2 (A 1 2))
(A 2 (A 0 (A 1 1)))
(A 2 (A 0 2))
(A 2 4)
(A 1 (A 2 3))
(A 1 (A 1 (A 2 2)))
(A 1 (A 1 (A 1 (A 2 1))))
(A 1 (A 1 (A 1 2)))
(A 1 (A 1 (A 0 (A 1 1))))
(A 1 (A 1 (A 0 2)))
(A 1 (A 1 4))
(A 1 (A 0 (A 1 3)))
(A 1 (A 0 (A 0 (A 1 2))))
(A 1 (A 0 (A 0 (A 0 (A 1 1)))))
(A 1 (A 0 (A 0 (A 0 2))))
(A 1 (A 0 (A 0 4)))
(A 1 (A 0 8))
(A 1 16)
65536
2024-05-29 21:56:50 +02:00
#+end_src
2024-05-29 18:34:27 +02:00
Če imamo še sledeče postopke:
#+begin_src scheme
(define (f n) (A 0 n))
(define (g n) (A 1 n))
(define (h n ) (A 2 n))
(define (k n) (* 5 n n))
#+end_src
2024-05-29 21:56:50 +02:00
Jedrnato opredeli matematične funkcije izračuna postopkov ~f~, ~g~ in ~h~. ~k~, recimo izračuna ~5n^2~.
#+begin_quote
~f~: 2n
#+end_quote
#+begin_quote
~g~: 2^n
#+end_quote
2024-05-29 18:34:27 +02:00
#+begin_quote
2024-05-29 21:56:50 +02:00
~h~: 2^{2^n}
2024-05-29 18:34:27 +02:00
#+end_quote