about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWilliam Carroll <wpcarro@gmail.com>2020-03-02T16·45+0000
committerWilliam Carroll <wpcarro@gmail.com>2020-03-02T16·45+0000
commit549e56186bcb152560e362d19c7ab291a95446ba (patch)
treebfcef26a530bdf7473d3e33d2975b9776a67470e
parent22d70b52c9780e7de7f9c58da33e94bae9119b89 (diff)
Solve InterviewCake's product-of-other-numbers
This problem challenged me: without using division, write a function that maps a
list of integers into a list of the product of every integer in the list except
for the integer at that index.

This was another greedy algorithm. The take-away is to first solve the problem
using brute force; this yields an algorithm with O(n*(n-1)) time
complexity. Instead of a quadratic time complexity, a linear time complexity can
be achieved my iterating over the list of integers twice:
1. Compute the products of every number to the left of the current number.
2. Compute the products of every number to the right of the current number.

Finally, iterate over each of these and compute lhs * rhs. Even though I've
solved this problem before, I used InterviewCake's hints because I was stuck
without them.

I should revisit this problem in a few weeks.
-rw-r--r--scratch/deepmind/part_two/product-of-other-numbers.py68
-rw-r--r--scratch/deepmind/part_two/todo.org2
2 files changed, 69 insertions, 1 deletions
diff --git a/scratch/deepmind/part_two/product-of-other-numbers.py b/scratch/deepmind/part_two/product-of-other-numbers.py
new file mode 100644
index 000000000000..6f7858ff4e5b
--- /dev/null
+++ b/scratch/deepmind/part_two/product-of-other-numbers.py
@@ -0,0 +1,68 @@
+import unittest
+
+
+# get_products_of_all_ints_except_at_index :: [Int] -> [Int]
+def get_products_of_all_ints_except_at_index(xs):
+    n = len(xs)
+    if n < 2:
+        raise Exception("Cannot computer without 2 or elements")
+    # lhs
+    befores = [None] * n
+    befores[0] = 1
+    for i in range(1, n):
+        befores[i] = befores[i - 1] * xs[i - 1]
+
+    # rhs
+    afters = [None] * n
+    afters[-1] = 1
+    for i in range(n - 2, -1, -1):
+        afters[i] = afters[i + 1] * xs[i + 1]
+
+    result = [None] * n
+    for i in range(n):
+        result[i] = befores[i] * afters[i]
+    return result
+
+
+# Tests
+class Test(unittest.TestCase):
+    def test_small_list(self):
+        actual = get_products_of_all_ints_except_at_index([1, 2, 3])
+        expected = [6, 3, 2]
+        self.assertEqual(actual, expected)
+
+    def test_longer_list(self):
+        actual = get_products_of_all_ints_except_at_index([8, 2, 4, 3, 1, 5])
+        expected = [120, 480, 240, 320, 960, 192]
+        self.assertEqual(actual, expected)
+
+    def test_list_has_one_zero(self):
+        actual = get_products_of_all_ints_except_at_index([6, 2, 0, 3])
+        expected = [0, 0, 36, 0]
+        self.assertEqual(actual, expected)
+
+    def test_list_has_two_zeros(self):
+        actual = get_products_of_all_ints_except_at_index([4, 0, 9, 1, 0])
+        expected = [0, 0, 0, 0, 0]
+        self.assertEqual(actual, expected)
+
+    def test_one_negative_number(self):
+        actual = get_products_of_all_ints_except_at_index([-3, 8, 4])
+        expected = [32, -12, -24]
+        self.assertEqual(actual, expected)
+
+    def test_all_negative_numbers(self):
+        actual = get_products_of_all_ints_except_at_index([-7, -1, -4, -2])
+        expected = [-8, -56, -14, -28]
+        self.assertEqual(actual, expected)
+
+    def test_error_with_empty_list(self):
+        with self.assertRaises(Exception):
+            get_products_of_all_ints_except_at_index([])
+
+    def test_error_with_one_number(self):
+        with self.assertRaises(Exception):
+            get_products_of_all_ints_except_at_index([1])
+
+
+unittest.main(verbosity=2)
diff --git a/scratch/deepmind/part_two/todo.org b/scratch/deepmind/part_two/todo.org
index ed3cc56277b9..078613611618 100644
--- a/scratch/deepmind/part_two/todo.org
+++ b/scratch/deepmind/part_two/todo.org
@@ -12,7 +12,7 @@
 * Greedy Algorithms
 ** DONE Apple Stocks
 ** DONE Highest Product of 3
-** TODO Product of All Other Numbers
+** DONE Product of All Other Numbers
 ** TODO Cafe Order Checker
 ** TODO In-Place Shuffle
 * Sorting, searching, and logarithms