From 781be5244ba62970c785d11127332bd36279cc23 Mon Sep 17 00:00:00 2001 From: shellhub Date: Sat, 26 Sep 2020 03:50:00 +0800 Subject: [PATCH 01/10] Updated circular_linked_list --- .../linked_list/circular_linked_list.py | 289 +++++++----------- 1 file changed, 113 insertions(+), 176 deletions(-) diff --git a/data_structures/linked_list/circular_linked_list.py b/data_structures/linked_list/circular_linked_list.py index 19d6ee6c6cb3..500a68f41b34 100644 --- a/data_structures/linked_list/circular_linked_list.py +++ b/data_structures/linked_list/circular_linked_list.py @@ -2,201 +2,138 @@ class Node: - """ - Class to represent a single node. - - Each node has following attributes - * data - * next_ptr - """ - def __init__(self, data: Any): self.data = data - self.next_ptr = None + self.next = None class CircularLinkedList: - """ - Class to represent the CircularLinkedList. - - CircularLinkedList has following attributes. - * head - * length - """ def __init__(self): self.head = None - self.length = 0 - - def __len__(self) -> int: - """ - Dunder method to return length of the CircularLinkedList - >>> cll = CircularLinkedList() - >>> len(cll) - 0 - >>> cll.append(1) - >>> len(cll) - 1 - >>> cll.prepend(0) - >>> len(cll) - 2 - >>> cll.delete_front() - >>> len(cll) - 1 - >>> cll.delete_rear() - >>> len(cll) - 0 - """ - return self.length - - def __str__(self) -> str: - """ - Dunder method to represent the string representation of the CircularLinkedList - >>> cll = CircularLinkedList() - >>> print(cll) - Empty linked list - >>> cll.append(1) - >>> cll.append(2) - >>> print(cll) - => - """ - current_node = self.head - if not current_node: - return "Empty linked list" - - results = [current_node.data] - current_node = current_node.next_ptr - - while current_node != self.head: - results.append(current_node.data) - current_node = current_node.next_ptr - - return " => ".join(f"" for result in results) - - def append(self, data: Any) -> None: - """ - Adds a node with given data to the end of the CircularLinkedList - >>> cll = CircularLinkedList() - >>> cll.append(1) - >>> print(f"{len(cll)}: {cll}") - 1: - >>> cll.append(2) - >>> print(f"{len(cll)}: {cll}") - 2: => - """ - current_node = self.head + self.tail = None - new_node = Node(data) - new_node.next_ptr = new_node + def __iter__(self): + node = self.head + while self.head is not None: + yield node.data + node = node.next + if node == self.head: + break - if current_node: - while current_node.next_ptr != self.head: - current_node = current_node.next_ptr + def __len__(self) -> int: + return len(tuple(iter(self))) - current_node.next_ptr = new_node - new_node.next_ptr = self.head - else: - self.head = new_node + def __repr__(self): + return "->".join(str(item) for item in iter(self)) - self.length += 1 + def insert_tail(self, data: Any) -> None: + self.insert_nth(len(self), data) - def prepend(self, data: Any) -> None: - """ - Adds a node with given data to the front of the CircularLinkedList - >>> cll = CircularLinkedList() - >>> cll.prepend(1) - >>> cll.prepend(2) - >>> print(f"{len(cll)}: {cll}") - 2: => - """ - current_node = self.head + def insert_head(self, data: Any) -> None: + self.insert_nth(0, data) + def insert_nth(self, index: int, data: Any) -> None: + if index < 0 or index > len(self): + raise IndexError("list index out of range.") new_node = Node(data) - new_node.next_ptr = new_node - - if current_node: - while current_node.next_ptr != self.head: - current_node = current_node.next_ptr - - current_node.next_ptr = new_node - new_node.next_ptr = self.head - - self.head = new_node - self.length += 1 - - def delete_front(self) -> None: - """ - Removes the 1st node from the CircularLinkedList - >>> cll = CircularLinkedList() - >>> cll.delete_front() - Traceback (most recent call last): - ... - IndexError: Deleting from an empty list - >>> cll.append(1) - >>> cll.append(2) - >>> print(f"{len(cll)}: {cll}") - 2: => - >>> cll.delete_front() - >>> print(f"{len(cll)}: {cll}") - 1: - >>> cll.delete_front() - >>> print(f"{len(cll)}: {cll}") - 0: Empty linked list - """ - if not self.head: - raise IndexError("Deleting from an empty list") - - current_node = self.head - - if current_node.next_ptr == current_node: - self.head = None + if self.head is None: + new_node.next = new_node # first node points itself + self.tail = self.head = new_node + elif index == 0: # insert at head + new_node.next = self.head + self.head = self.tail.next = new_node else: - while current_node.next_ptr != self.head: - current_node = current_node.next_ptr - - current_node.next_ptr = self.head.next_ptr - self.head = self.head.next_ptr - - self.length -= 1 - if not self.head: - assert self.length == 0 - - def delete_rear(self) -> None: - """ - Removes the last node from the CircularLinkedList - >>> cll = CircularLinkedList() - >>> cll.delete_rear() - Traceback (most recent call last): - ... - IndexError: Deleting from an empty list - >>> cll.append(1) - >>> cll.append(2) - >>> print(f"{len(cll)}: {cll}") - 2: => - >>> cll.delete_rear() - >>> print(f"{len(cll)}: {cll}") - 1: - >>> cll.delete_rear() - >>> print(f"{len(cll)}: {cll}") - 0: Empty linked list - """ - if not self.head: - raise IndexError("Deleting from an empty list") - - temp_node, current_node = self.head, self.head - - if current_node.next_ptr == current_node: - self.head = None + temp = self.head + for _ in range(index - 1): + temp = temp.next + new_node.next = temp.next + temp.next = new_node + if index == len(self) - 1: # insert at tail + self.tail = new_node + + def delete_front(self): + return self.delete_nth(0) + + def delete_tail(self) -> None: + return self.delete_nth(len(self) - 1) + + def delete_nth(self, index: int = 0): + if not 0 <= index < len(self): + raise IndexError("list index out of range.") + delete_node = self.head + if self.head == self.tail: # just one node + self.head = self.tail = None + elif index == 0: # delete head node + self.tail.next = self.tail.next.next + self.head = self.head.next else: - while current_node.next_ptr != self.head: - temp_node = current_node - current_node = current_node.next_ptr + temp = self.head + for _ in range(index - 1): + temp = temp.next + delete_node = temp.next + temp.next = temp.next.next + if index == len(self) - 1: # delete at tail + self.tail = temp + return delete_node.data - temp_node.next_ptr = current_node.next_ptr + def print_list(self) -> None: + print(self) - self.length -= 1 - if not self.head: - assert self.length == 0 + def is_empty(self): + return len(self) == 0 + + +def test_circular_linked_list() -> None: + """ + >>> test_circular_linked_list() + """ + circular_linked_list = CircularLinkedList() + assert len(circular_linked_list) == 0 + assert circular_linked_list.is_empty() is True + assert str(circular_linked_list) == "" + + try: + circular_linked_list.delete_front() + assert False # This should not happen + except IndexError: + assert True # This should happen + + try: + circular_linked_list.delete_tail() + assert False # This should not happen + except IndexError: + assert True # This should happen + + try: + circular_linked_list.delete_nth(-1) + assert False + except IndexError: + assert True + + try: + circular_linked_list.delete_nth(0) + assert False + except IndexError: + assert True + + for i in range(5): + assert len(circular_linked_list) == i + circular_linked_list.insert_nth(i, i + 1) + assert str(circular_linked_list) == "->".join(str(i) for i in range(1, 6)) + + circular_linked_list.insert_tail(6) + assert str(circular_linked_list) == "->".join(str(i) for i in range(1, 7)) + circular_linked_list.insert_head(0) + assert str(circular_linked_list) == "->".join(str(i) for i in range(0, 7)) + + assert circular_linked_list.delete_front() == 0 + assert circular_linked_list.delete_tail() == 6 + assert str(circular_linked_list) == "->".join(str(i) for i in range(1, 6)) + assert circular_linked_list.delete_nth(2) == 3 + + circular_linked_list.insert_nth(2, 3) + assert str(circular_linked_list) == "->".join(str(i) for i in range(1, 6)) if __name__ == "__main__": From c8fbb3af7d666edbff258f05ae8609148f3168cd Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Fri, 25 Sep 2020 19:51:02 +0000 Subject: [PATCH 02/10] fixup! Format Python code with psf/black push --- data_structures/linked_list/circular_linked_list.py | 1 - 1 file changed, 1 deletion(-) diff --git a/data_structures/linked_list/circular_linked_list.py b/data_structures/linked_list/circular_linked_list.py index 500a68f41b34..3d6b32c66536 100644 --- a/data_structures/linked_list/circular_linked_list.py +++ b/data_structures/linked_list/circular_linked_list.py @@ -8,7 +8,6 @@ def __init__(self, data: Any): class CircularLinkedList: - def __init__(self): self.head = None self.tail = None From d39c1f0d2925baed7a7999777522924eb93b169d Mon Sep 17 00:00:00 2001 From: Du Yuanchao Date: Sat, 26 Sep 2020 09:11:20 +0800 Subject: [PATCH 03/10] Update data_structures/linked_list/circular_linked_list.py Co-authored-by: Christian Clauss --- data_structures/linked_list/circular_linked_list.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/linked_list/circular_linked_list.py b/data_structures/linked_list/circular_linked_list.py index 3d6b32c66536..c5c187967ea3 100644 --- a/data_structures/linked_list/circular_linked_list.py +++ b/data_structures/linked_list/circular_linked_list.py @@ -14,7 +14,7 @@ def __init__(self): def __iter__(self): node = self.head - while self.head is not None: + while self.head: yield node.data node = node.next if node == self.head: From 915bb358eec391f71298771b7c6ffdc5ed239a0d Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 26 Sep 2020 01:12:15 +0000 Subject: [PATCH 04/10] updating DIRECTORY.md --- DIRECTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index f08c31794b1e..3227711c7853 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -646,6 +646,8 @@ * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_67/sol1.py) * Problem 76 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_76/sol1.py) + * Problem 97 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_97/sol1.py) * Problem 99 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_99/sol1.py) From 86c464e2bba4e148c182818e772d199d14186d53 Mon Sep 17 00:00:00 2001 From: Du Yuanchao Date: Sat, 26 Sep 2020 21:09:01 +0800 Subject: [PATCH 05/10] delete print_list() --- data_structures/linked_list/circular_linked_list.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/data_structures/linked_list/circular_linked_list.py b/data_structures/linked_list/circular_linked_list.py index c5c187967ea3..6cf9a7e1f37a 100644 --- a/data_structures/linked_list/circular_linked_list.py +++ b/data_structures/linked_list/circular_linked_list.py @@ -76,9 +76,6 @@ def delete_nth(self, index: int = 0): self.tail = temp return delete_node.data - def print_list(self) -> None: - print(self) - def is_empty(self): return len(self) == 0 From 13eec9b480d22148f88e73b617c421d4d8464694 Mon Sep 17 00:00:00 2001 From: Du Yuanchao Date: Sat, 26 Sep 2020 21:10:17 +0800 Subject: [PATCH 06/10] test is_empty() --- data_structures/linked_list/circular_linked_list.py | 1 + 1 file changed, 1 insertion(+) diff --git a/data_structures/linked_list/circular_linked_list.py b/data_structures/linked_list/circular_linked_list.py index 6cf9a7e1f37a..43c8cd442b99 100644 --- a/data_structures/linked_list/circular_linked_list.py +++ b/data_structures/linked_list/circular_linked_list.py @@ -113,6 +113,7 @@ def test_circular_linked_list() -> None: except IndexError: assert True + assert circular_linked_list.is_empty() is True for i in range(5): assert len(circular_linked_list) == i circular_linked_list.insert_nth(i, i + 1) From 0ccb0050e2d55d6f108026dfc3708b424aa758ef Mon Sep 17 00:00:00 2001 From: Du Yuanchao Date: Sat, 26 Sep 2020 21:53:38 +0800 Subject: [PATCH 07/10] test is_empty return False --- data_structures/linked_list/circular_linked_list.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data_structures/linked_list/circular_linked_list.py b/data_structures/linked_list/circular_linked_list.py index 43c8cd442b99..05e4d44be12a 100644 --- a/data_structures/linked_list/circular_linked_list.py +++ b/data_structures/linked_list/circular_linked_list.py @@ -132,6 +132,8 @@ def test_circular_linked_list() -> None: circular_linked_list.insert_nth(2, 3) assert str(circular_linked_list) == "->".join(str(i) for i in range(1, 6)) +assert circular_linked_list.is_empty() is False + if __name__ == "__main__": import doctest From 947acff0fab565fdfc0379f49c6da37027083404 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 26 Sep 2020 13:54:38 +0000 Subject: [PATCH 08/10] fixup! Format Python code with psf/black push --- data_structures/linked_list/circular_linked_list.py | 1 + 1 file changed, 1 insertion(+) diff --git a/data_structures/linked_list/circular_linked_list.py b/data_structures/linked_list/circular_linked_list.py index 05e4d44be12a..59f07ba9e35a 100644 --- a/data_structures/linked_list/circular_linked_list.py +++ b/data_structures/linked_list/circular_linked_list.py @@ -132,6 +132,7 @@ def test_circular_linked_list() -> None: circular_linked_list.insert_nth(2, 3) assert str(circular_linked_list) == "->".join(str(i) for i in range(1, 6)) + assert circular_linked_list.is_empty() is False From 633f5448b0ace8c9177640eed12c3a64bb35e4de Mon Sep 17 00:00:00 2001 From: Du Yuanchao Date: Sat, 26 Sep 2020 22:16:47 +0800 Subject: [PATCH 09/10] fixed indentation --- data_structures/linked_list/circular_linked_list.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/linked_list/circular_linked_list.py b/data_structures/linked_list/circular_linked_list.py index 59f07ba9e35a..189b5befa3ef 100644 --- a/data_structures/linked_list/circular_linked_list.py +++ b/data_structures/linked_list/circular_linked_list.py @@ -133,7 +133,7 @@ def test_circular_linked_list() -> None: assert str(circular_linked_list) == "->".join(str(i) for i in range(1, 6)) -assert circular_linked_list.is_empty() is False + assert circular_linked_list.is_empty() is False if __name__ == "__main__": From f5dc183d72efed3fde227e2945b097b950c9b4fc Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 26 Sep 2020 14:17:42 +0000 Subject: [PATCH 10/10] fixup! Format Python code with psf/black push --- data_structures/linked_list/circular_linked_list.py | 1 - 1 file changed, 1 deletion(-) diff --git a/data_structures/linked_list/circular_linked_list.py b/data_structures/linked_list/circular_linked_list.py index 189b5befa3ef..f67c1e8f2cf7 100644 --- a/data_structures/linked_list/circular_linked_list.py +++ b/data_structures/linked_list/circular_linked_list.py @@ -132,7 +132,6 @@ def test_circular_linked_list() -> None: circular_linked_list.insert_nth(2, 3) assert str(circular_linked_list) == "->".join(str(i) for i in range(1, 6)) - assert circular_linked_list.is_empty() is False