### re: Write better code: Day 1 - Highest Product VIEW POST

re: Yes, I see the problem. So far I see three cases: The biggest product is all positives. The biggest product is two smallest negatives and one big...

Okay, I think I got it:

``````import math

def get_product_of_3(array_of_ints):
if len(array_of_ints) < 3:
return 0

min_max = -math.inf
min_max_i = 0
maxes = [min_max, min_max, min_max]
max_neg = 0
max_neg_i = 0
negs = [0, 0]
for int in array_of_ints:
if int > min_max:
maxes[min_max_i] = int
min_max_i, min_max = min(enumerate(maxes), key=lambda x: x[1])
if int < max_neg:
negs[max_neg_i] = int
max_neg_i, max_neg = max(enumerate(negs), key=lambda x: x[1])

prod_maxes = maxes[0]*maxes[1]*maxes[2]
prod_negs = negs[0]*negs[1]
# This condition is only needed for `[n,p,p]`, to not return the invalid product of `0` when the product of maxes is negative.
if prod_negs != 0:
return max(prod_negs*max(maxes), prod_maxes)
return prod_maxes
``````

If we instead explicitly return the product of 3 inputs, this condition is no longer needed:

``````import math

def get_product_of_3(array_of_ints):
if len(array_of_ints) < 3:
return 0
if len(array_of_ints) == 3:
return array_of_ints[0]*array_of_ints[1]*array_of_ints[2]

min_max = -math.inf
min_max_i = 0
maxes = [min_max, min_max, min_max]
max_neg = 0
max_neg_i = 0
negs = [0, 0]
for int in array_of_ints:
if int > min_max:
maxes[min_max_i] = int
min_max_i, min_max = min(enumerate(maxes), key=lambda x: x[1])
if int < max_neg:
negs[max_neg_i] = int
max_neg_i, max_neg = max(enumerate(negs), key=lambda x: x[1])

prod_maxes = maxes[0]*maxes[1]*maxes[2]
prod_negs = negs[0]*negs[1]
return max(prod_negs*max(maxes), prod_maxes)
``````

Another possible optimization, for input such as `[...-100,-99,-98,-97,1,-96,-95,-94...]` is to stop expecting the "all negatives" case. This can easily be done by resetting all negative maxes to 0, so that incoming negatives are always smaller:

``````import math

def get_product_of_3(array_of_ints):
if len(array_of_ints) < 3:
return 0
if len(array_of_ints) == 3:
return array_of_ints[0]*array_of_ints[1]*array_of_ints[2]

awaiting_not_negatve = True
min_max = -math.inf
min_max_i = 0
maxes = [min_max, min_max, min_max]
max_neg = 0
max_neg_i = 0
negs = [0, 0]
for int in array_of_ints:
if int > min_max:
maxes[min_max_i] = int
if awaiting_not_negatve and int >= 0:
awaiting_not_negatve = False
for i, v in enumerate(maxes):
if v < 0:
maxes[i] = 0
min_max_i, min_max = min(enumerate(maxes), key=lambda x: x[1])
if int < max_neg:
negs[max_neg_i] = int
max_neg_i, max_neg = max(enumerate(negs), key=lambda x: x[1])

prod_maxes = maxes[0]*maxes[1]*maxes[2]
prod_negs = negs[0]*negs[1]
return max(prod_negs*max(maxes), prod_maxes)
``````
code of conduct - report abuse