60 lines
2.2 KiB
Scheme
60 lines
2.2 KiB
Scheme
#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
|