sicp-ex-1.3



<< Previous exercise (1.2) | sicp-solutions | Next exercise (1.4) >>


Exercise 1.3. Define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers.

 (define (square x) (* x x)) 
  
 (define (squareSum x y) (+ (square x) (square y))) 
  
 (define (sumOfLargestTwoSquared x y z) 
   (cond ((and (>= (+ x y) (+ y z)) (>= (+ x y) (+ x z))) (squareSum x y)) 
         ((and (>= (+ x z) (+ y z)) (>= (+ x z) (+ x y))) (squareSum x z)) 
         (else (squareSum y z)) 
   ) 
 ) 
 (sumOfLargestTwoSquared 1 2 3) 
 ;Value: 13 
 (sumOfLargestTwoSquared 1 1 1) 
 ;Value: 2 
 (sumOfLargestTwoSquared 1 2 2) 
 ;Value: 8 
 (sumOfLargestTwoSquared 1 1 2) 
 ;Value: 5 
 (sumOfLargestTwoSquared 1 4 3) 
 ;Value: 25 

mdsib

Here's a version with simpler logic to detect the smallest of the three values:

 (define (ssq a b) (+ (* a a) (* b b))) 
  
 (define (sumOfLargestTwoSquared x y z) 
   (cond ((and (<= x y) (<= x z)) (ssq y z)) 
         ((and (<= y x) (<= y z)) (ssq x z)) 
         (else (ssq x y)))) 

jfr

Another solution without using constructs that haven't been introduced yet

  
 (define (sum_of_squares a b) 
   (+ (* a a) (* b b))) 
  
 (define (bigger_two a b) 
   (if (> a b) 
       a 
       b)) 
  
 (define (sum_of_largest_two_squared a b c) 
   (if (> a b) 
     (sum_square a (bigger_two b c)) 
     (sum_square b (bigger_two a c)))) 

master

Another possibility (uses some language constructs that haven't been introduced yet):

  
 (define (square x) 
   (* x x)) 
  
 (define (sum-of-squares x y) 
   (+ (square x) (square y))) 
  
 (define (sum-of-squares-of-two-largest x y z) 
   (let* ((smallest (min x y z)) 
          (two-largest (remove smallest (list x y z)))) 
     (apply sum-of-squares two-largest))) 

An even simpler solution

  
 (define (square x) 
   (* x x)) 
  
 (define (sum-of-squares x y) 
   (+ (square x) (square y))) 
  
 (define (sum-of-squares-of-two-largest x y z) 
   (sum-of-squares (max x y) (max (min x y) z))) 

Another possibility

 (define (square-two-largest a b c) 
 (- (+ (* a a) (* b b) (* c c)) (* (min a b c) (min a b c)))) 
 (define (square x) (* x x)) 
 (define (sum-of-square a b) 
   (+ (square a) 
      (square b))) 
 (define (sum-square-of-two-lager a b c) 
   (- 
    (+ 
     (sum-of-square a b) 
     c) 
    (square (min a b c)) 
   ) 
 ) 

Here's yet another version.

  
 (define (sum-of-squares a b) 
   (+ (* a a) (* b b))) 
  
 (define (square-of-top a b c) 
   (cond ((= a (min a b c)) (sum-of-squares b c)) 
         ((= b (min a b c)) (sum-of-squares a c)) 
         ((= c (min a b c)) (sum-of-squares a b))))