<< 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

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))))

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))))
```

CS 61A notes https://people.eecs.berkeley.edu/~bh/61a-pages/Solutions/week1 give one interesting recursive call implementation

```
(define (sum-square-large papa mama baby)
(define (square x) (* x x))
(cond ((> mama papa) (sum-square-large mama papa baby))
((> baby mama) (sum-square-large papa baby mama))
(else (+ (square papa) (square mama)))))
```

Here it just ensure the sequence is strictly decreasing, otherwise swapping 2 items found not to meet this decreasing property. Then at the most inner call `papa mama` will be the 2 larger numbers.

It also refers to one interesting link https://code.google.com/archive/p/jrm-code-project/wikis/ProgrammingArt.wiki

```
(define (sum-square-largest x y z)
(cond
;; x is smallest
((and (< x y) (< x z)) (+ (* y y) (* z z)))
(else (sum-square-largest y z x))))
```

This works by finding the smallest number by the recursive call.

```
(define (sls x y z)
(cond ((> z x) (sls z y x))
((> z y) (sls x z y))
(else (+ (* x x) (* y y)))))
```

This works similarly but uses swapping instead of shifting.

----------

key quote excerpt about "art" related with the above codes from the above 2nd link:

> I don't think that the short version is more artistic than the long

> The code above is art in that I wrote it for no purpose other than to *communicate some humor*. It is not intended to be an example of good programming any more than an Escher print is intended to be an example of an architectural plan. I wouldn't consider it fine art either.

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