timothy235 icon

sicp-2-2-2-hierarchical-structures

timothy235 | PRO | 12/19/24 01:19:44 AM UTC (Edited) | 0 ⭐ | 383 👁️ | Never ⏰ | []
Racket |

6.16 KB

|

None

|

0 👍

/

0 👎

#lang racket
 
;;;;;;;;;;
;; 2.24 ;;
;;;;;;;;;;
 
(list 1 (list 2 (list 3 4)))
;; '(1 (2 (3 4)))
 
;; Note that, at each nesting level, there is one cons cell for each list element.
;; If the list element is an atom, the car points to the atom.  If the list
;; element is a sub-list, the car points to a new cons cell.
 
;; car | cdr ----> car | cdr ----> empty
 ;; |               |
 ;; 1              car | cdr ----> car | cdr ----> empty
                 ;; |               |
                 ;; 2              car | cdr ----> car | cdr ----> empty
                                 ;; |               |
                                 ;; 3               4
 
;; (list 1 (list 2 (list 3 4)))
    ;; |       \
    ;; 1       (list 2 (list 3 4))
                ;; |       \
                ;; 2       (list 3 4)
                            ;; |   \
                            ;; 3    4
 
;;;;;;;;;;
;; 2.25 ;;
;;;;;;;;;;
 
;; Note that a car composed with n - 1 cdr's selects the n-th element of a list.
 
(define nl1 (list 1 3 (list 5 7) 9))
(car (cdr (car (cdr (cdr nl1)))))
;; 7
(second (third nl1))
;; 7
 
(define nl2 (list (list 7)))
(car  (car nl2))
;; 7
(first (first nl2))
;; 7
 
(define nl3 (list 1 (list 2 (list 3 (list 4 (list 5 (list 6 7)))))))
(car (cdr (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr nl3))))))))))))
;; 7
(second (second (second (second (second (second nl3))))))
;; 7
 
;;;;;;;;;;
;; 2.26 ;;
;;;;;;;;;;
 
(define x (list 1 2 3))
(define y (list 4 5 6))
 
(append x y)
;; '(1 2 3 4 5 6)
(cons x y)
;; '((1 2 3) 4 5 6)
(list x y)
;; '((1 2 3) (4 5 6))
 
;;;;;;;;;;
;; 2.27 ;;
;;;;;;;;;;
 
(define (my-reverse lst)
  (define (iter old-lst new-lst)
    (if (empty? old-lst)
      new-lst
      (iter (rest old-lst) (cons (first old-lst) new-lst))))
  (iter lst empty))
 
(my-reverse (list (list 1 2) (list 3 4)))
;; '((3 4) (1 2))
 
(define (deep-reverse lst)
  (define (iter old-lst new-lst)
    (cond [(empty? old-lst) new-lst]
          [(pair? (first old-lst))
           (iter (rest old-lst)
                 (cons (deep-reverse (first old-lst)) new-lst))]
          [else (iter (rest old-lst)
                      (cons (first old-lst) new-lst))]))
  (iter lst empty))
 
(deep-reverse (list (list 1 2) (list 3 4)))
;; '((4 3) (2 1))
 
;;;;;;;;;;
;; 2.28 ;;
;;;;;;;;;;
 
;; Use recursion instead of iteration to keep the order.
;; Use append for sub-lists instead of cons to flatten the list.
 
(define (fringe lst)
  (cond [(empty? lst) empty]
        [(pair? (first lst))
         (append (fringe (first lst)) (fringe (rest lst)))]
        [else (cons (first lst) (fringe (rest lst)))]))
 
(fringe (list (list 1 2) (list 3 4)))
;; '(1 2 3 4)
 
;;;;;;;;;;
;; 2.29 ;;
;;;;;;;;;;
 
(define (make-mobile left right) (list left right))
(define (make-branch len str) (list len str))
(define (left-branch mobile) (first mobile))
(define (right-branch mobile) (second mobile))
(define (branch-length branch) (first branch))
(define (branch-structure branch) (second branch)) ; can be a weight or a mobile
 
(define (is-branch-mobile? branch)
  (list? (branch-structure branch)))
 
(define (total-branch-weight branch)
  (if (is-branch-mobile? branch)
    (total-weight (branch-structure branch))
    (branch-structure branch)))
 
(define (total-weight mobile)
  (+ (total-branch-weight (left-branch mobile))
     (total-branch-weight (right-branch mobile))))
 
(define (branch-balanced? branch)
  (if (is-branch-mobile? branch)
    (balanced? (branch-structure branch))
    #t))
 
(define (balanced? mobile)
  (and (branch-balanced? (left-branch mobile))
       (branch-balanced? (right-branch mobile))
       (= (* (branch-length (left-branch mobile))
             (total-branch-weight (left-branch mobile)))
          (* (branch-length (right-branch mobile))
             (total-branch-weight (right-branch mobile))))))
 
(define mobile1
  (make-mobile (make-branch 1 2)
               (make-branch 2 1)))
(total-weight mobile1)
;; 3
(balanced? mobile1)
;; #t
 
(define mobile2
  (make-mobile (make-branch 1 3)
               (make-branch 2 2)))
(total-weight mobile2)
;; 5
(balanced? mobile2)
;; #f
 
(define mobile3
  (make-mobile (make-branch 3 2)
               (make-branch 2 mobile1)))
(total-weight mobile3)
;; 5
(balanced? mobile3)
;; #t
 
;; If we changed the mobile and branch constructors to use cons instead of list,
;; then we would have to change the selectors to use first and rest instead of
;; first and second.  Nothing else would have to change.
 
;;;;;;;;;;
;; 2.30 ;;
;;;;;;;;;;
 
(define (square-tree tree)
  (cond [(empty? tree) empty]
        [(pair? (first tree))
         (cons (square-tree (first tree))
               (square-tree (rest tree)))]
        [else (cons (sqr (first tree))
                    (square-tree (rest tree)))]))
 
(square-tree (list (list 1 2) (list 3 4)))
;; '((1 4) (9 16))
 
(define (square-tree2 tree)
  (map (lambda (sub-tree)
         (if (pair? sub-tree)
           (square-tree2 sub-tree)
           (sqr sub-tree)))
       tree))
 
(square-tree2 (list (list 1 2) (list 3 4)))
;; '((1 4) (9 16))
 
;;;;;;;;;;
;; 2.31 ;;
;;;;;;;;;;
 
(define (tree-map proc tree)
  (map (lambda (sub-tree)
         (if (pair? sub-tree)
           (tree-map proc sub-tree)
           (proc sub-tree)))
       tree))
 
(define (square-tree3 tree) (tree-map sqr tree))
 
(square-tree3 (list (list 1 2) (list 3 4)))
;; '((1 4) (9 16))
 
;;;;;;;;;;
;; 2.32 ;;
;;;;;;;;;;
 
(define (subsets s)
  (cond [(empty? s) (list empty)]
        [else
          (define rst (subsets (rest s)))
          (append rst
                  (map (lambda (st) (cons (first s) st))
                       rst))]))
 
;; For any element x of a non-empty set, the set of all subsets can be evenly
;; split into two collections, those subsets that contain x and those that don't.
;; Furthermore, the collection of subsets that do contain x looks exactly like
;; the collection of subsets that do not contain x, except that each has had x
;; added to it.
 
(subsets (list 1 2))
;; '(() (2) (1) (1 2))
 
(subsets (list 1 2 3))
;; '(() (3) (2) (2 3) (1) (1 3) (1 2) (1 2 3))

Comments