SICP Exercise 1.3 request for comments

What about something like this?

(define (p a b c)
  (if (> a b)
      (if (> b c)
          (+ (square a) (square b))
          (+ (square a) (square c)))
      (if (> a c)
          (+ (square a) (square b))
          (+ (square b) (square c)))))

Using only the concepts presented at that point of the book, I would do it:

(define (square x) (* x x))

(define (sum-of-squares x y) (+ (square x) (square y)))

(define (min x y) (if (< x y) x y))

(define (max x y) (if (> x y) x y))

(define (sum-squares-2-biggest x y z)
  (sum-of-squares (max x y) (max z (min x y))))

big is called max. Use standard library functionality when it's there.

My approach is different. Rather than lots of tests, I simply add the squares of all three, then subtract the square of the smallest one.

(define (exercise1.3 a b c)
  (let ((smallest (min a b c))
        (square (lambda (x) (* x x))))
    (+ (square a) (square b) (square c) (- (square smallest)))))

Whether you prefer this approach, or a bunch of if tests, is up to you, of course.


Alternative implementation using SRFI 95:

(define (exercise1.3 . args)
  (let ((sorted (sort! args >))
        (square (lambda (x) (* x x))))
    (+ (square (car sorted)) (square (cadr sorted)))))

As above, but as a one-liner (thanks synx @ freenode #scheme); also requires SRFI 1 and SRFI 26:

(define (exercise1.3 . args)
  (apply + (map! (cut expt <> 2) (take! (sort! args >) 2))))

Tags:

Scheme

Sicp