2
\$\begingroup\$

This is a follow up to Maximum product of 3 integers in an int array using Python

Changes to the code include renamed variables for improved readability and I added more test cases.

import unittest


def highest_product(list_of_ints):
    max_seen = [float("-inf"), float("-inf"), float("-inf")]
    min_seen = [float("inf"), float("inf")]

    for x in list_of_ints:
        if x >= max_seen[0]:
            max_seen[0], max_seen[1], max_seen[2] = x, max_seen[0], max_seen[1]
        elif x >= max_seen[1]:
            max_seen[1], max_seen[2] = x, max_seen[1]
        elif x > max_seen[2]:
            max_seen[2] = x
        if x <= min_seen[0]:
            min_seen[0], min_seen[1] = x, min_seen[0]
        elif x < min_seen[1]:
            min_seen[1] = x

    max_product_candidate_one = min_seen[0] * min_seen[1] * max_seen[0]
    max_product_candidate_two = max_seen[0] * max_seen[1] * max_seen[2]

    return max(max_product_candidate_one, max_product_candidate_two)


class TestHighestProduct(unittest.TestCase):
    def test_highest_product(self):
        self.assertEqual(highest_product([6, -1, -1, -2, 0]), 12)
        self.assertEqual(highest_product([-6, -1, -1, -2]), -2)
        self.assertEqual(highest_product([0, 0, 0]), 0)
        self.assertEqual(highest_product([0, 0, -2]), 0)


if __name__ == '__main__':
    unittest.main(verbosity=2)
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

This version feels much more readable, especialy since you dropped half of your comparisons.

However, I really liked @JoeWallis use of heapq. I would however use heappushpop which will provide all the comparisons you are doing at once.

But you will need to manually extract out the maximum value of max_seen since you have no guarantee anymore on its position.

You can thus write:

from heapq import heappushpop

def highest_product(list_of_ints):
    max_seen = [float("-inf")] * 3
    min_seen = [float("-inf")] * 2

    for x in list_of_ints:
        heappushpop(max_seen, x)
        heappushpop(min_seen, -x)

    # No change of sign since we changed it twice (once for each element)
    max_product_candidate_one = min_seen[0] * min_seen[1] * max(max_seen)
    max_product_candidate_two = max_seen[0] * max_seen[1] * max_seen[2]

    return max(max_product_candidate_one, max_product_candidate_two)
\$\endgroup\$
1
  • 1
    \$\begingroup\$ -(-1) for heappushpop. \$\endgroup\$
    – Average
    Commented Oct 27, 2016 at 13:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.