From 5b34a79dbaca4afc32c65997d79c1fea70d66bb0 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Thu, 7 Jan 2021 10:58:00 +0530 Subject: [PATCH 01/73] Update queue.py --- pydatastructs/miscellaneous_data_structures/queue.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pydatastructs/miscellaneous_data_structures/queue.py b/pydatastructs/miscellaneous_data_structures/queue.py index c7b9d302e..097ad4f34 100644 --- a/pydatastructs/miscellaneous_data_structures/queue.py +++ b/pydatastructs/miscellaneous_data_structures/queue.py @@ -5,7 +5,8 @@ __all__ = [ 'Queue', - 'PriorityQueue' + 'PriorityQueue', + 'CircularQueue' ] class Queue(object): @@ -394,3 +395,6 @@ def peek(self): @property def is_empty(self): return self.items.is_empty + +class CircularQueue: + From 52f01c3f6071e5624ae1c3d6be6de8627939a333 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Fri, 8 Jan 2021 15:11:43 +0530 Subject: [PATCH 02/73] Update linked_lists.py --- pydatastructs/linear_data_structures/linked_lists.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/linked_lists.py b/pydatastructs/linear_data_structures/linked_lists.py index 083fc0af5..f0cb8c855 100644 --- a/pydatastructs/linear_data_structures/linked_lists.py +++ b/pydatastructs/linear_data_structures/linked_lists.py @@ -61,7 +61,16 @@ def insert_after(self, prev_node, key, data=None): data Any valid data to be stored in the node. """ - raise NotImplementedError('This is an abstract method') + elements = [] + current_node = self.head + while current_node!=prev_node: + current_node = current_node.next + if current_node == self.head: + raise Exception("The element is not found") + next_node=current_node.next + current_node.next=key + key.next=next_node + return def insert_at(self, index, key, data=None): """ From 6610a7f6b3ab86ac108374c2a34cf6b9267ad5e7 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Fri, 8 Jan 2021 15:12:20 +0530 Subject: [PATCH 03/73] Update linked_lists.py --- pydatastructs/linear_data_structures/linked_lists.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/linked_lists.py b/pydatastructs/linear_data_structures/linked_lists.py index f0cb8c855..3e0293e7a 100644 --- a/pydatastructs/linear_data_structures/linked_lists.py +++ b/pydatastructs/linear_data_structures/linked_lists.py @@ -66,7 +66,7 @@ def insert_after(self, prev_node, key, data=None): while current_node!=prev_node: current_node = current_node.next if current_node == self.head: - raise Exception("The element is not found") + raise Exception("The element is not found in the LinkedList") next_node=current_node.next current_node.next=key key.next=next_node From 4c5c855184437e0ab19a361a9c609f456678039d Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Fri, 8 Jan 2021 15:31:31 +0530 Subject: [PATCH 04/73] Update linked_lists.py --- pydatastructs/linear_data_structures/linked_lists.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pydatastructs/linear_data_structures/linked_lists.py b/pydatastructs/linear_data_structures/linked_lists.py index 3e0293e7a..5a1edc6b3 100644 --- a/pydatastructs/linear_data_structures/linked_lists.py +++ b/pydatastructs/linear_data_structures/linked_lists.py @@ -61,15 +61,16 @@ def insert_after(self, prev_node, key, data=None): data Any valid data to be stored in the node. """ - elements = [] + new_node=__new__(key,data) current_node = self.head while current_node!=prev_node: current_node = current_node.next if current_node == self.head: raise Exception("The element is not found in the LinkedList") next_node=current_node.next - current_node.next=key + current_node.next=new_node key.next=next_node + print("Successfully added a node") return def insert_at(self, index, key, data=None): From f93008ab92c5f35e9f1dc3d9381b646b49af6a26 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Fri, 8 Jan 2021 15:32:00 +0530 Subject: [PATCH 05/73] Update queue.py --- pydatastructs/miscellaneous_data_structures/queue.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pydatastructs/miscellaneous_data_structures/queue.py b/pydatastructs/miscellaneous_data_structures/queue.py index 097ad4f34..020108baa 100644 --- a/pydatastructs/miscellaneous_data_structures/queue.py +++ b/pydatastructs/miscellaneous_data_structures/queue.py @@ -5,8 +5,7 @@ __all__ = [ 'Queue', - 'PriorityQueue', - 'CircularQueue' + 'PriorityQueue' ] class Queue(object): @@ -396,5 +395,3 @@ def peek(self): def is_empty(self): return self.items.is_empty -class CircularQueue: - From 6867addc30de9bdae293a8101e5dc3cae455a589 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Fri, 8 Jan 2021 15:36:28 +0530 Subject: [PATCH 06/73] Update linked_lists.py --- pydatastructs/linear_data_structures/linked_lists.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/linked_lists.py b/pydatastructs/linear_data_structures/linked_lists.py index 5a1edc6b3..274771d6e 100644 --- a/pydatastructs/linear_data_structures/linked_lists.py +++ b/pydatastructs/linear_data_structures/linked_lists.py @@ -63,9 +63,11 @@ def insert_after(self, prev_node, key, data=None): """ new_node=__new__(key,data) current_node = self.head + if isempty(self): + raise Excpetion("The linked list is empty") while current_node!=prev_node: current_node = current_node.next - if current_node == self.head: + if current_node == self.head or current_node is None: raise Exception("The element is not found in the LinkedList") next_node=current_node.next current_node.next=new_node From 628045c86b52fcdb9ab847e3764eb483a80377dd Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Fri, 8 Jan 2021 15:36:50 +0530 Subject: [PATCH 07/73] Update linked_lists.py --- pydatastructs/linear_data_structures/linked_lists.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/linked_lists.py b/pydatastructs/linear_data_structures/linked_lists.py index 274771d6e..4db636d32 100644 --- a/pydatastructs/linear_data_structures/linked_lists.py +++ b/pydatastructs/linear_data_structures/linked_lists.py @@ -61,7 +61,7 @@ def insert_after(self, prev_node, key, data=None): data Any valid data to be stored in the node. """ - new_node=__new__(key,data) + new_node=__new__(key, data) current_node = self.head if isempty(self): raise Excpetion("The linked list is empty") From 09e5e42f8db79a84f848c9a669ae4c1a66c9a46d Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Fri, 8 Jan 2021 15:38:00 +0530 Subject: [PATCH 08/73] Completed updating the insert_after --- pydatastructs/linear_data_structures/linked_lists.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/linked_lists.py b/pydatastructs/linear_data_structures/linked_lists.py index 4db636d32..8b8b53829 100644 --- a/pydatastructs/linear_data_structures/linked_lists.py +++ b/pydatastructs/linear_data_structures/linked_lists.py @@ -64,7 +64,7 @@ def insert_after(self, prev_node, key, data=None): new_node=__new__(key, data) current_node = self.head if isempty(self): - raise Excpetion("The linked list is empty") + raise Excpetion("The linked list is empty!") while current_node!=prev_node: current_node = current_node.next if current_node == self.head or current_node is None: From 74009e6e33262412f3f2f137c370de9519f3bff4 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Fri, 8 Jan 2021 21:01:43 +0530 Subject: [PATCH 09/73] Update linked_lists.py --- pydatastructs/linear_data_structures/linked_lists.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pydatastructs/linear_data_structures/linked_lists.py b/pydatastructs/linear_data_structures/linked_lists.py index 8b8b53829..50f1c3581 100644 --- a/pydatastructs/linear_data_structures/linked_lists.py +++ b/pydatastructs/linear_data_structures/linked_lists.py @@ -64,11 +64,13 @@ def insert_after(self, prev_node, key, data=None): new_node=__new__(key, data) current_node = self.head if isempty(self): - raise Excpetion("The linked list is empty!") + print("The linked list is empty!") + return while current_node!=prev_node: current_node = current_node.next if current_node == self.head or current_node is None: - raise Exception("The element is not found in the LinkedList") + print("The element is not found in the LinkedList") + return next_node=current_node.next current_node.next=new_node key.next=next_node From 0055baa4f1c4ce5639c759766e02185e40b86482 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Fri, 8 Jan 2021 21:33:25 +0530 Subject: [PATCH 10/73] Update queue.py --- pydatastructs/miscellaneous_data_structures/queue.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pydatastructs/miscellaneous_data_structures/queue.py b/pydatastructs/miscellaneous_data_structures/queue.py index 020108baa..c7b9d302e 100644 --- a/pydatastructs/miscellaneous_data_structures/queue.py +++ b/pydatastructs/miscellaneous_data_structures/queue.py @@ -394,4 +394,3 @@ def peek(self): @property def is_empty(self): return self.items.is_empty - From 9dec38c7e4150f54fdbebfdc3e98fb59ca8c4c3d Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Sun, 10 Jan 2021 13:47:07 +0530 Subject: [PATCH 11/73] Update linked_lists.py --- .../linear_data_structures/linked_lists.py | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/pydatastructs/linear_data_structures/linked_lists.py b/pydatastructs/linear_data_structures/linked_lists.py index 50f1c3581..083fc0af5 100644 --- a/pydatastructs/linear_data_structures/linked_lists.py +++ b/pydatastructs/linear_data_structures/linked_lists.py @@ -61,21 +61,7 @@ def insert_after(self, prev_node, key, data=None): data Any valid data to be stored in the node. """ - new_node=__new__(key, data) - current_node = self.head - if isempty(self): - print("The linked list is empty!") - return - while current_node!=prev_node: - current_node = current_node.next - if current_node == self.head or current_node is None: - print("The element is not found in the LinkedList") - return - next_node=current_node.next - current_node.next=new_node - key.next=next_node - print("Successfully added a node") - return + raise NotImplementedError('This is an abstract method') def insert_at(self, index, key, data=None): """ From 708f6bc386f6cd08585b6fbb1bb4e44042f8271a Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Sun, 10 Jan 2021 13:57:31 +0530 Subject: [PATCH 12/73] Cocktail --- .../linear_data_structures/algorithms.py | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index a2fd774af..78967482b 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -12,6 +12,7 @@ 'matrix_multiply_parallel', 'counting_sort', 'bucket_sort', + 'cocktail_sort ] def _merge(array, sl, el, sr, er, end, comp): @@ -546,3 +547,45 @@ def bucket_sort(array: Array, **kwargs) -> Array: if _check_type(array, DynamicArray): array._modify(force=True) return array + +def cocktail_sort(): + """ + Performs cocktail sort on the given array. + + Parameters + ========== + + array: Array + The array which is to be sorted. + + Returns + ======= + + output: Array + The sorted array. + + Examples + ======== + + >>> from pydatastructs import DynamicOneDimensionalArray as DODA, cocktail_sort + >>> arr = DODA(int, [5, 78, 1, 0]) + >>> out = cocktail_sort(arr) + >>> str(out) + "['0', '1', '5', '78']" + >>> arr.delete(2) + >>> out = cocktail_sort(arr) + >>> str(out) + "['0', '5', '78']" + + References + ========== + + .. [1] https://en.wikipedia.org/wiki/Cocktail_shaker_sort + + Note + ==== + + Since, counting sort is a non-comparison sorting algorithm, + custom comparators aren't allowed. + The ouput array doesn't contain any `None` value. + """ From 27a5f1ac7f7c84aec353b625293622fcaa882e23 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Sun, 10 Jan 2021 13:58:09 +0530 Subject: [PATCH 13/73] Update algorithms.py --- pydatastructs/linear_data_structures/algorithms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 78967482b..55e30333d 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -12,7 +12,7 @@ 'matrix_multiply_parallel', 'counting_sort', 'bucket_sort', - 'cocktail_sort + 'cocktail_sort' ] def _merge(array, sl, el, sr, er, end, comp): @@ -585,7 +585,7 @@ def cocktail_sort(): Note ==== - Since, counting sort is a non-comparison sorting algorithm, + Since, cocktail sort is a non-comparison sorting algorithm, custom comparators aren't allowed. The ouput array doesn't contain any `None` value. """ From 6ae5a0cc6f8f929126116433cfcf20af8b80510d Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Sun, 10 Jan 2021 18:35:48 +0530 Subject: [PATCH 14/73] Implementing the cocktail sort --- .../linear_data_structures/algorithms.py | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 55e30333d..24bb013d6 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -548,7 +548,7 @@ def bucket_sort(array: Array, **kwargs) -> Array: array._modify(force=True) return array -def cocktail_sort(): +def cocktail_sort(array: Array, **kwargs) -> Array: """ Performs cocktail sort on the given array. @@ -589,3 +589,23 @@ def cocktail_sort(): custom comparators aren't allowed. The ouput array doesn't contain any `None` value. """ + def swap(i, j): + array[i], array[j] = array[j], array[i] + + lower = kwargs.get('start', 0) + upper = kwargs.get('end', len(array) - 1) + swapping = False + while (not swap and upper - lower > 1): + swapping = True + for j in range(lower, upper): + if array[j + 1] < array[j]: + swap(j + 1, j) + swapping = False + upper = upper - 1 + + for j in range(upper, lower, -1): + if array[j - 1] > array[j]: + swap(j - 1, j) + swapping = False + lower = lower + 1 + return array From aaf529a67cedd98a46e5149d36394f6deb19c523 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Sun, 10 Jan 2021 18:55:40 +0530 Subject: [PATCH 15/73] Update __init__.py --- pydatastructs/linear_data_structures/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/__init__.py b/pydatastructs/linear_data_structures/__init__.py index b4ad7041b..07c7629ce 100644 --- a/pydatastructs/linear_data_structures/__init__.py +++ b/pydatastructs/linear_data_structures/__init__.py @@ -28,6 +28,7 @@ heapsort, matrix_multiply_parallel, counting_sort, - bucket_sort + bucket_sort, + cocktail_sort ) __all__.extend(algorithms.__all__) From 9f937d4426c64dccceff495eafb78ad24af32f1b Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Sun, 10 Jan 2021 18:59:57 +0530 Subject: [PATCH 16/73] Correcting error --- pydatastructs/linear_data_structures/algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 24bb013d6..1cb9e507a 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -595,7 +595,7 @@ def swap(i, j): lower = kwargs.get('start', 0) upper = kwargs.get('end', len(array) - 1) swapping = False - while (not swap and upper - lower > 1): + while (not swapping and upper - lower > 1): swapping = True for j in range(lower, upper): if array[j + 1] < array[j]: From 38ebcbeef19d2449ee4f9ef0566333e0fe0d83a5 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Sun, 10 Jan 2021 19:12:18 +0530 Subject: [PATCH 17/73] Completion --- pydatastructs/linear_data_structures/algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 1cb9e507a..e305f845a 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -595,7 +595,7 @@ def swap(i, j): lower = kwargs.get('start', 0) upper = kwargs.get('end', len(array) - 1) swapping = False - while (not swapping and upper - lower > 1): + while (not swapping and upper - lower >= 1): swapping = True for j in range(lower, upper): if array[j + 1] < array[j]: From 9a77768188865821299376dd42b275286efb20dc Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Sun, 10 Jan 2021 19:35:36 +0530 Subject: [PATCH 18/73] Converting to ODA --- pydatastructs/linear_data_structures/algorithms.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index e305f845a..922f3cbda 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -567,15 +567,16 @@ def cocktail_sort(array: Array, **kwargs) -> Array: Examples ======== - >>> from pydatastructs import DynamicOneDimensionalArray as DODA, cocktail_sort - >>> arr = DODA(int, [5, 78, 1, 0]) + >>> from pydatastructs import OneDimensionalArray as ODA, cocktail_sort + >>> arr = ODA(int, [5, 78, 1, 0]) >>> out = cocktail_sort(arr) >>> str(out) "['0', '1', '5', '78']" >>> arr.delete(2) + >>> arr = ODA(int, [21, 37, 5]) >>> out = cocktail_sort(arr) >>> str(out) - "['0', '5', '78']" + "['5', '21', '37']" References ========== @@ -585,8 +586,8 @@ def cocktail_sort(array: Array, **kwargs) -> Array: Note ==== - Since, cocktail sort is a non-comparison sorting algorithm, - custom comparators aren't allowed. + Since, cocktail sort is a comparison sorting algorithm, + custom comparators are allowed. The ouput array doesn't contain any `None` value. """ def swap(i, j): From 40350b4a6ecf3952a031adba27a82ee59b243e05 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Sun, 10 Jan 2021 19:53:59 +0530 Subject: [PATCH 19/73] Update algorithms.py --- pydatastructs/linear_data_structures/algorithms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 922f3cbda..3d1c65d2c 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -571,12 +571,12 @@ def cocktail_sort(array: Array, **kwargs) -> Array: >>> arr = ODA(int, [5, 78, 1, 0]) >>> out = cocktail_sort(arr) >>> str(out) - "['0', '1', '5', '78']" + '[0, 1, 5, 78]' >>> arr.delete(2) >>> arr = ODA(int, [21, 37, 5]) >>> out = cocktail_sort(arr) >>> str(out) - "['5', '21', '37']" + '[5, 21, 37]' References ========== From a049c111cf676c7b8cb839eebfbd196f1b75aa11 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Sun, 10 Jan 2021 19:55:56 +0530 Subject: [PATCH 20/73] Update algorithms.py --- pydatastructs/linear_data_structures/algorithms.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 3d1c65d2c..f749797ba 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -572,7 +572,6 @@ def cocktail_sort(array: Array, **kwargs) -> Array: >>> out = cocktail_sort(arr) >>> str(out) '[0, 1, 5, 78]' - >>> arr.delete(2) >>> arr = ODA(int, [21, 37, 5]) >>> out = cocktail_sort(arr) >>> str(out) From a990d466bf803d5d25e64320c02c91384673af31 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Sun, 10 Jan 2021 20:00:39 +0530 Subject: [PATCH 21/73] Really! --- pydatastructs/linear_data_structures/algorithms.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index f749797ba..2bcf78602 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -591,7 +591,6 @@ def cocktail_sort(array: Array, **kwargs) -> Array: """ def swap(i, j): array[i], array[j] = array[j], array[i] - lower = kwargs.get('start', 0) upper = kwargs.get('end', len(array) - 1) swapping = False @@ -602,7 +601,6 @@ def swap(i, j): swap(j + 1, j) swapping = False upper = upper - 1 - for j in range(upper, lower, -1): if array[j - 1] > array[j]: swap(j - 1, j) From e49d2688ab0592ba620c2d314a285c17f4d0233c Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Mon, 11 Jan 2021 12:23:43 +0530 Subject: [PATCH 22/73] Including cocktail sort --- .../linear_data_structures/tests/test_algorithms.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index b220dee11..11b6d1844 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -1,7 +1,7 @@ from pydatastructs import ( merge_sort_parallel, DynamicOneDimensionalArray, OneDimensionalArray, brick_sort, brick_sort_parallel, - heapsort, matrix_multiply_parallel, counting_sort, bucket_sort) + heapsort, matrix_multiply_parallel, counting_sort, bucket_sort, cocktail_sort) from pydatastructs.utils.raises_util import raises import random @@ -70,6 +70,9 @@ def test_counting_sort(): 480, 548, 686, 688, 696, 779] assert counting_sort(arr)._data == expected_arr +def test_cocktail_sort(): + _test_common_sort(cocktail_sort) + def test_matrix_multiply_parallel(): ODA = OneDimensionalArray From c6c5fdd6330ac7c2f0b28320fe0e39b9a3ba562b Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Mon, 11 Jan 2021 12:32:53 +0530 Subject: [PATCH 23/73] Correcting for doda --- pydatastructs/linear_data_structures/algorithms.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 2bcf78602..75968177e 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -597,12 +597,18 @@ def swap(i, j): while (not swapping and upper - lower >= 1): swapping = True for j in range(lower, upper): - if array[j + 1] < array[j]: + if None in array[j:j+2]: + if arr[j] is None: + swap(j+1,j) + elif array[j + 1] < array[j]: swap(j + 1, j) swapping = False upper = upper - 1 for j in range(upper, lower, -1): - if array[j - 1] > array[j]: + if None in array[j-1:j+1]: + if arr[j-1] is None: + swap(j-1,j) + elif array[j - 1] > array[j]: swap(j - 1, j) swapping = False lower = lower + 1 From db70e68a7e0f98e4a3efb9c662f06dd950540113 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Mon, 11 Jan 2021 12:37:51 +0530 Subject: [PATCH 24/73] Error Correction --- pydatastructs/linear_data_structures/algorithms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 75968177e..b085f2768 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -597,7 +597,7 @@ def swap(i, j): while (not swapping and upper - lower >= 1): swapping = True for j in range(lower, upper): - if None in array[j:j+2]: + if array[j] is None or array[j+1] is None: if arr[j] is None: swap(j+1,j) elif array[j + 1] < array[j]: @@ -605,7 +605,7 @@ def swap(i, j): swapping = False upper = upper - 1 for j in range(upper, lower, -1): - if None in array[j-1:j+1]: + if array[j] is None or array[j+1] is None: if arr[j-1] is None: swap(j-1,j) elif array[j - 1] > array[j]: From 9acbebf8a0cacac06a65ff2faab311a4f94c8c43 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Mon, 11 Jan 2021 12:40:52 +0530 Subject: [PATCH 25/73] Yep done! --- .../linear_data_structures/algorithms.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index b085f2768..3f58ec437 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -586,8 +586,7 @@ def cocktail_sort(array: Array, **kwargs) -> Array: ==== Since, cocktail sort is a comparison sorting algorithm, - custom comparators are allowed. - The ouput array doesn't contain any `None` value. + custom comparators aren't allowed. """ def swap(i, j): array[i], array[j] = array[j], array[i] @@ -597,17 +596,17 @@ def swap(i, j): while (not swapping and upper - lower >= 1): swapping = True for j in range(lower, upper): - if array[j] is None or array[j+1] is None: - if arr[j] is None: - swap(j+1,j) + if array[j] is None or array[j + 1] is None: + if array[j] is None: + swap(j + 1, j) elif array[j + 1] < array[j]: swap(j + 1, j) swapping = False upper = upper - 1 for j in range(upper, lower, -1): - if array[j] is None or array[j+1] is None: - if arr[j-1] is None: - swap(j-1,j) + if array[j] is None or array[j - 1] is None: + if array[j - 1] is None: + swap(j - 1, j) elif array[j - 1] > array[j]: swap(j - 1, j) swapping = False From 57d7fbf5b673c4f0a397b9cb10076a6dc44e4095 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Mon, 11 Jan 2021 12:55:14 +0530 Subject: [PATCH 26/73] Hope this works fine --- .../linear_data_structures/algorithms.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 3f58ec437..feef265be 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -594,19 +594,23 @@ def swap(i, j): upper = kwargs.get('end', len(array) - 1) swapping = False while (not swapping and upper - lower >= 1): + if array.count(None)==len(array)-lower: + break swapping = True for j in range(lower, upper): - if array[j] is None or array[j + 1] is None: - if array[j] is None: - swap(j + 1, j) + if array[j] is None and array[j + 1] is None: + continue + elif array[j] is None: + swap(j + 1, j) elif array[j + 1] < array[j]: swap(j + 1, j) swapping = False upper = upper - 1 for j in range(upper, lower, -1): - if array[j] is None or array[j - 1] is None: - if array[j - 1] is None: - swap(j - 1, j) + if array[j] is None and array[j - 1] is None: + continue + elif array[j - 1] is None: + swap(j - 1, j) elif array[j - 1] > array[j]: swap(j - 1, j) swapping = False From 35696529a5b38ef6fbc40fafaae9cea82fa37e08 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Mon, 11 Jan 2021 12:57:14 +0530 Subject: [PATCH 27/73] Update algorithms.py --- pydatastructs/linear_data_structures/algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index feef265be..e3a46deed 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -609,7 +609,7 @@ def swap(i, j): for j in range(upper, lower, -1): if array[j] is None and array[j - 1] is None: continue - elif array[j - 1] is None: + elif array[j - 1] is None: swap(j - 1, j) elif array[j - 1] > array[j]: swap(j - 1, j) From c9d4f9c3fe2804faaa2cffd9d81da379f0410e4b Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Mon, 11 Jan 2021 13:00:07 +0530 Subject: [PATCH 28/73] Commit --- pydatastructs/linear_data_structures/algorithms.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index e3a46deed..cfb80e936 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -594,24 +594,14 @@ def swap(i, j): upper = kwargs.get('end', len(array) - 1) swapping = False while (not swapping and upper - lower >= 1): - if array.count(None)==len(array)-lower: - break swapping = True for j in range(lower, upper): - if array[j] is None and array[j + 1] is None: - continue - elif array[j] is None: - swap(j + 1, j) - elif array[j + 1] < array[j]: + if array[j + 1] < array[j]: swap(j + 1, j) swapping = False upper = upper - 1 for j in range(upper, lower, -1): - if array[j] is None and array[j - 1] is None: - continue - elif array[j - 1] is None: - swap(j - 1, j) - elif array[j - 1] > array[j]: + if array[j - 1] > array[j]: swap(j - 1, j) swapping = False lower = lower + 1 From e1d817ffdf7c13ea4fae1c5c2fb776097d548f3d Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Mon, 11 Jan 2021 13:00:59 +0530 Subject: [PATCH 29/73] Cocktail update --- .../linear_data_structures/tests/test_algorithms.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index 11b6d1844..2d85b08a3 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -71,7 +71,18 @@ def test_counting_sort(): assert counting_sort(arr)._data == expected_arr def test_cocktail_sort(): - _test_common_sort(cocktail_sort) + random.seed(1000) + + n = random.randint(10, 20) + arr = DynamicOneDimensionalArray(int, 0) + for _ in range(n): + arr.append(random.randint(1, 1000)) + for _ in range(n//3): + arr.delete(random.randint(0, n//2)) + + expected_arr = [102, 134, 228, 247, 362, 373, 448, + 480, 548, 686, 688, 696, 779] + assert counting_sort(arr)._data == expected_arr def test_matrix_multiply_parallel(): ODA = OneDimensionalArray From 864e95c4e3e06cae819d653f4965a2ad99d3c99e Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Mon, 11 Jan 2021 13:01:58 +0530 Subject: [PATCH 30/73] Update algorithms.py --- pydatastructs/linear_data_structures/algorithms.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index cfb80e936..def1f9833 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -587,6 +587,7 @@ def cocktail_sort(array: Array, **kwargs) -> Array: Since, cocktail sort is a comparison sorting algorithm, custom comparators aren't allowed. + The ouput array doesn't contain any `None` value. """ def swap(i, j): array[i], array[j] = array[j], array[i] From 570a287eb52c242b11a7f2aa86fbed69b8eb5c4f Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Tue, 12 Jan 2021 15:47:17 +0530 Subject: [PATCH 31/73] Update test_algorithms.py --- pydatastructs/linear_data_structures/tests/test_algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index 2d85b08a3..ce4433c0c 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -82,7 +82,7 @@ def test_cocktail_sort(): expected_arr = [102, 134, 228, 247, 362, 373, 448, 480, 548, 686, 688, 696, 779] - assert counting_sort(arr)._data == expected_arr + assert cocktail_sort(arr)._data == expected_arr def test_matrix_multiply_parallel(): ODA = OneDimensionalArray From cf91f8a7e9e7a9b2c6aafbf64e9a8a382a471ad8 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Tue, 12 Jan 2021 16:12:07 +0530 Subject: [PATCH 32/73] Let's check --- .../linear_data_structures/algorithms.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index def1f9833..5378ca7b9 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -587,7 +587,7 @@ def cocktail_sort(array: Array, **kwargs) -> Array: Since, cocktail sort is a comparison sorting algorithm, custom comparators aren't allowed. - The ouput array doesn't contain any `None` value. + The ouput array does contain `None` value. But the iteration will be less than or equalt to o(n//2) """ def swap(i, j): array[i], array[j] = array[j], array[i] @@ -597,13 +597,21 @@ def swap(i, j): while (not swapping and upper - lower >= 1): swapping = True for j in range(lower, upper): - if array[j + 1] < array[j]: + if array[j] is None and array[j + 1] is not None: + swap(j + 1, j) + elif array[j + 1] is None or array[j] is None: + continue + elif array[j + 1] < array[j]: swap(j + 1, j) swapping = False upper = upper - 1 for j in range(upper, lower, -1): - if array[j - 1] > array[j]: - swap(j - 1, j) + if array[j - 1] is None and array[j] is not None: + swap(j, j - 1) + elif array[j] is None or array[j - 1] is None: + continue + elif array[j - 1] > array[j]: + swap(j, j - 1) swapping = False lower = lower + 1 return array From 3c34257e7a1941851c180ceef2a7f189b270bc94 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Tue, 12 Jan 2021 16:13:00 +0530 Subject: [PATCH 33/73] Update test_algorithms.py --- pydatastructs/linear_data_structures/tests/test_algorithms.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index ce4433c0c..a200e1f48 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -29,7 +29,8 @@ def _test_common_sort(sort, *args, **kwargs): None, None, None, None, None, None, None, None, None, None, None, None] assert arr._data == expected_arr - assert (arr._last_pos_filled, arr._num, arr._size) == (12, 13, 31) + if sort!=cocktail_sort: + assert (arr._last_pos_filled, arr._num, arr._size) == (12, 13, 31) n = random.randint(10, 20) arr = OneDimensionalArray(int, n) From 1ae0e3dd598426ad7054e582294ea1d6ae7843bb Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Tue, 12 Jan 2021 16:17:02 +0530 Subject: [PATCH 34/73] Update test_algorithms.py --- .../linear_data_structures/tests/test_algorithms.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index a200e1f48..586fd35ed 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -72,18 +72,7 @@ def test_counting_sort(): assert counting_sort(arr)._data == expected_arr def test_cocktail_sort(): - random.seed(1000) - - n = random.randint(10, 20) - arr = DynamicOneDimensionalArray(int, 0) - for _ in range(n): - arr.append(random.randint(1, 1000)) - for _ in range(n//3): - arr.delete(random.randint(0, n//2)) - - expected_arr = [102, 134, 228, 247, 362, 373, 448, - 480, 548, 686, 688, 696, 779] - assert cocktail_sort(arr)._data == expected_arr + _test_common_sort(cocktail_sort) def test_matrix_multiply_parallel(): ODA = OneDimensionalArray From 89b903aff85e605d1b37d3ce875d0c1e771d8703 Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Wed, 13 Jan 2021 11:22:49 +0530 Subject: [PATCH 35/73] Fixed cocktail sort --- .../linear_data_structures/algorithms.py | 42 +++++++++++-------- .../tests/test_algorithms.py | 2 - 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 5378ca7b9..169da3463 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -499,7 +499,6 @@ def bucket_sort(array: Array, **kwargs) -> Array: This function does not support custom comparators as is the case with other sorting functions in this file. - The ouput array doesn't contain any `None` value. """ start = kwargs.get('start', 0) end = kwargs.get('end', len(array) - 1) @@ -557,6 +556,22 @@ def cocktail_sort(array: Array, **kwargs) -> Array: array: Array The array which is to be sorted. + start: int + The starting index of the portion + which is to be sorted. + Optional, by default 0 + end: int + The ending index of the portion which + is to be sorted. + Optional, by default the index + of the last position filled. + comp: lambda/function + The comparator which is to be used + for sorting. If the function returns + False then only swapping is performed. + Optional, by default, less than or + equal to is used for comparing two + values. Returns ======= @@ -581,37 +596,28 @@ def cocktail_sort(array: Array, **kwargs) -> Array: ========== .. [1] https://en.wikipedia.org/wiki/Cocktail_shaker_sort - - Note - ==== - - Since, cocktail sort is a comparison sorting algorithm, - custom comparators aren't allowed. - The ouput array does contain `None` value. But the iteration will be less than or equalt to o(n//2) """ def swap(i, j): array[i], array[j] = array[j], array[i] + lower = kwargs.get('start', 0) upper = kwargs.get('end', len(array) - 1) + comp = kwargs.get("comp", lambda u, v: u <= v) + swapping = False while (not swapping and upper - lower >= 1): + swapping = True for j in range(lower, upper): - if array[j] is None and array[j + 1] is not None: - swap(j + 1, j) - elif array[j + 1] is None or array[j] is None: - continue - elif array[j + 1] < array[j]: + if _comp(array[j], array[j+1], comp) is False: swap(j + 1, j) swapping = False + upper = upper - 1 for j in range(upper, lower, -1): - if array[j - 1] is None and array[j] is not None: - swap(j, j - 1) - elif array[j] is None or array[j - 1] is None: - continue - elif array[j - 1] > array[j]: + if _comp(array[j-1], array[j], comp) is False: swap(j, j - 1) swapping = False lower = lower + 1 + return array diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index 586fd35ed..f4e87f3cb 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -29,8 +29,6 @@ def _test_common_sort(sort, *args, **kwargs): None, None, None, None, None, None, None, None, None, None, None, None] assert arr._data == expected_arr - if sort!=cocktail_sort: - assert (arr._last_pos_filled, arr._num, arr._size) == (12, 13, 31) n = random.randint(10, 20) arr = OneDimensionalArray(int, n) From 7a4581cac2d448f3115e6802730349fbbd27e487 Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Wed, 13 Jan 2021 11:24:38 +0530 Subject: [PATCH 36/73] cocktail_sort -> cocktail_shaker_sort --- pydatastructs/linear_data_structures/__init__.py | 2 +- pydatastructs/linear_data_structures/algorithms.py | 10 +++++----- .../linear_data_structures/tests/test_algorithms.py | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pydatastructs/linear_data_structures/__init__.py b/pydatastructs/linear_data_structures/__init__.py index 07c7629ce..dcf48160d 100644 --- a/pydatastructs/linear_data_structures/__init__.py +++ b/pydatastructs/linear_data_structures/__init__.py @@ -29,6 +29,6 @@ matrix_multiply_parallel, counting_sort, bucket_sort, - cocktail_sort + cocktail_shaker_sort ) __all__.extend(algorithms.__all__) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 169da3463..9c656cc0f 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -12,7 +12,7 @@ 'matrix_multiply_parallel', 'counting_sort', 'bucket_sort', - 'cocktail_sort' + 'cocktail_shaker_sort' ] def _merge(array, sl, el, sr, er, end, comp): @@ -547,7 +547,7 @@ def bucket_sort(array: Array, **kwargs) -> Array: array._modify(force=True) return array -def cocktail_sort(array: Array, **kwargs) -> Array: +def cocktail_shaker_sort(array: Array, **kwargs) -> Array: """ Performs cocktail sort on the given array. @@ -582,13 +582,13 @@ def cocktail_sort(array: Array, **kwargs) -> Array: Examples ======== - >>> from pydatastructs import OneDimensionalArray as ODA, cocktail_sort + >>> from pydatastructs import OneDimensionalArray as ODA, cocktail_shaker_sort >>> arr = ODA(int, [5, 78, 1, 0]) - >>> out = cocktail_sort(arr) + >>> out = cocktail_shaker_sort(arr) >>> str(out) '[0, 1, 5, 78]' >>> arr = ODA(int, [21, 37, 5]) - >>> out = cocktail_sort(arr) + >>> out = cocktail_shaker_sort(arr) >>> str(out) '[5, 21, 37]' diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index f4e87f3cb..22eccbb60 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -1,7 +1,7 @@ from pydatastructs import ( merge_sort_parallel, DynamicOneDimensionalArray, OneDimensionalArray, brick_sort, brick_sort_parallel, - heapsort, matrix_multiply_parallel, counting_sort, bucket_sort, cocktail_sort) + heapsort, matrix_multiply_parallel, counting_sort, bucket_sort, cocktail_shaker_sort) from pydatastructs.utils.raises_util import raises import random @@ -69,8 +69,8 @@ def test_counting_sort(): 480, 548, 686, 688, 696, 779] assert counting_sort(arr)._data == expected_arr -def test_cocktail_sort(): - _test_common_sort(cocktail_sort) +def test_cocktail_shaker_sort(): + _test_common_sort(cocktail_shaker_sort) def test_matrix_multiply_parallel(): ODA = OneDimensionalArray From 0c741ca64ad7379cf4adf4bddfb46f1405fee7bf Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Wed, 13 Jan 2021 16:36:34 +0530 Subject: [PATCH 37/73] Starting with Quicksort --- .../linear_data_structures/algorithms.py | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 9c656cc0f..f52082664 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -12,7 +12,8 @@ 'matrix_multiply_parallel', 'counting_sort', 'bucket_sort', - 'cocktail_shaker_sort' + 'cocktail_shaker_sort', + 'quick_sort' ] def _merge(array, sl, el, sr, er, end, comp): @@ -621,3 +622,54 @@ def swap(i, j): lower = lower + 1 return array + +def quick_sort(array: Array, **kwargs) -> Array: + """ + Performs quick sort on the given array. + + Parameters + ========== + + array: Array + The array which is to be sorted. + start: int + The starting index of the portion + which is to be sorted. + Optional, by default 0 + end: int + The ending index of the portion which + is to be sorted. + Optional, by default the index + of the last position filled. + comp: lambda/function + The comparator which is to be used + for sorting. If the function returns + False then only swapping is performed. + Optional, by default, less than or + equal to is used for comparing two + values. + + Returns + ======= + + output: Array + The sorted array. + + Examples + ======== + + >>> from pydatastructs import OneDimensionalArray as ODA, quick_sort + >>> arr = ODA(int, [5, 78, 1, 0]) + >>> out = quick_sort(arr) + >>> str(out) + '[0, 1, 5, 78]' + >>> arr = ODA(int, [21, 37, 5]) + >>> out = quick_sort(arr) + >>> str(out) + '[5, 21, 37]' + + References + ========== + + .. [1] https://en.wikipedia.org/wiki/Quicksort + """ From 4835dd42785bfab6603817be09708222aaa82533 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Wed, 13 Jan 2021 16:45:24 +0530 Subject: [PATCH 38/73] Adding quick sort --- .../linear_data_structures/algorithms.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index f52082664..e0bcd9d1f 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -673,3 +673,36 @@ def quick_sort(array: Array, **kwargs) -> Array: .. [1] https://en.wikipedia.org/wiki/Quicksort """ + def partition(arr,l,h): + i = ( l - 1 ) + x = arr[h] + for j in range(l , h): + if arr[j] <= x: + i = i+1 + arr[i],arr[j] = arr[j],arr[i] + arr[i+1],arr[h] = arr[h],arr[i+1] + return (i+1) + + size = h - l + 1 + stack = [0] * (size) + top = -1 + top += 1 + stack[top] = l + top += 1 + stack[top] = h + while top >= 0: + h = stack[top] + top -= 1 + l = stack[top] + top -= 1 + p = partition( arr, l, h ) + if p - 1 > l: + top += 1 + stack[top] = l + top += 1 + stack[top] = p - 1 + if p + 1 < h: + top += 1 + stack[top] = p + 1 + top += 1 + stack[top] = h From 069613ac6552796602c58b4935495f6e6ed9f52e Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Wed, 13 Jan 2021 16:55:01 +0530 Subject: [PATCH 39/73] Making changes --- .../linear_data_structures/algorithms.py | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index e0bcd9d1f..1e4c65749 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -673,35 +673,37 @@ def quick_sort(array: Array, **kwargs) -> Array: .. [1] https://en.wikipedia.org/wiki/Quicksort """ - def partition(arr,l,h): - i = ( l - 1 ) - x = arr[h] - for j in range(l , h): + def partition(low, high): + i = (low - 1) + x = arr[high] + for j in range(l , high): if arr[j] <= x: - i = i+1 + i = i + 1 arr[i],arr[j] = arr[j],arr[i] - arr[i+1],arr[h] = arr[h],arr[i+1] - return (i+1) + arr[i + 1],arr[high] = arr[high],arr[i + 1] + return (i + 1) + + lower = kwargs.get('start', 0) + upper = kwargs.get('end', len(array) - 1) + comp = kwargs.get("comp", lambda u, v: u <= v) + stack, top = [0] * (upper - lower + 1), -1 - size = h - l + 1 - stack = [0] * (size) - top = -1 top += 1 - stack[top] = l + stack[top] = lower top += 1 - stack[top] = h + stack[top] = upper while top >= 0: h = stack[top] top -= 1 l = stack[top] top -= 1 - p = partition( arr, l, h ) - if p - 1 > l: + p = partition(arr, lower, upper) + if p - 1 > lower: top += 1 stack[top] = l top += 1 stack[top] = p - 1 - if p + 1 < h: + if p + 1 < upper: top += 1 stack[top] = p + 1 top += 1 From 3f974095b5f87dbb0f0ec50f44decca876f21a83 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Wed, 13 Jan 2021 16:56:35 +0530 Subject: [PATCH 40/73] Update algorithms.py --- pydatastructs/linear_data_structures/algorithms.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 1e4c65749..a6a13aa67 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -693,17 +693,17 @@ def partition(low, high): top += 1 stack[top] = upper while top >= 0: - h = stack[top] + high = stack[top] top -= 1 - l = stack[top] + low = stack[top] top -= 1 - p = partition(arr, lower, upper) - if p - 1 > lower: + p = partition(arr, low, high) + if p - 1 > low: top += 1 stack[top] = l top += 1 stack[top] = p - 1 - if p + 1 < upper: + if p + 1 < high: top += 1 stack[top] = p + 1 top += 1 From 2177e04dcb49025de4e45ddf69ded4220f115a58 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Wed, 13 Jan 2021 17:12:59 +0530 Subject: [PATCH 41/73] Update __init__.py --- pydatastructs/linear_data_structures/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/__init__.py b/pydatastructs/linear_data_structures/__init__.py index dcf48160d..89cca835c 100644 --- a/pydatastructs/linear_data_structures/__init__.py +++ b/pydatastructs/linear_data_structures/__init__.py @@ -29,6 +29,7 @@ matrix_multiply_parallel, counting_sort, bucket_sort, - cocktail_shaker_sort + cocktail_shaker_sort, + quick_sort ) __all__.extend(algorithms.__all__) From 7e23b41e0bc8c452066ad91772c45b9373bb2cc5 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Wed, 13 Jan 2021 17:14:25 +0530 Subject: [PATCH 42/73] Hope this works --- pydatastructs/linear_data_structures/algorithms.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index a6a13aa67..4a94f9961 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -675,12 +675,12 @@ def quick_sort(array: Array, **kwargs) -> Array: """ def partition(low, high): i = (low - 1) - x = arr[high] + x = array[high] for j in range(l , high): - if arr[j] <= x: + if array[j] <= x: i = i + 1 - arr[i],arr[j] = arr[j],arr[i] - arr[i + 1],arr[high] = arr[high],arr[i + 1] + array[i], array[j] = array[j], array[i] + array[i + 1], array[high] = array[high], array[i + 1] return (i + 1) lower = kwargs.get('start', 0) @@ -708,3 +708,4 @@ def partition(low, high): stack[top] = p + 1 top += 1 stack[top] = h + return array From abe4362f337914660dc8dc145faf03a4207a899b Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Wed, 13 Jan 2021 17:22:52 +0530 Subject: [PATCH 43/73] Update algorithms.py --- pydatastructs/linear_data_structures/algorithms.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 4a94f9961..5c42bf149 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -676,18 +676,18 @@ def quick_sort(array: Array, **kwargs) -> Array: def partition(low, high): i = (low - 1) x = array[high] - for j in range(l , high): + for j in range(low , high): if array[j] <= x: i = i + 1 array[i], array[j] = array[j], array[i] array[i + 1], array[high] = array[high], array[i + 1] return (i + 1) - + lower = kwargs.get('start', 0) upper = kwargs.get('end', len(array) - 1) comp = kwargs.get("comp", lambda u, v: u <= v) stack, top = [0] * (upper - lower + 1), -1 - + top += 1 stack[top] = lower top += 1 From 0ad0b56563a478d2685493d0027dca9de6addf78 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Wed, 13 Jan 2021 17:23:54 +0530 Subject: [PATCH 44/73] Update algorithms.py --- pydatastructs/linear_data_structures/algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 5c42bf149..e598c0825 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -707,5 +707,5 @@ def partition(low, high): top += 1 stack[top] = p + 1 top += 1 - stack[top] = h + stack[top] = high return array From 4e1e8d4d9600f79886fb6fbb0f612169b2d45980 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Wed, 13 Jan 2021 17:58:17 +0530 Subject: [PATCH 45/73] Ok --- pydatastructs/linear_data_structures/algorithms.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index e598c0825..aceefedf2 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -673,11 +673,13 @@ def quick_sort(array: Array, **kwargs) -> Array: .. [1] https://en.wikipedia.org/wiki/Quicksort """ + comp = kwargs.get("comp", lambda u, v: u <= v) + def partition(low, high): i = (low - 1) x = array[high] for j in range(low , high): - if array[j] <= x: + if _comp(array[j], x, comp) is False: i = i + 1 array[i], array[j] = array[j], array[i] array[i + 1], array[high] = array[high], array[i + 1] @@ -685,7 +687,6 @@ def partition(low, high): lower = kwargs.get('start', 0) upper = kwargs.get('end', len(array) - 1) - comp = kwargs.get("comp", lambda u, v: u <= v) stack, top = [0] * (upper - lower + 1), -1 top += 1 From f8afd2621ddede52ea4a302b9d65e4f98756364c Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Wed, 13 Jan 2021 18:02:29 +0530 Subject: [PATCH 46/73] Update algorithms.py --- pydatastructs/linear_data_structures/algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index aceefedf2..64cde0cd3 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -679,7 +679,7 @@ def partition(low, high): i = (low - 1) x = array[high] for j in range(low , high): - if _comp(array[j], x, comp) is False: + if _comp(array[j], x, comp) is True: i = i + 1 array[i], array[j] = array[j], array[i] array[i + 1], array[high] = array[high], array[i + 1] From 377bfd67b5df02fec477b8cd312e205085d30854 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Wed, 13 Jan 2021 18:04:03 +0530 Subject: [PATCH 47/73] added quick sort --- .../linear_data_structures/tests/test_algorithms.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index 22eccbb60..83b1a636c 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -1,7 +1,7 @@ from pydatastructs import ( merge_sort_parallel, DynamicOneDimensionalArray, OneDimensionalArray, brick_sort, brick_sort_parallel, - heapsort, matrix_multiply_parallel, counting_sort, bucket_sort, cocktail_shaker_sort) + heapsort, matrix_multiply_parallel, counting_sort, bucket_sort, cocktail_shaker_sort, quick_sort) from pydatastructs.utils.raises_util import raises import random @@ -72,6 +72,9 @@ def test_counting_sort(): def test_cocktail_shaker_sort(): _test_common_sort(cocktail_shaker_sort) +def test_quick_sort(): + _test_common_sort(quick_sort) + def test_matrix_multiply_parallel(): ODA = OneDimensionalArray From 7c4d918d26026d68a233fdffd47af2db14692a44 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Wed, 13 Jan 2021 18:23:03 +0530 Subject: [PATCH 48/73] Update algorithms.py --- pydatastructs/linear_data_structures/algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index fdd782d05..e6f880af8 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -698,7 +698,7 @@ def partition(low, high): top -= 1 low = stack[top] top -= 1 - p = partition(arr, low, high) + p = partition(low, high) if p - 1 > low: top += 1 stack[top] = l From c042722085489fbbcfb1c5aec1556be94cc900d2 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Wed, 13 Jan 2021 18:24:39 +0530 Subject: [PATCH 49/73] Removing whitespace --- pydatastructs/linear_data_structures/algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index e6f880af8..a64fdec2b 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -709,7 +709,7 @@ def partition(low, high): stack[top] = p + 1 top += 1 stack[top] = high - + if _check_type(array, DynamicArray): array._modify(force=True) From ed7a05971933dcfba43e0da51b7d6f7c555817f3 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Wed, 13 Jan 2021 18:27:03 +0530 Subject: [PATCH 50/73] Error correction --- pydatastructs/linear_data_structures/algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index a64fdec2b..a5098e681 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -701,7 +701,7 @@ def partition(low, high): p = partition(low, high) if p - 1 > low: top += 1 - stack[top] = l + stack[top] = low top += 1 stack[top] = p - 1 if p + 1 < high: From 9cda68239909f2853f3de40cdee43f771d445469 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Thu, 14 Jan 2021 17:02:08 +0530 Subject: [PATCH 51/73] Start to implement stack --- pydatastructs/linear_data_structures/algorithms.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index a5098e681..7fc158f3b 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -673,6 +673,7 @@ def quick_sort(array: Array, **kwargs) -> Array: .. [1] https://en.wikipedia.org/wiki/Quicksort """ + from pydatastructs import Stack comp = kwargs.get("comp", lambda u, v: u <= v) def partition(low, high): From 65d0f881ffc0824eed16a752511b1e198a88a4bd Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Thu, 14 Jan 2021 19:18:41 +0530 Subject: [PATCH 52/73] Hope this work --- .../linear_data_structures/algorithms.py | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 7fc158f3b..0f1cd9943 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -688,28 +688,21 @@ def partition(low, high): lower = kwargs.get('start', 0) upper = kwargs.get('end', len(array) - 1) - stack, top = [0] * (upper - lower + 1), -1 - - top += 1 - stack[top] = lower - top += 1 - stack[top] = upper - while top >= 0: - high = stack[top] - top -= 1 - low = stack[top] - top -= 1 + stack, top = Stack(), -1 + + stack.push(lower) + stack.push(upper) + + while stack.is_empty(): + high = stack.pop() + low = stack.pop() p = partition(low, high) if p - 1 > low: - top += 1 - stack[top] = low - top += 1 - stack[top] = p - 1 + stack.push(low) + stack.push(p - 1) if p + 1 < high: - top += 1 - stack[top] = p + 1 - top += 1 - stack[top] = high + stack.push(p + 1) + stack.push(high) if _check_type(array, DynamicArray): array._modify(force=True) From f22a7ac0e72a99d165b01eb1c43e9e52cd45affb Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Thu, 14 Jan 2021 19:22:13 +0530 Subject: [PATCH 53/73] Update algorithms.py --- pydatastructs/linear_data_structures/algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 0f1cd9943..a73feb995 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -693,7 +693,7 @@ def partition(low, high): stack.push(lower) stack.push(upper) - while stack.is_empty(): + while is_empty(): high = stack.pop() low = stack.pop() p = partition(low, high) From 5da091e10b9a9ef06fe987527edae0bce879ad87 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Thu, 14 Jan 2021 19:26:43 +0530 Subject: [PATCH 54/73] Yep --- pydatastructs/linear_data_structures/algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index a73feb995..9c96cac3a 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -693,7 +693,7 @@ def partition(low, high): stack.push(lower) stack.push(upper) - while is_empty(): + while stack.is_empty: high = stack.pop() low = stack.pop() p = partition(low, high) From 2c7afac8acf1cf2e63daff8f899e042f587aa41a Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Thu, 14 Jan 2021 19:34:51 +0530 Subject: [PATCH 55/73] Forgot --- pydatastructs/linear_data_structures/algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 9c96cac3a..f461cb933 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -693,7 +693,7 @@ def partition(low, high): stack.push(lower) stack.push(upper) - while stack.is_empty: + while stack.is_empty==False: high = stack.pop() low = stack.pop() p = partition(low, high) From e8d13b085e61f563cbf3d181f69676c866fd0cc4 Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Fri, 15 Jan 2021 12:51:18 +0530 Subject: [PATCH 56/73] Shifting None to end --- pydatastructs/linear_data_structures/algorithms.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index f461cb933..ccd4a1bf6 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -621,6 +621,9 @@ def swap(i, j): swapping = False lower = lower + 1 + if _check_type(array, DynamicArray): + array._modify(force=True) + return array def quick_sort(array: Array, **kwargs) -> Array: From f7c64630b4c1bc428dddc8610dc5bb30e9934e07 Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Fri, 15 Jan 2021 12:52:45 +0530 Subject: [PATCH 57/73] Restored test --- pydatastructs/linear_data_structures/tests/test_algorithms.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index 6e58a80c1..60effb15a 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -30,6 +30,7 @@ def _test_common_sort(sort, *args, **kwargs): None, None, None, None, None, None, None, None, None, None, None, None] assert arr._data == expected_arr + assert (arr._last_pos_filled, arr._num, arr._size) == (12, 13, 31) n = random.randint(10, 20) arr = OneDimensionalArray(int, n) From b4760219ba166b68c87d27c31d8418f3b9898f3e Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Fri, 15 Jan 2021 13:00:32 +0530 Subject: [PATCH 58/73] Apply suggestions from code review --- pydatastructs/linear_data_structures/algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index ccd4a1bf6..ba986b598 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -696,7 +696,7 @@ def partition(low, high): stack.push(lower) stack.push(upper) - while stack.is_empty==False: + while stack.is_empty is False: high = stack.pop() low = stack.pop() p = partition(low, high) From 923b1bef0ab6c093cff402fa4f27117d250604c1 Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Fri, 15 Jan 2021 21:01:30 +0530 Subject: [PATCH 59/73] Yes Done --- pydatastructs/linear_data_structures/algorithms.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index ba986b598..ea5491024 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -689,6 +689,11 @@ def partition(low, high): array[i + 1], array[high] = array[high], array[i + 1] return (i + 1) + def pivotselect(low, high): + pivot=kwargs.get('pick_pivot_element',high) + array[high], array[pivot] = array[pivot], array[high] + return partition(low, high) + lower = kwargs.get('start', 0) upper = kwargs.get('end', len(array) - 1) stack, top = Stack(), -1 @@ -699,7 +704,7 @@ def partition(low, high): while stack.is_empty is False: high = stack.pop() low = stack.pop() - p = partition(low, high) + p = pivotselect(low, high) if p - 1 > low: stack.push(low) stack.push(p - 1) From bcb678e3c44297d3e51a2549b1ef01b478e5c50d Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Sat, 16 Jan 2021 13:17:09 +0530 Subject: [PATCH 60/73] Pivot picking logic corrected --- .../linear_data_structures/algorithms.py | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index ea5491024..718e9b812 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -651,6 +651,15 @@ def quick_sort(array: Array, **kwargs) -> Array: Optional, by default, less than or equal to is used for comparing two values. + pick_pivot_element: lambda/function + The function implementing the pivot picking + logic for quick sort. Should accept, `low`, + `high`, and `array` in this order, where `low` + represents the left end of the current partition, + `high` represents the right end, and `array` is + the original input array to `quick_sort` function. + Optional, by default, picks the element at `high` + index of the current partition as pivot. Returns ======= @@ -678,10 +687,12 @@ def quick_sort(array: Array, **kwargs) -> Array: """ from pydatastructs import Stack comp = kwargs.get("comp", lambda u, v: u <= v) + pick_pivot_element = kwargs.get("pick_pivot_element", + lambda low, high, array: array[high]) - def partition(low, high): + def partition(low, high, pick_pivot_element): i = (low - 1) - x = array[high] + x = pick_pivot_element(low, high, array) for j in range(low , high): if _comp(array[j], x, comp) is True: i = i + 1 @@ -689,14 +700,9 @@ def partition(low, high): array[i + 1], array[high] = array[high], array[i + 1] return (i + 1) - def pivotselect(low, high): - pivot=kwargs.get('pick_pivot_element',high) - array[high], array[pivot] = array[pivot], array[high] - return partition(low, high) - lower = kwargs.get('start', 0) upper = kwargs.get('end', len(array) - 1) - stack, top = Stack(), -1 + stack = Stack() stack.push(lower) stack.push(upper) @@ -704,7 +710,7 @@ def pivotselect(low, high): while stack.is_empty is False: high = stack.pop() low = stack.pop() - p = pivotselect(low, high) + p = partition(low, high, pick_pivot_element) if p - 1 > low: stack.push(low) stack.push(p - 1) From a6fec403be50a1006db67815169e8dbdfd23e640 Mon Sep 17 00:00:00 2001 From: Arvind-raj06 Date: Sat, 16 Jan 2021 20:04:45 +0530 Subject: [PATCH 61/73] Completed --- .../linear_data_structures/__init__.py | 3 +- .../linear_data_structures/algorithms.py | 61 ++++++++++++++++++- .../tests/test_algorithms.py | 15 ++++- 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/pydatastructs/linear_data_structures/__init__.py b/pydatastructs/linear_data_structures/__init__.py index 89cca835c..d4d770c14 100644 --- a/pydatastructs/linear_data_structures/__init__.py +++ b/pydatastructs/linear_data_structures/__init__.py @@ -30,6 +30,7 @@ counting_sort, bucket_sort, cocktail_shaker_sort, - quick_sort + quick_sort, + longest_common_subsequence ) __all__.extend(algorithms.__all__) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 718e9b812..ee2ecafda 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -13,7 +13,8 @@ 'counting_sort', 'bucket_sort', 'cocktail_shaker_sort', - 'quick_sort' + 'quick_sort', + 'longest_common_subsequence' ] def _merge(array, sl, el, sr, er, end, comp): @@ -722,3 +723,61 @@ def partition(low, high, pick_pivot_element): array._modify(force=True) return array + +def longest_common_subsequence(seq1, seq2) -> tuple: + """ + Implements Longest Common Subsequence + + Parameters + ======== + + seq1: string or list + seq2: string or list + + Returns + ======= + + output: tuple + (Length of LCS, Common Sequence) + Common Sequence will be of the same data type is the seq1. + + Examples + ======== + + >>> from pydatastructs import longest_common_subsequence as LCS + >>> LCS("ABCDEF", "ABBCDDDE") + (5, 'ABCDE') + >>> arr1 = ['A', 'P', 'P'] + >>> arr2 = ['A', 'p', 'P', 'S', 'P'] + >>> LCS(arr1, arr2) + (3, ['A', 'P', 'P']) + + References + ========== + + .. [1] https://en.wikipedia.org/wiki/Longest_common_subsequence_problem + """ + + row, col = len(seq1), len(seq2) + check_mat = [[0 for _ in range(col+1)] for x in range(row+1)] + for i in range(row): + for j in range(col): + if (seq1[i] == seq2[j]): + check_mat[i+1][j+1] = check_mat[i][j]+1 + else: + check_mat[i+1][j+1] = max(check_mat[i+1][j], check_mat[i][j+1]) + + lcseq, lclen = [], check_mat[row][col] + while(row > 0 and col > 0): + if(check_mat[row][col] == check_mat[row][col-1]): + col -= 1 + elif(check_mat[row][col] == check_mat[row-1][col]): + row -= 1 + else: + lcseq.append(seq1[row-1]) + row -= 1 + col -= 1 + + if(type(seq1) == str): + lcseq = ''.join(lcseq) + return (lclen, lcseq[::-1]) diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index 60effb15a..59d823623 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -1,7 +1,7 @@ from pydatastructs import ( merge_sort_parallel, DynamicOneDimensionalArray, OneDimensionalArray, brick_sort, brick_sort_parallel, - heapsort, matrix_multiply_parallel, counting_sort, bucket_sort, cocktail_shaker_sort, quick_sort) + heapsort, matrix_multiply_parallel, counting_sort, bucket_sort, cocktail_shaker_sort, quick_sort, longest_common_subsequence) from pydatastructs.utils.raises_util import raises import random @@ -100,3 +100,16 @@ def test_matrix_multiply_parallel(): J = [[2, 1, 2], [1, 2, 1], [2, 2, 2]] output = matrix_multiply_parallel(I, J, num_threads=1) assert expected_result == output + +def test_longest_common_sequence(): + expected_result = (5, 'ASCII') + + str1, str2 = 'AASCCII', 'ASSCIIII' + output = longest_common_subsequence(str1, str2) + assert expected_result == output + + expected_result = (3, ['O', 'V', 'A']) + + I, J = ['O', 'V', 'A', 'L'], ['F', 'O', 'R', 'V', 'A', 'E', 'W'] + output = longest_common_subsequence(I, J) + assert expected_result == output From 96067eb9f5d60ce2da41bece8ee85fe7e421ae35 Mon Sep 17 00:00:00 2001 From: Arvind-raj06 Date: Sat, 16 Jan 2021 21:10:38 +0530 Subject: [PATCH 62/73] Error Correction --- pydatastructs/linear_data_structures/algorithms.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index ee2ecafda..00b3f1531 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -731,8 +731,8 @@ def longest_common_subsequence(seq1, seq2) -> tuple: Parameters ======== - seq1: string or list - seq2: string or list + seq1: String or List or Tuple + seq2: String or List or Tuple Returns ======= @@ -757,7 +757,8 @@ def longest_common_subsequence(seq1, seq2) -> tuple: .. [1] https://en.wikipedia.org/wiki/Longest_common_subsequence_problem """ - + if type(seq1) != str or type(seq1) != tuple or type(seq1) != list or type(seq2) != str or type(seq2) != tuple or type(seq2) != list: + raise TypeError("Only Strings, Tuple and List are allowed") row, col = len(seq1), len(seq2) check_mat = [[0 for _ in range(col+1)] for x in range(row+1)] for i in range(row): @@ -780,4 +781,6 @@ def longest_common_subsequence(seq1, seq2) -> tuple: if(type(seq1) == str): lcseq = ''.join(lcseq) + if(type(seq1) == tuple): + lcseq = tuple(lcseq) return (lclen, lcseq[::-1]) From a73bc2570e1258da7a0da8e1d053eaca9b58d0b8 Mon Sep 17 00:00:00 2001 From: Arvind-raj06 Date: Sat, 16 Jan 2021 21:15:12 +0530 Subject: [PATCH 63/73] Yep --- pydatastructs/linear_data_structures/algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 00b3f1531..9879ab8fb 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -757,7 +757,7 @@ def longest_common_subsequence(seq1, seq2) -> tuple: .. [1] https://en.wikipedia.org/wiki/Longest_common_subsequence_problem """ - if type(seq1) != str or type(seq1) != tuple or type(seq1) != list or type(seq2) != str or type(seq2) != tuple or type(seq2) != list: + if type(seq1) != str and type(seq1) != tuple and type(seq1) != list or type(seq2) != str and type(seq2) != tuple and type(seq2) != list: raise TypeError("Only Strings, Tuple and List are allowed") row, col = len(seq1), len(seq2) check_mat = [[0 for _ in range(col+1)] for x in range(row+1)] From 07fc3e907710c53b4e9100362a6a28fbb53e749e Mon Sep 17 00:00:00 2001 From: Arvind Raj T <46020497+Arvind-raj06@users.noreply.github.com> Date: Sat, 16 Jan 2021 21:25:00 +0530 Subject: [PATCH 64/73] Update algorithms.py --- pydatastructs/linear_data_structures/algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 9879ab8fb..08154f0a9 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -739,7 +739,7 @@ def longest_common_subsequence(seq1, seq2) -> tuple: output: tuple (Length of LCS, Common Sequence) - Common Sequence will be of the same data type is the seq1. + Common Sequence will be of the same data type as seq1. Examples ======== From 86f389c6110bd55c49467850942df8a1ba60b7ed Mon Sep 17 00:00:00 2001 From: Arvind-raj06 Date: Sat, 16 Jan 2021 21:28:19 +0530 Subject: [PATCH 65/73] Update algorithms.py --- pydatastructs/linear_data_structures/algorithms.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 9879ab8fb..8434bc41a 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -739,7 +739,7 @@ def longest_common_subsequence(seq1, seq2) -> tuple: output: tuple (Length of LCS, Common Sequence) - Common Sequence will be of the same data type is the seq1. + Common Sequence will be of the same data type as seq1. Examples ======== @@ -757,8 +757,11 @@ def longest_common_subsequence(seq1, seq2) -> tuple: .. [1] https://en.wikipedia.org/wiki/Longest_common_subsequence_problem """ - if type(seq1) != str and type(seq1) != tuple and type(seq1) != list or type(seq2) != str and type(seq2) != tuple and type(seq2) != list: + if type(seq1) != str and type(seq1) != tuple and type(seq1) != list: raise TypeError("Only Strings, Tuple and List are allowed") + if type(seq2) != str and type(seq2) != tuple and type(seq2) != list: + raise TypeError("Only Strings, Tuple and List are allowed") + row, col = len(seq1), len(seq2) check_mat = [[0 for _ in range(col+1)] for x in range(row+1)] for i in range(row): From 8c269605968f3d62de9dda8fc7d6159c5fdca79a Mon Sep 17 00:00:00 2001 From: Arvind-raj06 Date: Sat, 16 Jan 2021 21:51:05 +0530 Subject: [PATCH 66/73] Implement --- pydatastructs/linear_data_structures/algorithms.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 8434bc41a..9485bc9e0 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -757,9 +757,7 @@ def longest_common_subsequence(seq1, seq2) -> tuple: .. [1] https://en.wikipedia.org/wiki/Longest_common_subsequence_problem """ - if type(seq1) != str and type(seq1) != tuple and type(seq1) != list: - raise TypeError("Only Strings, Tuple and List are allowed") - if type(seq2) != str and type(seq2) != tuple and type(seq2) != list: + if not(isinstance(seq1, (str, tuple, list))) or not(isinstance(seq2, (str, tuple, list))): raise TypeError("Only Strings, Tuple and List are allowed") row, col = len(seq1), len(seq2) From 699b3b21d9744e73be00900e7b02278a55c5326c Mon Sep 17 00:00:00 2001 From: Arvind-raj06 Date: Sat, 16 Jan 2021 22:23:27 +0530 Subject: [PATCH 67/73] Update algorithms.py --- pydatastructs/linear_data_structures/algorithms.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 9485bc9e0..0eeff7eda 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -757,7 +757,9 @@ def longest_common_subsequence(seq1, seq2) -> tuple: .. [1] https://en.wikipedia.org/wiki/Longest_common_subsequence_problem """ - if not(isinstance(seq1, (str, tuple, list))) or not(isinstance(seq2, (str, tuple, list))): + if not(isinstance(seq1, (str, tuple, list))): + raise TypeError("Only Strings, Tuple and List are allowed") + if not(isinstance(seq2, (str, tuple, list))): raise TypeError("Only Strings, Tuple and List are allowed") row, col = len(seq1), len(seq2) From 0ae90852eaac78ee96a8a0a5c5bed518cfd00d06 Mon Sep 17 00:00:00 2001 From: Arvind-raj06 Date: Sat, 16 Jan 2021 22:36:00 +0530 Subject: [PATCH 68/73] Update algorithms.py --- pydatastructs/linear_data_structures/algorithms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 0eeff7eda..7a166b894 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -757,9 +757,9 @@ def longest_common_subsequence(seq1, seq2) -> tuple: .. [1] https://en.wikipedia.org/wiki/Longest_common_subsequence_problem """ - if not(isinstance(seq1, (str, tuple, list))): + if not isinstance(seq1, (str, tuple, list)): raise TypeError("Only Strings, Tuple and List are allowed") - if not(isinstance(seq2, (str, tuple, list))): + if not isinstance(seq2, (str, tuple, list)): raise TypeError("Only Strings, Tuple and List are allowed") row, col = len(seq1), len(seq2) From 90f108961a2c772cb3d6d7de5f1e1e178a4b4d76 Mon Sep 17 00:00:00 2001 From: Arvind-raj06 Date: Sun, 17 Jan 2021 10:56:10 +0530 Subject: [PATCH 69/73] Yes added --- .../linear_data_structures/tests/test_algorithms.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index 12cc9bb26..12dd9985e 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -114,3 +114,9 @@ def test_longest_common_sequence(): I, J = ['O', 'V', 'A', 'L'], ['F', 'O', 'R', 'V', 'A', 'E', 'W'] output = longest_common_subsequence(I, J) assert expected_result == output + + expected_result = (2, ('O', 't')) + + I, J = ('K', 'O', 't', 'H', 'E'), ('L', 'O', 'C', 't') + output = longest_common_subsequence(I, J) + assert expected_result == output From 2196ec258704fc66920cd98a4244cdc33e0add0b Mon Sep 17 00:00:00 2001 From: Arvind-raj06 Date: Sun, 17 Jan 2021 18:01:09 +0530 Subject: [PATCH 70/73] Update algorithms.py --- .../linear_data_structures/algorithms.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 7a166b894..288af678b 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -731,15 +731,16 @@ def longest_common_subsequence(seq1, seq2) -> tuple: Parameters ======== - seq1: String or List or Tuple - seq2: String or List or Tuple + seq1: Any 1D data structure that can be indexed (like list, tuple, string) + seq2: Any 1D data structure that can be indexed (like list, tuple, string) Returns ======= output: tuple - (Length of LCS, Common Sequence) - Common Sequence will be of the same data type as seq1. + The first element of the tuple represents the length of longest common subsequence and + the second element is the longest common subsequence itself. + Common subsequence will be of the same data type as that of input sequences. Examples ======== @@ -757,14 +758,10 @@ def longest_common_subsequence(seq1, seq2) -> tuple: .. [1] https://en.wikipedia.org/wiki/Longest_common_subsequence_problem """ - if not isinstance(seq1, (str, tuple, list)): - raise TypeError("Only Strings, Tuple and List are allowed") - if not isinstance(seq2, (str, tuple, list)): - raise TypeError("Only Strings, Tuple and List are allowed") - row, col = len(seq1), len(seq2) - check_mat = [[0 for _ in range(col+1)] for x in range(row+1)] + check_mat = {0:[0 for _ in range(col+1)]} for i in range(row): + check_mat[i+1]=[0 for _ in range(col+1)] for j in range(col): if (seq1[i] == seq2[j]): check_mat[i+1][j+1] = check_mat[i][j]+1 From 2766287ca3f840d40e4b25c4bbf80c4f5b03f79c Mon Sep 17 00:00:00 2001 From: Arvind-raj06 Date: Mon, 18 Jan 2021 21:47:27 +0530 Subject: [PATCH 71/73] Implemented --- .../linear_data_structures/algorithms.py | 76 +++++++++---------- .../tests/test_algorithms.py | 21 +++-- 2 files changed, 46 insertions(+), 51 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 288af678b..2c1ac18ba 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -724,63 +724,61 @@ def partition(low, high, pick_pivot_element): return array -def longest_common_subsequence(seq1, seq2) -> tuple: +def longest_common_subsequence(seq1: Array, seq2: Array, **kwargs) -> Array: """ Implements Longest Common Subsequence Parameters ======== - seq1: Any 1D data structure that can be indexed (like list, tuple, string) - seq2: Any 1D data structure that can be indexed (like list, tuple, string) + seq1: Array + The array which is to be sorted. + seq2: Array + The array which is to be sorted. Returns ======= - output: tuple - The first element of the tuple represents the length of longest common subsequence and - the second element is the longest common subsequence itself. - Common subsequence will be of the same data type as that of input sequences. + output: Array + Array is the longest common subsequence. Examples ======== - >>> from pydatastructs import longest_common_subsequence as LCS - >>> LCS("ABCDEF", "ABBCDDDE") - (5, 'ABCDE') - >>> arr1 = ['A', 'P', 'P'] - >>> arr2 = ['A', 'p', 'P', 'S', 'P'] - >>> LCS(arr1, arr2) - (3, ['A', 'P', 'P']) + >>> from pydatastructs import longest_common_subsequence as LCS, OneDimensionalArray as ODA + >>> arr1 = ODA(str, ['A', 'B', 'C', 'D', 'E']) + >>> arr2 = ODA(str, ['A', 'B', 'C', 'G' ,'D', 'E', 'F']) + >>> lcs = LCS(arr1, arr2) + >>> str(lcs) + "['A', 'B', 'C', 'D', 'E']" + >>> arr1 = ODA(str, ['A', 'P', 'P']) + >>> arr2 = ODA(str, ['A', 'p', 'P', 'S', 'P']) + >>> lcs = LCS(arr1, arr2) + >>> str(lcs) + "['A', 'P', 'P']" References ========== .. [1] https://en.wikipedia.org/wiki/Longest_common_subsequence_problem """ - row, col = len(seq1), len(seq2) - check_mat = {0:[0 for _ in range(col+1)]} - for i in range(row): - check_mat[i+1]=[0 for _ in range(col+1)] - for j in range(col): - if (seq1[i] == seq2[j]): - check_mat[i+1][j+1] = check_mat[i][j]+1 + from pydatastructs import OneDimensionalArray as ODA + row = kwargs.get('end', len(seq1)) + col = kwargs.get('end', len(seq2)) + check_mat = {0:[(0, []) for _ in range(col + 1)]} + + for i in range(1, row + 1): + check_mat[i] = [(0, []) for _ in range(col + 1)] + for j in range(1, col + 1): + if seq1[i-1] == seq2[j-1]: + temp = check_mat[i-1][j-1][1][:] + temp.append(seq1[i-1]) + check_mat[i][j] = (check_mat[i-1][j-1][0] + 1, temp) else: - check_mat[i+1][j+1] = max(check_mat[i+1][j], check_mat[i][j+1]) - - lcseq, lclen = [], check_mat[row][col] - while(row > 0 and col > 0): - if(check_mat[row][col] == check_mat[row][col-1]): - col -= 1 - elif(check_mat[row][col] == check_mat[row-1][col]): - row -= 1 - else: - lcseq.append(seq1[row-1]) - row -= 1 - col -= 1 - - if(type(seq1) == str): - lcseq = ''.join(lcseq) - if(type(seq1) == tuple): - lcseq = tuple(lcseq) - return (lclen, lcseq[::-1]) + if check_mat[i-1][j][0] > check_mat[i][j-1][0]: + check_mat[i][j] = check_mat[i-1][j] + else: + check_mat[i][j] = check_mat[i][j-1] + + lcseq = ODA(str, check_mat[row][col][-1]) + return lcseq diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index 12dd9985e..5ef9ca86c 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -103,20 +103,17 @@ def test_matrix_multiply_parallel(): assert expected_result == output def test_longest_common_sequence(): - expected_result = (5, 'ASCII') + ODA = OneDimensionalArray + expected_result = "['A', 'S', 'C', 'I', 'I']" - str1, str2 = 'AASCCII', 'ASSCIIII' + str1 = ODA(str, ['A', 'A', 'S', 'C', 'C', 'I', 'I']) + str2 = ODA(str, ['A', 'S', 'S', 'C', 'I', 'I', 'I', 'I']) output = longest_common_subsequence(str1, str2) - assert expected_result == output + assert expected_result == str(output) - expected_result = (3, ['O', 'V', 'A']) + expected_result = "['O', 'V', 'A']" - I, J = ['O', 'V', 'A', 'L'], ['F', 'O', 'R', 'V', 'A', 'E', 'W'] + I = ODA(str, ['O', 'V', 'A', 'L']) + J = ODA(str, ['F', 'O', 'R', 'V', 'A', 'E', 'W']) output = longest_common_subsequence(I, J) - assert expected_result == output - - expected_result = (2, ('O', 't')) - - I, J = ('K', 'O', 't', 'H', 'E'), ('L', 'O', 'C', 't') - output = longest_common_subsequence(I, J) - assert expected_result == output + assert expected_result == str(output) From a85e08bb7ade342c9791c7cd2cb93f7b7254b39b Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Tue, 19 Jan 2021 13:14:19 +0530 Subject: [PATCH 72/73] Added tests and fixed docs --- .../linear_data_structures/algorithms.py | 27 +++++++++++-------- .../tests/test_algorithms.py | 13 +++++++-- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 2c1ac18ba..74d1a34ae 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -724,23 +724,24 @@ def partition(low, high, pick_pivot_element): return array -def longest_common_subsequence(seq1: Array, seq2: Array, **kwargs) -> Array: +def longest_common_subsequence(seq1: OneDimensionalArray, seq2: OneDimensionalArray) -> OneDimensionalArray: """ - Implements Longest Common Subsequence + Finds the longest common subsequence between the + two given sequences. Parameters ======== seq1: Array - The array which is to be sorted. + The first sequence. seq2: Array - The array which is to be sorted. + The second sequence. Returns ======= output: Array - Array is the longest common subsequence. + The longest common subsequence. Examples ======== @@ -761,11 +762,16 @@ def longest_common_subsequence(seq1: Array, seq2: Array, **kwargs) -> Array: ========== .. [1] https://en.wikipedia.org/wiki/Longest_common_subsequence_problem + + Note + ==== + + The data types of elements across both the sequences + should be same. """ - from pydatastructs import OneDimensionalArray as ODA - row = kwargs.get('end', len(seq1)) - col = kwargs.get('end', len(seq2)) - check_mat = {0:[(0, []) for _ in range(col + 1)]} + row = len(seq1) + col = len(seq2) + check_mat = {0: [(0, []) for _ in range(col + 1)]} for i in range(1, row + 1): check_mat[i] = [(0, []) for _ in range(col + 1)] @@ -780,5 +786,4 @@ def longest_common_subsequence(seq1: Array, seq2: Array, **kwargs) -> Array: else: check_mat[i][j] = check_mat[i][j-1] - lcseq = ODA(str, check_mat[row][col][-1]) - return lcseq + return OneDimensionalArray(seq1._dtype, check_mat[row][col][-1]) diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index 5ef9ca86c..f50a3da89 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -109,11 +109,20 @@ def test_longest_common_sequence(): str1 = ODA(str, ['A', 'A', 'S', 'C', 'C', 'I', 'I']) str2 = ODA(str, ['A', 'S', 'S', 'C', 'I', 'I', 'I', 'I']) output = longest_common_subsequence(str1, str2) - assert expected_result == str(output) + assert str(output) == expected_result expected_result = "['O', 'V', 'A']" I = ODA(str, ['O', 'V', 'A', 'L']) J = ODA(str, ['F', 'O', 'R', 'V', 'A', 'E', 'W']) output = longest_common_subsequence(I, J) - assert expected_result == str(output) + assert str(output) == expected_result + + X = ODA(int, [1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1]) + Y = ODA(int, [1, 2, 3, 4, 4, 3, 2, 1]) + output = longest_common_subsequence(X, Y) + assert str(output) == '[1, 2, 3, 4, 4, 3, 2, 1]' + + Z = ODA(int, []) + output = longest_common_subsequence(Y, Z) + assert str(output) == '[]' From 478bf66508ca0cb2b7b1ea8d4fa47275c5c6569f Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Tue, 19 Jan 2021 13:14:49 +0530 Subject: [PATCH 73/73] fixed docs --- pydatastructs/linear_data_structures/algorithms.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 74d1a34ae..c6022c1ff 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -732,15 +732,15 @@ def longest_common_subsequence(seq1: OneDimensionalArray, seq2: OneDimensionalAr Parameters ======== - seq1: Array + seq1: OneDimensionalArray The first sequence. - seq2: Array + seq2: OneDimensionalArray The second sequence. Returns ======= - output: Array + output: OneDimensionalArray The longest common subsequence. Examples @@ -767,7 +767,7 @@ def longest_common_subsequence(seq1: OneDimensionalArray, seq2: OneDimensionalAr ==== The data types of elements across both the sequences - should be same. + should be same and should be comparable. """ row = len(seq1) col = len(seq2)