Reputation: 9
I'm trying to find the greatest number out of three numbers and then displaying to the user what the biggest number is or if the biggest number is equal. For example if highest(1,6,6)
would return b and c are equal
. My code for this does work but it involves a bunch of nested if clauses and I was wondering if there is a more efficent way of doing this?
Here is the code that I think can be improved upon (written in python but I imagine the solution applies over many languages)
def highest(a, b, c):
if a >= b and a >= c:
if a != b:
if a != c:
return "a is greatest"
else:
return "a and c are equal"
else:
return "a and b are equal"
elif b >= c:
if b != c:
return "b is greatest"
else:
return "b and c are equal"
else:
return "c is greatest"
print(highest(n1, n2, n3))
Upvotes: 0
Views: 201
Reputation: 433
"...a more efficent way" is quite ambigious in this case. The most performant and straight forward way would probably be Ze'ev Ben-Tsvi answer (see other answer).
The shortest amount of code needed is probably:
def highest(a,b,c):
parameter = ['a', 'b', 'c']
max_values = [i for i, x in enumerate((a,b,c)) \
if x == max(enumerate((a,b,c)), key=lambda x: x[1])[1]]
if len(max_values) == 1:
return f"{parameter[max_values[0]]} is greatest"
elif len(max_values) == 2:
return f"{parameter[max_values[0]]} & {parameter[max_values[1]]} are equal"
else:
return "They are all equal"
Upvotes: 0
Reputation: 27404
This approach incorporates a response for when all 3 values are identical:
def highest(*args):
assert len(args) == 3
d = dict()
for x, n in zip(args, "abc"):
d.setdefault(x, []).append(n)
match len(ms := d[max(args)]):
case 3:
return "a, b and c are equal"
case 2:
return "{} and {} are equal".format(*ms)
case _:
return "{} is highest".format(*ms)
It is not necessarily the case that fewer lines of code equate to greater efficiency.
The following solution has more lines of code than in the first part of this answer but will almost certainly be more efficient:
def highest(a, b, c):
if a == b and b == c:
return "a, b and c are equal"
m = max(a, b, c)
if a == m:
if b == m:
return "a and b are equal"
if c == m:
return "a and c are equal"
return "a is highest"
if b == m:
if c == m:
return "b and c are equal"
return "b is highest"
return "c is highest"
Upvotes: 2
Reputation: 1432
Elerium115 is right and you miss the option of all three variables being equal.
Nested if clauses, if planned right can be more efficient than less nested if clauses.
def highest(a, b, c):
if a == b == c:
return "a, b and c are equal"
if a == b > c:
return "a and b are equal"
if a == c > b:
return "a and c are equal"
if b == c > a:
return "b and c are equal"
if c < a > b:
return "a is the highest"
if a < b > c:
return "b is the highest"
return "c is the highest"
def highest2(a, b, c):
if a > b:
if a > c:
return "a is the highest"
elif a == c:
return "a and c are equal"
else:
return "c is the highest"
elif a == b:
if a > c:
return "a and b are equal"
elif a == c:
return "a, b and c are equal"
else:
return "c is the highest"
elif b > c:
return "b is the highest"
elif b == c:
return "b and c are equal"
return "c is the highest"
While in the highest2 function, there are a maximum of 4 comparisons before the function returns the right answer, to get the right answer in the highest function can take 6 doubled comparisons if the answer is "c is the highest"
Upvotes: 0
Reputation: 1594
def highest(a, b, c):
letters = ['a','b','c']
number_list = [a,b,c]
highest = max(number_list)
if number_list.count(highest) > 1:
indexes = [i for i, num in enumerate(number_list) if num == highest]
if len(indexes) == 2:
print(f"{letters[indexes[0]]} and {letters[indexes[1]]} are equal")
elif len(indexes) == 3:
print(f"{', '.join(letters)} are equal")
else:
index = number_list.index(highest)
print(f"{letters[index]} is the highest number")
highest(1,3,6)
highest(1,6,6)
highest(6,6,6)
Just in case you ACTUALLY need to return "a b or c is the greatest" as you have in you question.
But really all you need it
print(f"{max(a,b,c)} is the highest number")
Upvotes: -2