## Exercise 6

### September 27, 2019

Since the textbook is about C++, we’ll write our solution in an imperative style, following Stroustrup’s solution as closely as possible:

(define (exercise6) (let* ((val1 (read)) (val2 (read)) (val3 (read)) (smallest 0) (middle 0) (largest 0)) (cond ((and (<= val1 val2) (<= val1 val3)) (set! smallest val1) (cond ((<= val2 val3) (set! middle val2) (set! largest val3)) (else (set! middle val3) (set! largest val2)))) ((and (<= val2 val1) (<= val2 val3)) (set! smallest val2) (cond ((<= val1 val3) (set! middle val1) (set! largest val3)) (else (set! middle val3) (set! largest val2)))) (else (set! smallest val3) (cond ((<= val1 val2) (set! middle val1) (set! largest val2)) (else (set! middle val2) (set! largest val3))))) (for-each display `("values sorted : " ,smallest ", " ,middle ", " ,largest #\newline))))

Running the program gives this:

> (exercise6) 6 4 10 values sorted : 4, 6, 10 > (exercise6) 4 5 4 values sorted : 4, 4, 5

You can run the program at https://ideone.com/8sDMd3.

Here’s another approach (omitting the reads and written in Python)

The last elif-clause can become an else-clause. This does more tests than your/Stroustrup’s solution, but it is very easy to check it for correctness: just see that each of the print statements satisfies the relational tests, and that there are 3! tests altogether. It also satisfies the rule in

The Elements of Programming Style: flatten out multiple tests when possible.Oops, got messed up there:

Here’s another approach (omitting the reads and written in Python)

The last elif-clause can become an else-clause. This does more tests than your/Stroustrup’s solution, but it is very easy to check it for correctness: just see that each of the print statements satisfies the relational tests, and that there are 3! tests altogether. It also satisfies the rule in <i>The Elements of Programming Style: flatten out multiple tests when possible.

Here’s a solution in Python.

Example Usage:

I would encourage the student to first of all write a nice simple and obviously correct solution, without being concerned with efficiency:

We have one clause for each of the 6 possible orderings, and the condition is just that a,b and c do have that ordering, so barring simple typos, not much can go wrong. The final else clause is just there to catch such errors (a more sophisticated programmer might use an assertion here).

For most purposes, that would be the perfect solution, but a more enthusiastic student might observe that we might do many more comparisons that necessary, in which case, they might get extra marks for something like this:

In two of the six cases, only two comparisons need to be done, and the other four cases just require one extra check. The student has annotated each of the main branches with the cases that will be handled by that branch, making it easy to check all cases are handled correctly; also the second branch is the same as the first, with a and b exchanged, making use of the symmetry of the situation and further increasing confidence. Testing will be made easier by having the first, more obviously correct function to compare against.