-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(puzzles): cyclically shifted array
Using binary search to find the index of the smallest number in a cyclically shifted array
- Loading branch information
BrianLusina
authored and
BrianLusina
committed
Nov 22, 2024
1 parent
acafb89
commit 55a1b7c
Showing
4 changed files
with
110 additions
and
0 deletions.
There are no files selected for viewing
22 changes: 22 additions & 0 deletions
22
puzzles/search/binary_search/cyclically_shifted_array/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Cyclically Shifted Array | ||
|
||
Return the index of the smallest number in a cyclically shifted array. | ||
|
||
An array is “cyclically shifted” if it is possible to shift its entries cyclically so that it becomes sorted. | ||
|
||
The following list is an example of a cyclically shifted array: | ||
|
||
A = [4, 5, 6, 7, 1, 2, 3] | ||
|
||
Below are all the possible cyclic shifts of an array: | ||
|
||
```plain | ||
Array A: [1,2,3,4,5,6,7] | ||
[2,3,4,5,6,7,1] | ||
[5,6,7,1,2,3,4] | ||
[3,4,5,6,7,1,2] | ||
[6,7,1,2,3,4,5] | ||
[4,5,6,7,1,2,3] | ||
[7,1,2,3,4,5,6] | ||
``` |
29 changes: 29 additions & 0 deletions
29
puzzles/search/binary_search/cyclically_shifted_array/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
from typing import List | ||
|
||
def find_index_of_smallest_number(numbers: List[int]) -> int: | ||
""" | ||
Finds the index of the smallest number in a cyclically shifted array | ||
Args: | ||
numbers (list): cyclically shifted array | ||
Returns: | ||
int: index of the smallest number in a cyclically shifted array | ||
""" | ||
left_pointer = 0 | ||
right_pointer = len(numbers) - 1 | ||
|
||
while left_pointer < right_pointer: | ||
middle = (left_pointer + right_pointer) >> 1 | ||
|
||
# if the number in the middle is less than or equal to the number on the right, this means that the search space | ||
# should be moved to the left. Eliminating numbers on the right by moving the right pointer to the middle. This | ||
# is because the numbers are increasing, therefore the numbers we are looking for can not be on the right | ||
if numbers[middle] <= numbers[right_pointer]: | ||
right_pointer = middle | ||
elif numbers[middle] > numbers[right_pointer]: | ||
# move the left pointer to the middle + 1 to eliminate the search space on the left if the middle number | ||
# is greater than the number at the right pointer. This is because the numbers are decreasing from the middle | ||
# therefore we can possibly find the number we are searching for in the right search space | ||
left_pointer = middle + 1 | ||
|
||
return left_pointer |
56 changes: 56 additions & 0 deletions
56
puzzles/search/binary_search/cyclically_shifted_array/test_cyclically_shifted_array.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import unittest | ||
from . import find_index_of_smallest_number | ||
|
||
|
||
class FindIndexOfSmallestNumberTestCase(unittest.TestCase): | ||
def test_1(self): | ||
"""should return 4 in input of [4, 5, 6, 7, 1, 2, 3]""" | ||
numbers = [4, 5, 6, 7, 1, 2, 3] | ||
expected = 4 | ||
actual = find_index_of_smallest_number(numbers) | ||
self.assertEqual(expected, actual) | ||
|
||
def test_2(self): | ||
"""should return 2 in input of [6, 7, 1, 2, 3, 4, 5]""" | ||
numbers = [6, 7, 1, 2, 3, 4, 5] | ||
expected = 2 | ||
actual = find_index_of_smallest_number(numbers) | ||
self.assertEqual(expected, actual) | ||
|
||
def test_3(self): | ||
"""should return 1 in input of [7, 1, 2, 3, 4, 5, 6]""" | ||
numbers = [7, 1, 2, 3, 4, 5, 6] | ||
expected = 1 | ||
actual = find_index_of_smallest_number(numbers) | ||
self.assertEqual(expected, actual) | ||
|
||
def test_4(self): | ||
"""should return 0 in input of [1, 2, 3, 4, 5, 6, 7]""" | ||
numbers = [1, 2, 3, 4, 5, 6, 7] | ||
expected = 0 | ||
actual = find_index_of_smallest_number(numbers) | ||
self.assertEqual(expected, actual) | ||
|
||
def test_5(self): | ||
"""should return 5 in input of [3, 4, 5, 6, 7, 1, 2]""" | ||
numbers = [3, 4, 5, 6, 7, 1, 2] | ||
expected = 5 | ||
actual = find_index_of_smallest_number(numbers) | ||
self.assertEqual(expected, actual) | ||
|
||
def test_6(self): | ||
"""should return 6 in input of [2, 3, 4, 5, 6, 7, 1]""" | ||
numbers = [2, 3, 4, 5, 6, 7, 1] | ||
expected = 6 | ||
actual = find_index_of_smallest_number(numbers) | ||
self.assertEqual(expected, actual) | ||
|
||
def test_7(self): | ||
"""should return 3 in input of [5, 6, 7, 1, 2, 3, 5]""" | ||
numbers = [5, 6, 7, 1, 2, 3, 5] | ||
expected = 3 | ||
actual = find_index_of_smallest_number(numbers) | ||
self.assertEqual(expected, actual) | ||
|
||
if __name__ == '__main__': | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters