2
\$\begingroup\$

I'm reading Structure and Interpretation of Computer Programs. In the first exercise, I came across a programming problem to add the squares of the 2 bigger numbers out of 3 numbers.

I came up with the following procedure:

(define (sum-of-larger-two a b c)
  (
    if (> a b) 
      (if (> b c) 
        (+ (* a a) (* b b)) 
        (+ (* a a) (* c c))
      )
      (if (> c a)
        (+ (* b b) (* c c))
        (+ (* b b) (* a a))
      )
  )
)

Is there a more succinct way to write this program?

\$\endgroup\$
2
  • \$\begingroup\$ Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles. \$\endgroup\$ Nov 1, 2019 at 11:28
  • \$\begingroup\$ @TobySpeight Does the new title solve the issue. \$\endgroup\$
    – pacmaninbw
    Nov 1, 2019 at 11:52

1 Answer 1

4
\$\begingroup\$

One of the ways of obtaining concision is by “astracting” a repeated operation to define a new function. For instance in this case you could use the square function previously defined in that chapter.

But if you look at the expression (square a) you will discover that it is longer then (* a a), even it is, in some sense, more readable (has a minor number of symbols, so it is simpler to understand).

But having a function to abstract an operation could have other benefits that an immediate reduction in the count of the characters. Consider that in your example you are comparing two numbers to find the larger between them: in other words, you are looking for their maximum.

So, let's define a new maximum operator:

(define (max a b)
  (if (> a b) a b)

Then, having the functions square and max you can now combine them, like, for instance, in:

(define (sum-of-larger-two a b c)
  (if (> a b)
      (+ (square a)
         (square (max b c)))
      (+ (square b)
         (square (max a c)))))

Or you can rearrange the operations in this way:

(define (sum-of-larger-two a b c)
  (+ (square (max a b))
     (square (if (= (max a b) a)
                 (max b c)
                 (max a c)))))

Note that we are reducing the number of conditions to check in the function sum-of-larger-two (in addition to reducing the number of lines and symbols), and so we are simplifying it, improving both its readability as well as its maintainability.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.