schemesicp

Scheme: Returning two largest numbers from a set of three numbers


I am supposed to write a function that prints the sum of squares of the two greater numbers out of a set of given three numbers.

I have handled the situation rather clumsily. Instead of writing a function that returns the two largest numbers out of a set of 3, I have written the function so that expressions reduce to the two required numbers. # SSL function.

The reason I had to do this was that I could not write a LISP function that could return multiple values together, and I could not write a LISP function that could read two values as an argument.

Is there a way that I can abstract out the calculation of the largest number in some other procedure?

(define
    (min a b)
    (if (> a b) b a)
)

(define
    (max a b)
    (if (< a b) b a)
)


(define
    (square a)
    ( * a a)
)



(define 
    (ssl a b c)
    (+ (square (max a b)) (square (max (min a b) c)))
)

Solution

  • As usual, it's a good idea to split the problem in subproblems which are easier to solve; I'll explain how to write a solution and at the same time I'll answer your questions. First, let's find out the two greatest numbers out of three and return them in a list - this is a simple, portable way to return multiple values:

    (define (max-two a b c)
      (if (>= a b)
          (if (>= b c)
              (list a b)
              (list a c))
          (if (>= a c)
              (list b a)
              (list b c))))
    

    Now let's write a procedure that takes as input two numbers, squares them and then adds the results - this is how we can declare a function that receives multiple values as arguments:

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

    Finally, let's compose the procedures to obtain the answer - we'll use apply for applying sum-square (a function that receives two parameters) to the result returned by max-two (a list with two elements) - this is how we can process the multiple values returned by max-two:

    (define (sum-max a b c)
      (apply sum-square (max-two a b c)))
    

    The result is as expected:

    (sum-max 3 1 2)
    => 13