From 76fd929dd11a9d08f0cf40423f85da4595cea242 Mon Sep 17 00:00:00 2001 From: ArunSiva Date: Sat, 14 Oct 2023 18:17:41 +0530 Subject: [PATCH 01/10] earliest deadline first scheduling algo added --- scheduling/shortest_deadline_first.py | 64 +++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 scheduling/shortest_deadline_first.py diff --git a/scheduling/shortest_deadline_first.py b/scheduling/shortest_deadline_first.py new file mode 100644 index 000000000000..2d84aa18313c --- /dev/null +++ b/scheduling/shortest_deadline_first.py @@ -0,0 +1,64 @@ +''' +Earliest Deadline First (EDF) Scheduling Algorithm + +This code implements the Earliest Deadline First (EDF) +scheduling algorithm, which schedules processes based on their deadlines. +If a process cannot meet its deadline, it is marked as "Idle." + +Reference: +https://www.geeksforgeeks.org/earliest-deadline-first-edf-cpu-scheduling-algorithm/ + +Author: Arunkumar +Date: 14th October 2023 +''' + +def earliest_deadline_first_scheduling(processes: list[tuple[str, int, int, int]]) -> list[str]: + """ + Perform Earliest Deadline First (EDF) scheduling. + + Args: + processes (List[Tuple[str, int, int, int]]): A list of processes with their names, + arrival times, deadlines, and execution times. + + Returns: + List[str]: A list of process names in the order they are executed. + + Examples: + >>> processes = [("A", 1, 5, 2), ("B", 2, 8, 3), ("C", 3, 4, 1)] + >>> execution_order = earliest_deadline_first_scheduling(processes) + >>> execution_order + ['Idle', 'A', 'C', 'B'] + + """ + result = [] + current_time = 0 + + while processes: + available_processes = [ + process for process in processes if process[1] <= current_time + ] + + if not available_processes: + result.append("Idle") + current_time += 1 + else: + next_process = min( + available_processes, key=lambda x: x[2] + ) + name, _ , deadline, execution_time = next_process + + if current_time + execution_time <= deadline: + result.append(name) + current_time += execution_time + processes.remove(next_process) + else: + result.append("Idle") + current_time += 1 + + return result + +if __name__ == "__main__": + processes = [("A", 1, 5, 2), ("B", 2, 8, 3), ("C", 3, 4, 1)] + execution_order = earliest_deadline_first_scheduling(processes) + for i, process in enumerate(execution_order): + print(f"Time {i}: Executing process {process}") From 4363669194897f37e8c0d03bb61fed87215beea8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 14 Oct 2023 12:49:42 +0000 Subject: [PATCH 02/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- scheduling/shortest_deadline_first.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/scheduling/shortest_deadline_first.py b/scheduling/shortest_deadline_first.py index 2d84aa18313c..cd93bf2f6be4 100644 --- a/scheduling/shortest_deadline_first.py +++ b/scheduling/shortest_deadline_first.py @@ -1,18 +1,21 @@ -''' +""" Earliest Deadline First (EDF) Scheduling Algorithm This code implements the Earliest Deadline First (EDF) scheduling algorithm, which schedules processes based on their deadlines. If a process cannot meet its deadline, it is marked as "Idle." -Reference: +Reference: https://www.geeksforgeeks.org/earliest-deadline-first-edf-cpu-scheduling-algorithm/ Author: Arunkumar Date: 14th October 2023 -''' +""" -def earliest_deadline_first_scheduling(processes: list[tuple[str, int, int, int]]) -> list[str]: + +def earliest_deadline_first_scheduling( + processes: list[tuple[str, int, int, int]] +) -> list[str]: """ Perform Earliest Deadline First (EDF) scheduling. @@ -42,10 +45,8 @@ def earliest_deadline_first_scheduling(processes: list[tuple[str, int, int, int] result.append("Idle") current_time += 1 else: - next_process = min( - available_processes, key=lambda x: x[2] - ) - name, _ , deadline, execution_time = next_process + next_process = min(available_processes, key=lambda x: x[2]) + name, _, deadline, execution_time = next_process if current_time + execution_time <= deadline: result.append(name) @@ -57,6 +58,7 @@ def earliest_deadline_first_scheduling(processes: list[tuple[str, int, int, int] return result + if __name__ == "__main__": processes = [("A", 1, 5, 2), ("B", 2, 8, 3), ("C", 3, 4, 1)] execution_order = earliest_deadline_first_scheduling(processes) From bbac298effa4e9a0be6402945f880b1f7c66f642 Mon Sep 17 00:00:00 2001 From: ArunSiva Date: Sat, 14 Oct 2023 18:21:54 +0530 Subject: [PATCH 03/10] earliest deadline first scheduling algo added --- scheduling/shortest_deadline_first.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/scheduling/shortest_deadline_first.py b/scheduling/shortest_deadline_first.py index 2d84aa18313c..c4148e8e40d1 100644 --- a/scheduling/shortest_deadline_first.py +++ b/scheduling/shortest_deadline_first.py @@ -6,19 +6,22 @@ If a process cannot meet its deadline, it is marked as "Idle." Reference: -https://www.geeksforgeeks.org/earliest-deadline-first-edf-cpu-scheduling-algorithm/ +https://www.geeksforgeeks.org/ +earliest-deadline-first-edf-cpu-scheduling-algorithm/ Author: Arunkumar Date: 14th October 2023 ''' -def earliest_deadline_first_scheduling(processes: list[tuple[str, int, int, int]]) -> list[str]: +def earliest_deadline_first_scheduling(processes: + list[tuple[str, int, int, int]]) -> list[str]: """ Perform Earliest Deadline First (EDF) scheduling. Args: - processes (List[Tuple[str, int, int, int]]): A list of processes with their names, - arrival times, deadlines, and execution times. + processes (List[Tuple[str, int, int, int]]): A list of + processes with their names, + arrival times, deadlines, and execution times. Returns: List[str]: A list of process names in the order they are executed. From 628b1b30ac0a0a2cfa2809aeb2dc2f8c96214117 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 14 Oct 2023 12:58:12 +0000 Subject: [PATCH 04/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- scheduling/shortest_deadline_first.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scheduling/shortest_deadline_first.py b/scheduling/shortest_deadline_first.py index 79c705ca1e48..6201625c7374 100644 --- a/scheduling/shortest_deadline_first.py +++ b/scheduling/shortest_deadline_first.py @@ -5,7 +5,7 @@ scheduling algorithm, which schedules processes based on their deadlines. If a process cannot meet its deadline, it is marked as "Idle." -Reference: +Reference: https://www.geeksforgeeks.org/ earliest-deadline-first-edf-cpu-scheduling-algorithm/ @@ -13,8 +13,10 @@ Date: 14th October 2023 """ -def earliest_deadline_first_scheduling(processes: - list[tuple[str, int, int, int]]) -> list[str]: + +def earliest_deadline_first_scheduling( + processes: list[tuple[str, int, int, int]] +) -> list[str]: """ Perform Earliest Deadline First (EDF) scheduling. @@ -45,7 +47,9 @@ def earliest_deadline_first_scheduling(processes: result.append("Idle") current_time += 1 else: - next_process = min(available_processes, key=lambda tuple_values: tuple_values[2]) + next_process = min( + available_processes, key=lambda tuple_values: tuple_values[2] + ) name, _, deadline, execution_time = next_process if current_time + execution_time <= deadline: From 9397c738b0005b0c2ade4073009b70e768fe821c Mon Sep 17 00:00:00 2001 From: ArunSiva Date: Sat, 14 Oct 2023 18:52:28 +0530 Subject: [PATCH 05/10] ceil and floor and bst --- .../binary_tree/floor_ceil_in_bst.py | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 data_structures/binary_tree/floor_ceil_in_bst.py diff --git a/data_structures/binary_tree/floor_ceil_in_bst.py b/data_structures/binary_tree/floor_ceil_in_bst.py new file mode 100644 index 000000000000..b3c54c043f91 --- /dev/null +++ b/data_structures/binary_tree/floor_ceil_in_bst.py @@ -0,0 +1,81 @@ +''' +The floor of a key 'k' in a BST is the maximum +value that is smaller than or equal to 'k'. + +The ceiling of a key 'k' in a BST is the minimum +value that is greater than or equal to 'k'. + +Reference: +https://bit.ly/46uB0a2 + + +Author : Arunkumar +Date : 14th October 2023 + +''' + + +from typing import Optional + +class TreeNode: + def __init__(self, key: int): + """ + Initialize a TreeNode with the given key. + + Args: + key (int): The key value for the node. + """ + self.key = key + self.left: Optional[TreeNode] = None + self.right: Optional[TreeNode] = None + +def floor_ceiling(root: Optional[TreeNode], key: int) -> tuple[Optional[int], Optional[int]]: + """ + Find the floor and ceiling values for a given key in a Binary Search Tree (BST). + + Args: + root (TreeNode): The root of the BST. + key (int): The key for which to find the floor and ceiling. + + Returns: + tuple[Optional[int], Optional[int]]: A tuple containing the floor and ceiling values, respectively. + + Examples: + >>> root = TreeNode(10) + >>> root.left = TreeNode(5) + >>> root.right = TreeNode(20) + >>> root.left.left = TreeNode(3) + >>> root.left.right = TreeNode(7) + >>> root.right.left = TreeNode(15) + >>> root.right.right = TreeNode(25) + >>> floor, ceiling = floor_ceiling(root, 8) + >>> floor + 7 + >>> ceiling + 10 + >>> floor, ceiling = floor_ceiling(root, 14) + >>> floor + 10 + >>> ceiling + 15 + """ + floor_val = None + ceiling_val = None + + while root is not None: + if root.key == key: + return root.key, root.key + + if key < root.key: + ceiling_val = root.key + root = root.left + else: + floor_val = root.key + root = root.right + + return floor_val, ceiling_val + +if __name__ == "__main__": + import doctest + + doctest.testmod() From 31e43db90d7d98dd28f7bd1ee8f5aca11f0d9892 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 14 Oct 2023 13:24:46 +0000 Subject: [PATCH 06/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- data_structures/binary_tree/floor_ceil_in_bst.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/data_structures/binary_tree/floor_ceil_in_bst.py b/data_structures/binary_tree/floor_ceil_in_bst.py index b3c54c043f91..7b5ca0c51042 100644 --- a/data_structures/binary_tree/floor_ceil_in_bst.py +++ b/data_structures/binary_tree/floor_ceil_in_bst.py @@ -1,4 +1,4 @@ -''' +""" The floor of a key 'k' in a BST is the maximum value that is smaller than or equal to 'k'. @@ -12,16 +12,17 @@ Author : Arunkumar Date : 14th October 2023 -''' +""" from typing import Optional + class TreeNode: def __init__(self, key: int): """ Initialize a TreeNode with the given key. - + Args: key (int): The key value for the node. """ @@ -29,7 +30,10 @@ def __init__(self, key: int): self.left: Optional[TreeNode] = None self.right: Optional[TreeNode] = None -def floor_ceiling(root: Optional[TreeNode], key: int) -> tuple[Optional[int], Optional[int]]: + +def floor_ceiling( + root: Optional[TreeNode], key: int +) -> tuple[Optional[int], Optional[int]]: """ Find the floor and ceiling values for a given key in a Binary Search Tree (BST). @@ -75,6 +79,7 @@ def floor_ceiling(root: Optional[TreeNode], key: int) -> tuple[Optional[int], Op return floor_val, ceiling_val + if __name__ == "__main__": import doctest From 22f40d95bedefb4d79fe5cf9f5317ae96a501f4a Mon Sep 17 00:00:00 2001 From: ArunSiva Date: Sat, 14 Oct 2023 19:05:33 +0530 Subject: [PATCH 07/10] ceil and floor and bst 2 --- .../binary_tree/floor_ceil_in_bst.py | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/data_structures/binary_tree/floor_ceil_in_bst.py b/data_structures/binary_tree/floor_ceil_in_bst.py index b3c54c043f91..b1b138ff7a4b 100644 --- a/data_structures/binary_tree/floor_ceil_in_bst.py +++ b/data_structures/binary_tree/floor_ceil_in_bst.py @@ -1,4 +1,4 @@ -''' +""" The floor of a key 'k' in a BST is the maximum value that is smaller than or equal to 'k'. @@ -8,28 +8,25 @@ Reference: https://bit.ly/46uB0a2 - Author : Arunkumar Date : 14th October 2023 - -''' +""" -from typing import Optional - class TreeNode: def __init__(self, key: int): """ Initialize a TreeNode with the given key. - + Args: key (int): The key value for the node. """ self.key = key - self.left: Optional[TreeNode] = None - self.right: Optional[TreeNode] = None + self.left: TreeNode | None = None + self.right: TreeNode | None = None -def floor_ceiling(root: Optional[TreeNode], key: int) -> tuple[Optional[int], Optional[int]]: + +def floor_ceiling(root: TreeNode | None, key: int) -> tuple[int | None, int | None]: """ Find the floor and ceiling values for a given key in a Binary Search Tree (BST). @@ -38,7 +35,8 @@ def floor_ceiling(root: Optional[TreeNode], key: int) -> tuple[Optional[int], Op key (int): The key for which to find the floor and ceiling. Returns: - tuple[Optional[int], Optional[int]]: A tuple containing the floor and ceiling values, respectively. + tuple[int | None, int | None]: + A tuple containing the floor and ceiling values, respectively. Examples: >>> root = TreeNode(10) @@ -64,7 +62,9 @@ def floor_ceiling(root: Optional[TreeNode], key: int) -> tuple[Optional[int], Op while root is not None: if root.key == key: - return root.key, root.key + floor_val = root.key + ceiling_val = root.key + break if key < root.key: ceiling_val = root.key @@ -75,6 +75,7 @@ def floor_ceiling(root: Optional[TreeNode], key: int) -> tuple[Optional[int], Op return floor_val, ceiling_val + if __name__ == "__main__": import doctest From 6238c4a6efebee69f8e04895a370e327917bcd0a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 14 Oct 2023 13:38:53 +0000 Subject: [PATCH 08/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- data_structures/binary_tree/floor_ceil_in_bst.py | 1 - 1 file changed, 1 deletion(-) diff --git a/data_structures/binary_tree/floor_ceil_in_bst.py b/data_structures/binary_tree/floor_ceil_in_bst.py index bec75156da8e..b1b138ff7a4b 100644 --- a/data_structures/binary_tree/floor_ceil_in_bst.py +++ b/data_structures/binary_tree/floor_ceil_in_bst.py @@ -13,7 +13,6 @@ """ - class TreeNode: def __init__(self, key: int): """ From f845dd4cb8b720844440e77da6d1572a3e841c95 Mon Sep 17 00:00:00 2001 From: ArunSiva Date: Sat, 14 Oct 2023 19:11:26 +0530 Subject: [PATCH 09/10] ceil and floor and bst 3 --- data_structures/binary_tree/floor_ceil_in_bst.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data_structures/binary_tree/floor_ceil_in_bst.py b/data_structures/binary_tree/floor_ceil_in_bst.py index bec75156da8e..18417a83fcc2 100644 --- a/data_structures/binary_tree/floor_ceil_in_bst.py +++ b/data_structures/binary_tree/floor_ceil_in_bst.py @@ -13,9 +13,8 @@ """ - class TreeNode: - def __init__(self, key: int): + def __init__(self, key: int) -> None: """ Initialize a TreeNode with the given key. From 21dfa200cb5973a85d11e7a88df7edd1da26e6ee Mon Sep 17 00:00:00 2001 From: ArunSiva Date: Fri, 20 Oct 2023 16:10:11 +0530 Subject: [PATCH 10/10] optimized and corrected longest increasing subsequence problem --- .../longest_increasing_subsequence.py | 69 +++++++++++-------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/dynamic_programming/longest_increasing_subsequence.py b/dynamic_programming/longest_increasing_subsequence.py index d827893763c5..629799d4a46b 100644 --- a/dynamic_programming/longest_increasing_subsequence.py +++ b/dynamic_programming/longest_increasing_subsequence.py @@ -1,5 +1,6 @@ """ Author : Mehdi ALAOUI +Optimized : Arunkumar This is a pure Python implementation of Dynamic Programming solution to the longest increasing subsequence of a given sequence. @@ -13,46 +14,54 @@ from __future__ import annotations -def longest_subsequence(array: list[int]) -> list[int]: # This function is recursive +def longest_subsequence(array: list[int]) -> list[int]: """ - Some examples + Find the longest increasing subsequence in the given array + using dynamic programming. + + Args: + array (list[int]): The input array. + + Returns: + list[int]: The longest increasing subsequence. + + Examples: >>> longest_subsequence([10, 22, 9, 33, 21, 50, 41, 60, 80]) [10, 22, 33, 41, 60, 80] >>> longest_subsequence([4, 8, 7, 5, 1, 12, 2, 3, 9]) [1, 2, 3, 9] >>> longest_subsequence([9, 8, 7, 6, 5, 7]) - [8] + [5, 7] >>> longest_subsequence([1, 1, 1]) - [1, 1, 1] + [1] >>> longest_subsequence([]) [] """ - array_length = len(array) - # If the array contains only one element, we return it (it's the stop condition of - # recursion) - if array_length <= 1: - return array - # Else - pivot = array[0] - is_found = False - i = 1 - longest_subseq: list[int] = [] - while not is_found and i < array_length: - if array[i] < pivot: - is_found = True - temp_array = [element for element in array[i:] if element >= array[i]] - temp_array = longest_subsequence(temp_array) - if len(temp_array) > len(longest_subseq): - longest_subseq = temp_array - else: - i += 1 - - temp_array = [element for element in array[1:] if element >= pivot] - temp_array = [pivot, *longest_subsequence(temp_array)] - if len(temp_array) > len(longest_subseq): - return temp_array - else: - return longest_subseq + if not array: + return [] + + n = len(array) + # Initialize an array to store the length of the longest + # increasing subsequence ending at each position. + lis_lengths = [1] * n + + for i in range(1, n): + for j in range(i): + if array[i] > array[j]: + lis_lengths[i] = max(lis_lengths[i], lis_lengths[j] + 1) + + # Find the maximum length of the increasing subsequence. + max_length = max(lis_lengths) + + # Reconstruct the longest subsequence in reverse order. + subsequence = [] + current_length = max_length + for i in range(n - 1, -1, -1): + if lis_lengths[i] == current_length: + subsequence.append(array[i]) + current_length -= 1 + + return subsequence[::-1] # Reverse the subsequence to get the correct order. if __name__ == "__main__":