about summary refs log tree commit diff
path: root/deepmind/find-rotation-point.py
diff options
context:
space:
mode:
authorWilliam Carroll <wpcarro@gmail.com>2020-01-22T10·11+0000
committerWilliam Carroll <wpcarro@gmail.com>2020-01-22T10·11+0000
commitde039c7133c80caa76e0549e2388a6e54768286f (patch)
treea22dcc126db707e340fc3d18095b67ac2ef2b5dd /deepmind/find-rotation-point.py
parentbbea699f06157d0291f837d4e09a0f391ad09a06 (diff)
Complete find-rotation-point
Solves an InterviewCake.com problem that returns the index of the element in a
list that should be the first element in that list. It's an exercise that's
useful for seeing other applications of a binary search.
Diffstat (limited to 'deepmind/find-rotation-point.py')
-rw-r--r--deepmind/find-rotation-point.py55
1 files changed, 55 insertions, 0 deletions
diff --git a/deepmind/find-rotation-point.py b/deepmind/find-rotation-point.py
new file mode 100644
index 000000000000..5c21d5167ce9
--- /dev/null
+++ b/deepmind/find-rotation-point.py
@@ -0,0 +1,55 @@
+import unittest
+from math import floor
+
+
+def midpoint(a, b):
+    return a + floor((b - a) / 2)
+
+
+def do_find_rotation_point(a, b, xs):
+    i = midpoint(a, b)
+    count = b - a + 1
+
+    if count == 2:
+        if xs[a] > xs[b]:
+            return b
+        else:
+            return -1
+
+    if i in {a, b}:
+        return i
+
+    if xs[a] < xs[i]:
+        return do_find_rotation_point(i, b, xs)
+    else:
+        return do_find_rotation_point(a, i, xs)
+
+
+def find_rotation_point(xs):
+    return do_find_rotation_point(0, len(xs) - 1, xs)
+
+
+# Tests
+class Test(unittest.TestCase):
+    def test_small_list(self):
+        actual = find_rotation_point(['cape', 'cake'])
+        expected = 1
+        self.assertEqual(actual, expected)
+
+    def test_medium_list(self):
+        actual = find_rotation_point(
+            ['grape', 'orange', 'plum', 'radish', 'apple'])
+        expected = 4
+        self.assertEqual(actual, expected)
+
+    def test_large_list(self):
+        actual = find_rotation_point([
+            'ptolemaic', 'retrograde', 'supplant', 'undulate', 'xenoepist',
+            'asymptote', 'babka', 'banoffee', 'engender', 'karpatka',
+            'othellolagkage'
+        ])
+        expected = 5
+        self.assertEqual(actual, expected)
+
+
+unittest.main(verbosity=2)