From 1bdb0c666c16036b73208aba3bed96240b7bafc3 Mon Sep 17 00:00:00 2001 From: Thorn Avery Date: Sat, 21 Aug 2021 06:45:26 +0000 Subject: [PATCH] first commit --- .gitignore | 2 ++ 1/1/1.md | 12 ++++++++++++ 1/1/2.scm | 11 +++++++++++ 1/1/3.scm | 23 +++++++++++++++++++++++ 1/1/4.md | 1 + 1/1/5.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1/1/6.md | 5 +++++ 1/1/7.scm | 35 +++++++++++++++++++++++++++++++++++ 1/1/8.scm | 27 +++++++++++++++++++++++++++ README.md | 7 +++++++ 10 files changed, 173 insertions(+) create mode 100644 .gitignore create mode 100644 1/1/1.md create mode 100644 1/1/2.scm create mode 100644 1/1/3.scm create mode 100644 1/1/4.md create mode 100644 1/1/5.md create mode 100644 1/1/6.md create mode 100644 1/1/7.scm create mode 100644 1/1/8.scm create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d38c149 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.swp +*~ diff --git a/1/1/1.md b/1/1/1.md new file mode 100644 index 0000000..787e310 --- /dev/null +++ b/1/1/1.md @@ -0,0 +1,12 @@ +10 +12 +8 +3 +6 +19 +#f +4 +16 +6 +16 + diff --git a/1/1/2.scm b/1/1/2.scm new file mode 100644 index 0000000..6e89bc2 --- /dev/null +++ b/1/1/2.scm @@ -0,0 +1,11 @@ +#lang sicp + +(/ (+ 5 + 4 + (- 2 + (- 3 + (+ 6 + (/ 4 5))))) + (* 3 + (- 6 2) + (- 2 7))) diff --git a/1/1/3.scm b/1/1/3.scm new file mode 100644 index 0000000..a42d9ae --- /dev/null +++ b/1/1/3.scm @@ -0,0 +1,23 @@ +#lang sicp + +(define (square x) + (* x x)) + +(define (sum-of-squares x y) + (+ (square x) (square y))) + +(define (foo x y z) + (if (> x y) + (if (> y z) + (sum-of-squares x y) + (sum-of-squares x z)) + (if (> x z) + (sum-of-squares x y) + (sum-of-squares y z)))) + +(foo 1 2 3) +(foo 1 3 2) +(foo 2 1 3) +(foo 2 3 1) +(foo 3 1 2) +(foo 3 2 1) diff --git a/1/1/4.md b/1/1/4.md new file mode 100644 index 0000000..0f5de03 --- /dev/null +++ b/1/1/4.md @@ -0,0 +1 @@ +the application procedure will first evaluate the if statement, resulting in one of the symbols `+` or `-`. this will be the value of the first place within the outer set of brackets, which will determine which procedure is used during application of the rest of the procedure. diff --git a/1/1/5.md b/1/1/5.md new file mode 100644 index 0000000..a4365b6 --- /dev/null +++ b/1/1/5.md @@ -0,0 +1,50 @@ +when evaluating the procedure: + +``` +(define (p) (p)) + +(define (test x y) + (if (= x 0) + 0 + y)) +``` + +by evaluating: + +``` +(test 0 (p)) +``` + +under both normal order and applicative order evaluation, you will see; + +## applicative order + +under applicative order evaluation, we would first fully evaluate any arguments to a procedure, then evaluate the procedure with those values. + +to evaluate `(test 0 (p)` we would first need to evaluate `0` and `(p)` + +`0` is a primitive value, and thus evaluates to the value `0`. + +`(p)` is a procedure in the global environment, defined as `(p)`. we would recieve a value of `(p)`, which according to our evaluation strategy would need to be fully evaluated before we can continue evaluating `(test 0 (p))`. this would create an infinite loop as we would never reach a value of `(p)` that doesnt require further evaluation, and our program will hang. + +## normal order + +under normal order, we do not evaluate arguments until they are needed. thus, to evaluate `(test 0 (p))`, the following steps are taken: + +``` +(test 0 (p)) + +(if (= 0 0) 0 (p)) + +(if #t 0 (p)) + +0 +``` + +the first line is our initial procedure application +the second is our definition of `test`, with the substitutions `x` -> `0` and `y` -> `(p)`. +the special form `if` will only evaluate the third argument, if the first (the predicate) is false. +the third line is the aftermath of evaluating `(= 0 0)` in order to check the value of our predicate, which is `true`. +the fourth line is the result of the `if` procedure, returning `0`. + +notably, as we are following normal order application, we never needed to evaluate `(p)` (thus avoiding hanging our program). however had the predicate to the `if` procedure returned `false`, we would then need to evaluate `(p)` to find a value for the wider `if` application, and enter a loop. diff --git a/1/1/6.md b/1/1/6.md new file mode 100644 index 0000000..de030d4 --- /dev/null +++ b/1/1/6.md @@ -0,0 +1,5 @@ +when attempting to compute square roots using the new `new-if` procedure (which acts as `if` however is not a special form), all three of the arguments to `new-if` must be fully evaluated before the `new-if` can return a value. this is in contrast to the special form `if` which only ever evaluates one of the second and third arguments, conditional on the first argument. + +in this case, even if the current guess is good enough (indicating that the second argument of the `new-if` should be returned) the procedure is still required to evaluate the third argument, which contains a recursive call. + +as such, using the non-special form `new-if` will never return a value, as it has no way of stopping evaluation once a good enough answer has been found. diff --git a/1/1/7.scm b/1/1/7.scm new file mode 100644 index 0000000..d9a17e9 --- /dev/null +++ b/1/1/7.scm @@ -0,0 +1,35 @@ +(define (sqrt-iter guess x) + (if (good-enough? guess x) + guess + (sqrt-iter (improve guess x) x))) + +(define (improve guess x) + (average guess (/ x guess))) + +(define (average x y) + (/ (+ x y) 2)) + +(define (square x) + (* x x)) + +(define (good-enough? guess x) + (< (abs (- (square guess) + x)) + 0.001)) + +(define (my-good-enough? guess prev-guess) + (< (abs (- guess prev-guess)) + (/ guess 100000))) + +(define (my-sqrt-iter guess prev-guess x) + (if (my-good-enough? guess prev-guess) + guess + (my-sqrt-iter (improve guess x) + guess + x))) + +(define (my-sqrt x) + (my-sqrt-iter 1.0 (improve 1.0 x) x)) + +(define (sqrt x) + (sqrt-iter 1.0 x)) diff --git a/1/1/8.scm b/1/1/8.scm new file mode 100644 index 0000000..25e0626 --- /dev/null +++ b/1/1/8.scm @@ -0,0 +1,27 @@ +(define (improve guess x) + (/ (+ (/ x (square guess)) + (* 2 guess)) + 3)) + +(define (average x y) + (/ (+ x y) 2)) + +(define (square x) + (* x x)) + +(define (cube x) + (* x x x)) + +(define (my-good-enough? guess prev-guess) + (< (abs (- guess prev-guess)) + (/ guess 100000))) + +(define (my-cube-root-iter guess prev-guess x) + (if (my-good-enough? guess prev-guess) + guess + (my-cube-root-iter (improve guess x) + guess + x))) + +(define (my-cube-root x) + (my-cube-root-iter 1.0 (improve 1.0 x) x)) diff --git a/README.md b/README.md new file mode 100644 index 0000000..28883d5 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# SICP + +answers to SICP exercises. + +answered in `#lang sicp` for racket. + +can be installed with `raco pkg install sicp`