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.

Advertisements

Pages: 1 2

4 Responses to “Exercise 6”

  1. John Cowan said

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

    if a <= b and b <= c and a <= c: print a, b, c
    elif a = c and a <= c: print a, c, b
    #elif a <= b and b = c: impossible
    elif a = c and a >= c: print c, a, b
    elif a >= b and b <= c and a = b and b >= c and a = b and b = c: print b, c, a
    elif a >= b and b >= c and a >= c: print c, b, a

    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.

  2. John Cowan said

    Oops, got messed up there:

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

    if a <= b and b <= c and a <= c: print a, b, c
    elif a <= b and b >= c and a <= c: print a, c, b
    #elif a <= b and b <= c and a >= c: impossible
    elif a <= b and b >= c and a >= c: print c, a, b
    elif a >= b and b <= c and a <= c: print b, a, c
    #elif a >= b and b >= c and a <= c: impossible
    elif a >= b and b <= c and a >= c: print b, c, a
    elif a >= b and b >= c and a >= c: print c, b, a

    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.

  3. Daniel said

    Here’s a solution in Python.

    a, b, c = (int(x) for x in input('Enter three integers: ').split())
    if a > b: a, b = b, a
    if b > c: b, c = c, b
    if a > b: a, b = b, a
    print(f'{a}, {b}, {c}')
    

    Example Usage:

    $ python exercise6.py 
    Enter three integers: 10 4 6
    4, 6, 10
    
    $ python exercise6.py 
    Enter three integers: 4 5 4
    4, 4, 5
    
  4. matthew said

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

    if a <= b <= c: print(a,b,c)
    elif a <= c <= b: print(a,c,b)
    elif b <= a <= c: print(b,a,c)
    elif b <= c <= a: print(b,c,a)
    elif c <= a <= b: print(c,a,b)
    elif c <= b <= a: print(c,b,a)
    else: print("Error!")
    

    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:

    if a <= b:
        # (a,b,c),(a,c,b),(c,a,b)
        if b <= c:
            print(a,b,c)
        elif a <= c:
            print(a,c,b)
        else:
            print(c,a,b)
    else:
        # (b,a,c),(b,c,a),(c,b,a)
        if a <= c:
            print(b,a,c)
        elif b <= c:
            print(b,c,a)
        else:
            print(c,b,a)
    

    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.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: