git.net

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

The power of three, sort of


I have chosen to stay out of the discussion as it clearly was a TEACHING
example where giving an ANSWER is not the point.

 

So I would like to add some thought without a detailed answer for the boring
way some are trying to steer an answer for. They are probably right that the
instructor wants the students to learn that way.

 

My understanding is the lesson was in how to use the IF command on exactly
three numbers to get the maximum, or perhaps both the maximum and minimum.

 

If this was not for school but the real world, the trivial answer would be
to use max() or min() or perhaps a minmax() that returns a tuple. Or, you
could sort() and choose the first and/or last. 

 

All the above are easy and expand well to any number of N items.

 

My second thought was to do it in one of several standard methods with
nested IF/ELSE statements perhaps using an ELIF. It would produce six (or
perhaps more)  branches and each of them would set any of  a/b/c to be the
maximum. A second complete set would invert some of the > or >= symbols to
get the minimum.

 

But that seems quite long and complicated and I will not show it as we keep
waiting for the student to solve it and then show it so any other students
could copy it!

 

Since there are 3! Possible combinations (albeit if some numbers are the
same, sort of less) a brute force method seems preferable as in:

 

    if (a >= b >= c): max = a

    .

    if (c >= b >= a): max = c

 

That seems wasteful in so many ways and can be shortened perhaps to:

 

    if (a >= b >= c): max = a

    elif (b >= a >= c): max = b

    .

    else: max = c

 

Again, six known combinations and fewer tests on average.

 

Another variation is arguably even easier to think about.

 

    max, min = float('-inf'), float('inf')

    if a > max: max = a

    .

    if c > max: max = c

    # repeat for min using <

 

No nesting and I assume within the allowed rules.

 

The latter makes you wonder about using the one (perhaps two or three) line
version:

 

    a, b, c = int(input("first: ")), int(input("second: ")),
int(input("last: "))

    max = a if (a>=b and a>=c) else (b if (b>=a and b>=c) else c)

    print("max = %d" % max)

 

Again, fairly simple but using a ternary and nested version of if.

 

Results:

 

first: 5

second: 10

last: 7

max = 10

 

first: 5

second: 10

last: 10

max = 10

 

Not saying this is a charmed version using the power of three but I wonder
what kind of answers the instructor expects. I mean you can trivially write
more versions including iterative ones where you unpack the input into a
tuple or list and iterate on it or where you use a function for recursion or
create an object you keep adding to that maintains the biggest so far and on
and on. You can even do calculations after the first two inputs and then use
that to compare after the third input. There is no one right answer even for
simplified methods.

 

If I get to teach this, I probably would not tell them there are many ways
but might give extra credit for those who innovate or make it somewhat more
efficient looking but perhaps penalize solutions that others might not
easily understand.

 

Ending comment. Every use of the ellipsis above should not be typed in and
represent missing lines that need to be added but are not being specified.
The one liner does work and there are more nested variations of that you can
use. My thoughts apply well beyond this simple example to the question of
how you define a problem so that people use only what they know so far and
are taught how to use it even if they may not ever actually need to use it
again.