1

Exercise 1.3 in SICP asks to define a procedure that takes 3 numbers as arguments and returns the sum of the squares of the 2 largest numbers. I think I've gotten it correct but I wasn't totally sure if I've covered all cases. My implementation is as follows:

(define (bigsq a b c)
    (cond ((and (> a b) (> b c)) (+ (* a a) (* b b)))
          ((and (> a b) (not (> b c))) (+ (* a a) (* c c)))
          ((> c a) (+ (* b b) (* c c)))
          (else (+ (* a a) (* b b))))

Is there a way to write those first 2 conditions as one, as well? Also any comments on efficiency are welcome as well.

ad absurdum
  • 19,498
  • 5
  • 37
  • 60
lamyvista
  • 113
  • 3
  • @Renzo The question is whether the code is correct. The part about style is an aside. – Barmar Apr 26 '20 at 04:26
  • `(not (> b c))` is `(<= b c)` – Barmar Apr 26 '20 at 04:29
  • 3
    You should be able to generate test cases for all the possibilities, there aren't that many of them. There are 6 permutations of 3 different numbers, 1 permutation of 3 same numbers. When 2 of them are equal, there are 3 permutations where the third is highest, and 3 permutations where the third is lowest. So 13 total cases to test. – Barmar Apr 26 '20 at 04:35
  • The book up until that point made it seem like <= wasn't a built in operator so I just went with the negation. Will try enumerating all possibilities for my test cases. – lamyvista Apr 26 '20 at 04:41
  • Personally I agree with only using features that are introduced up to that point in the book, but in that spirit you should consider using the sum-square procedure introduced earlier in the section. (fwiw it may be inisgnificantly more efficient to use 'if' instead of 'cond' https://stackoverflow.com/a/610719/53252) – codybartfast Apr 26 '20 at 07:55

1 Answers1

1

For starters, we could use a helper procedure for implementing the sum just once:

(define (sum x y)
  (+ (* x x) (* y y)))

Now, for the conditions: given that the order doesn't matter - (sum a b) is the same as (sum b a), there's only 4 cases to consider, and we can avoid repeating some of the comparisons by nesting ifs:

(define (sum-max a b c)
  (if (>= a b)
      (if (>= b c)
          (sum a b)
          (sum a c))
      (if (>= a c)
          (sum b a)
          (sum b c))))
Óscar López
  • 232,561
  • 37
  • 312
  • 386