#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