From 8f4c2125bc971828fae901571856be25b29ae837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Kapri=C5=A1?= <kayprish@bonsai.cool> Date: Wed, 5 Feb 2025 18:13:20 +0100 Subject: [PATCH] Add solutions to exercises from subsetion 2.2.2 --- ex-2.24.txt | 20 ++++++++++++++++++ ex-2.25.txt | 3 +++ ex-2.26.txt | 3 +++ ex-2.27.scm | 15 ++++++++++++++ ex-2.28.scm | 16 ++++++++++++++ ex-2.29.scm | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ex-2.30.scm | 13 ++++++++++++ ex-2.31.scm | 7 +++++++ ex-2.32.scm | 9 ++++++++ 9 files changed, 146 insertions(+) create mode 100644 ex-2.24.txt create mode 100644 ex-2.25.txt create mode 100644 ex-2.26.txt create mode 100644 ex-2.27.scm create mode 100644 ex-2.28.scm create mode 100644 ex-2.29.scm create mode 100644 ex-2.30.scm create mode 100644 ex-2.31.scm create mode 100644 ex-2.32.scm diff --git a/ex-2.24.txt b/ex-2.24.txt new file mode 100644 index 0000000..76ad429 --- /dev/null +++ b/ex-2.24.txt @@ -0,0 +1,20 @@ +Result: +(1 (2 (3 4))) + +Box-and-pointer diagram: +[.|.] -> [.|.] -> nil + V V + 1 [.|.] -> [.|.] -> nil + V V + 2 [.|.] -> [.|.] -> nil + V V + 3 4 + +Tree structure: +(1 (2 (3 4))) + / \ +1 (2 (3 4)) + / \ + 2 (3 4) + / \ + 3 4 diff --git a/ex-2.25.txt b/ex-2.25.txt new file mode 100644 index 0000000..8acd736 --- /dev/null +++ b/ex-2.25.txt @@ -0,0 +1,3 @@ +cadaddr +caar +cadadadadadadr diff --git a/ex-2.26.txt b/ex-2.26.txt new file mode 100644 index 0000000..c61a51e --- /dev/null +++ b/ex-2.26.txt @@ -0,0 +1,3 @@ +(1 2 3 4 5 6) +((1 2 3) 4 5 6) +((1 2 3) (4 5 6)) diff --git a/ex-2.27.scm b/ex-2.27.scm new file mode 100644 index 0000000..a5a75d1 --- /dev/null +++ b/ex-2.27.scm @@ -0,0 +1,15 @@ +#lang sicp + +(define (dr-aux x acc) + (if (null? x) + acc + (let ((head (car x)) + (tail (cdr x))) + (if (pair? head) + (dr-aux tail + (cons (deep-reverse head) + acc)) + (dr-aux tail + (cons head acc)))))) +(define (deep-reverse x) + (dr-aux x '())) diff --git a/ex-2.28.scm b/ex-2.28.scm new file mode 100644 index 0000000..ea41c4e --- /dev/null +++ b/ex-2.28.scm @@ -0,0 +1,16 @@ +#lang sicp + +(define (list? x) + (or (null? x) (pair? x))) + +(define (fringe tree) + (if (null? tree) + '() + (let* ((head (car tree)) + (tail (cdr tree)) + (h-list (if (list? head) ; if it's a subtree + (fringe head) ; turn it into a list + ; otherwise, just make a + ; one-element list + (list head)))) + (append h-list (fringe tail))))) diff --git a/ex-2.29.scm b/ex-2.29.scm new file mode 100644 index 0000000..b87ab26 --- /dev/null +++ b/ex-2.29.scm @@ -0,0 +1,60 @@ +#lang sicp + +(define (make-mobile left right) + (list left right)) +; a. part 1 +(define (left-branch mobile) + (car mobile)) +(define (right-branch mobile) + (cadr mobile)) + +(define (make-branch length structure) + (list length structure)) + +; a. part 2 +(define (branch-length branch) + (car branch)) +(define (branch-structure branch) + (cadr branch)) + +; b +(define (total-weight mobile) + (if (number? mobile) + mobile + (+ (total-weight (branch-structure (left-branch mobile))) + (total-weight (branch-structure (right-branch mobile)))))) + +; c, with O(n) complexity, because the basic algorithm would +; recalculate weights of lower level submobiles, each node is +; calculated h times, where h is the number of it's ancestors +; for a typical mobile, this would cause the complexity to be +; O(log(n) * n) +(define (mobile-balanced? mobile) + ; this returns a pair, a bool describing whether the mobile + ; is balanced, and a number, describing the total weight of + ; the mobile + (define (balanced-aux mobile) + (if (number? mobile) + (cons #t mobile) + (let* ((left-submobile (branch-structure (left-branch mobile))) + (right-submobile (branch-structure (right-branch mobile))) + (len-left (branch-length (left-branch mobile))) + (len-right (branch-length (right-branch mobile))) + (bal-aux-left (balanced-aux left-submobile)) + (bal-aux-right (balanced-aux right-submobile)) + (balanced-left? (car bal-aux-left)) + (balanced-right? (car bal-aux-right)) + (weight-left (cdr bal-aux-left)) + (weight-right (cdr bal-aux-right))) + (cons (and balanced-left? + balanced-right? + (= (* weight-left len-left) + (* weight-right len-right))) + (+ weight-left weight-right))))) + (car (balanced-aux mobile))) +; d. The way we wrote the code so far, we've managed to +; cleanly separate the internals of the mobile and branch +; structures from the code which uses them, so the only thing +; that needs to be changed is the selectors. In this case in +; particular, we only need to change the right-branch, and +; branch-structure selectors, by changing the cadr into a cdr diff --git a/ex-2.30.scm b/ex-2.30.scm new file mode 100644 index 0000000..39d3072 --- /dev/null +++ b/ex-2.30.scm @@ -0,0 +1,13 @@ +#lang sicp + +(define (square x) (* x x)) + +;(define (square-tree tree) +; (cond ((null? tree) '()) +; ((number? tree) (square tree)) +; (else (cons (square-tree (car tree)) +; (square-tree (cdr tree)))))) +(define (square-tree tree) + (if (number? tree) + (square tree) + (map square-tree tree))) diff --git a/ex-2.31.scm b/ex-2.31.scm new file mode 100644 index 0000000..b712bcd --- /dev/null +++ b/ex-2.31.scm @@ -0,0 +1,7 @@ +#lang sicp + +(define (tree-map f tree) + (cond ((null? tree) '()) + ((pair? tree) (cons (tree-map f (car tree)) + (tree-map f (cdr tree)))) + (else (f tree)))) diff --git a/ex-2.32.scm b/ex-2.32.scm new file mode 100644 index 0000000..3e90d85 --- /dev/null +++ b/ex-2.32.scm @@ -0,0 +1,9 @@ +#lang sicp + +(define (subsets s) + (if (null? s) + (list nil) + (let ((rest (subsets (cdr s)))) + (append rest (map (lambda (set) (cons (car s) + set)) + rest)))))