learning-sicp

My embarrassing half assed SICP run.
Log | Files | Refs

commit 2d18dbc20b1e1a9099397209c5c67daa6304b508
parent fb2fbcfe232da967776c979fba70148aa9f6302c
Author: Yuval Langer <yuval.langer@gmail.com>
Date:   Sun,  2 Apr 2023 16:32:36 +0300

Add more solutions.

Diffstat:
Asicp/solutions/2_73.scm | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asicp/solutions/3_2.scm | 18++++++++++++++++++
Asicp/solutions/3_3.scm | 27+++++++++++++++++++++++++++
Asicp/tests/2_73.scm | 14++++++++++++++
Asicp/tests/3_2.scm | 29+++++++++++++++++++++++++++++
Asicp/tests/3_3.scm | 14++++++++++++++
6 files changed, 212 insertions(+), 0 deletions(-)

diff --git a/sicp/solutions/2_73.scm b/sicp/solutions/2_73.scm @@ -0,0 +1,110 @@ +(define-library (sicp solutions 2_73) + (import (scheme base)) + (import (scheme cxr)) + (import (scheme write)) + (import (srfi :26)) + (import (srfi :111)) + (import (sicp utils)) + (import (only (sicp solutions 2_56) + =number? + make-exponentiation + make-product + make-sum + same-variable? + )) + (export deriv + get + put) + + (begin + (define put-get-table '()) + + (define (put operator data-type proc) + (define new-key (cons operator data-type)) + (define new-key-value-pair (cons new-key proc)) + (set! put-get-table + (cons new-key-value-pair + (filter + (lambda (key-value-pair) + (not + (equal? + (car key-value-pair) + new-key))) + put-get-table)))) + + (define (get op data-type) + (define search-result + (filter (lambda (key-value-pair) + (equal? + (cons op data-type) + (car key-value-pair))) + put-get-table)) + (if (null? search-result) + (error "Unknown expression type: " op data-type) + (cdar search-result))) + + (define (operator exp) + (car exp)) + + (define (operands exp) + (cdr exp)) + + (define (variable? exp) + (symbol? exp)) + + (define (deriv exp var) + (cond + ((number? exp) 0) + ((variable? exp) + (if (same-variable? exp var) + 1 + 0)) + (else + ((get 'deriv (operator exp)) + (operands exp) + var)))) + + (define (addend exp) + (car exp)) + + (define (augend exp) + (cadr exp)) + + (put 'deriv + '+ + (lambda (exp var) + (display (list 'deriv '+ exp var)) + (newline) + (make-sum + (deriv (addend exp) var) + (deriv (augend exp) var)))) + + (define (multiplier p) + (car p)) + + (define (multiplicand p) + (cadr p)) + + (put 'deriv + '* + (lambda (exp var) + (make-sum + (make-product (multiplier exp) + (deriv (multiplicand exp) var)) + (make-product (deriv (multiplier exp) var) + (multiplicand exp))))) + + (define (base e) + (car e)) + + (define (exponent e) + (cadr e)) + + (put 'deriv + '** + (lambda (exp var) + (display (list 'deriv '** exp var)) + (newline) + (make-product (exponent exp) + (make-exponentiation (base exp) + (make-sum (exponent exp) -1))))))) diff --git a/sicp/solutions/3_2.scm b/sicp/solutions/3_2.scm @@ -0,0 +1,18 @@ +(define-library (sicp solutions 3_2) + (import (scheme base)) + (export make-monitored) + + (begin + (define (make-monitored proc) + (define number-of-calls 0) + + (lambda (input) + (cond + ((eq? input 'how-many-calls?) + number-of-calls) + ((eq? input 'reset-count) + (set! number-of-calls 0)) + (else + (set! number-of-calls + (+ 1 number-of-calls)) + (proc input))))))) diff --git a/sicp/solutions/3_3.scm b/sicp/solutions/3_3.scm @@ -0,0 +1,27 @@ +(define-library (sicp solutions 3_3) + (import (scheme base)) + (export make-account) + + (begin + (define (make-account balance super-secret-symbol) + (define (withdraw amount) + (if (>= balance amount) + (begin + (set! balance + (- balance + amount)) + balance) + "Insufficient funds")) + + (define (deposit amount) + (set! balance (+ balance + amount)) + balance) + + (lambda (whisper m) + (if (eq? whisper super-secret-symbol) + (cond + ((eq? m 'withdraw) withdraw) + ((eq? m 'deposit) deposit) + (else (error "Uknown request: MAKE-ACCOUNT" m))) + (lambda x "Incorrect password")))))) diff --git a/sicp/tests/2_73.scm b/sicp/tests/2_73.scm @@ -0,0 +1,14 @@ +(import (srfi :64)) +(import (sicp solutions 2_73)) + +(display (deriv '(+ x 1) 'x)) (newline) +(display (deriv '(* (* x x) x) 'x)) (newline) +(display (deriv '(** x 2) 'x)) (newline) + +;; (put 'a 'b map) + +;; (write ((get 'a 'b) 1+ '(1 2 3))) (newline) + +;; (test-begin "2.73") +;; (test-equal 1 1) +;; (test-end "2.73") diff --git a/sicp/tests/3_2.scm b/sicp/tests/3_2.scm @@ -0,0 +1,29 @@ +(import (srfi :64)) +(import (sicp solutions 3_2)) + +(define s (make-monitored sqrt)) + +(test-begin "3.2") +(test-equal + 0 + (s 'how-many-calls?)) +(test-equal + 10 + (s 100)) +(test-equal + 1 + (s 'how-many-calls?)) +(s 100) +(s 100) +(test-equal + 3 + (s 'how-many-calls?)) +(s 'reset-count) +(s 100) +(s 100) +(s 100) +(s 100) +(test-equal + 4 + (s 'how-many-calls?)) +(test-end "3.2") diff --git a/sicp/tests/3_3.scm b/sicp/tests/3_3.scm @@ -0,0 +1,14 @@ +(import (srfi :64)) +(import (sicp solutions 3_3)) + +(define acc + (make-account 100 'secret-password)) + +(test-begin "3.3") +(test-equal + 60 + ((acc 'secret-password 'withdraw) 40)) +(test-equal + "Incorrect password" + ((acc 'some-other-password 'deposit) 50)) +(test-end "3.3")