From 2364494193359c16160ee760bd02da995ab314d7 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Wed, 2 Oct 2024 12:41:04 +0530 Subject: [PATCH 1/7] Add activity selection new algorithm --- greedy_methods/activity_selection.py | 52 ++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 greedy_methods/activity_selection.py diff --git a/greedy_methods/activity_selection.py b/greedy_methods/activity_selection.py new file mode 100644 index 000000000000..ab5405ddb497 --- /dev/null +++ b/greedy_methods/activity_selection.py @@ -0,0 +1,52 @@ +""" +The Activity Selection Problem is a classic problem in which a set of activities, +each with a start and end time, needs to be scheduled in such a way that +the maximum number of non-overlapping activities is selected. +This is a greedy algorithm where at each step, +we choose the activity that finishes the earliest +and does not conflict with previously selected activities. + +Wikipedia: https://en.wikipedia.org/wiki/Activity_selection_problem +""" + + +def activity_selection(activities: list[tuple[int, int]]) -> list[tuple[int, int]]: + """ + Solve the Activity Selection Problem using a greedy algorithm by selecting + the maximum number of non-overlapping activities from a list of activities. + + Parameters: + activities: A list of tuples where each tuple contains + the start and end times of an activity. + + Returns: + A list of selected activities that are non-overlapping. + + Example: + >>> activity_selection([(1, 3), (2, 5), (3, 9), (6, 8)]) + [(1, 3), (6, 8)] + + >>> activity_selection([(0, 6), (1, 4), (3, 5), (5, 7), (5, 9), (8, 9)]) + [(1, 4), (5, 7), (8, 9)] + + >>> activity_selection([(1, 2), (2, 4), (3, 5), (0, 6)]) + [(1, 2), (2, 4)] + + >>> activity_selection([(5, 9), (1, 2), (3, 4), (0, 6)]) + [(1, 2), (3, 4), (5, 9)] + """ + + # Step 1: Sort the activities by their end time + sorted_activities = sorted(activities, key=lambda x: x[1]) + + # Step 2: Select the first activity (the one that finishes the earliest) + # as the initial activity + selected_activities = [sorted_activities[0]] + + # Step 3: Iterate through the sorted activities and select the ones + # that do not overlap with the last selected activity + for i in range(1, len(sorted_activities)): + if sorted_activities[i][0] >= selected_activities[-1][1]: + selected_activities.append(sorted_activities[i]) + + return selected_activities From c81787e69595fc8727e56af62d4a614230692b17 Mon Sep 17 00:00:00 2001 From: Hardvan Date: Wed, 2 Oct 2024 07:11:19 +0000 Subject: [PATCH 2/7] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 955001e2aa23..3aae7c9475df 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -518,6 +518,7 @@ * [Test Min Spanning Tree Prim](graphs/tests/test_min_spanning_tree_prim.py) ## Greedy Methods + * [Activity Selection](greedy_methods/activity_selection.py) * [Best Time To Buy And Sell Stock](greedy_methods/best_time_to_buy_and_sell_stock.py) * [Fractional Cover Problem](greedy_methods/fractional_cover_problem.py) * [Fractional Knapsack](greedy_methods/fractional_knapsack.py) From 57fbc0332e14de1a5ee7814159fb433c9ec5007a Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Wed, 2 Oct 2024 12:42:24 +0530 Subject: [PATCH 3/7] Rename x to activity --- greedy_methods/activity_selection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/greedy_methods/activity_selection.py b/greedy_methods/activity_selection.py index ab5405ddb497..6cdeff3d031e 100644 --- a/greedy_methods/activity_selection.py +++ b/greedy_methods/activity_selection.py @@ -37,7 +37,7 @@ def activity_selection(activities: list[tuple[int, int]]) -> list[tuple[int, int """ # Step 1: Sort the activities by their end time - sorted_activities = sorted(activities, key=lambda x: x[1]) + sorted_activities = sorted(activities, key=lambda activity: activity[1]) # Step 2: Select the first activity (the one that finishes the earliest) # as the initial activity From eec8dca8ad7bc19d2aaa2cc94257c31951a2ab85 Mon Sep 17 00:00:00 2001 From: Hardvan Date: Sun, 12 Oct 2025 05:57:12 +0000 Subject: [PATCH 4/7] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index b31d4d6e8b77..5beafd2dc392 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -195,6 +195,7 @@ * [Permutations](data_structures/arrays/permutations.py) * [Prefix Sum](data_structures/arrays/prefix_sum.py) * [Product Sum](data_structures/arrays/product_sum.py) + * [Rotate Array](data_structures/arrays/rotate_array.py) * [Sparse Table](data_structures/arrays/sparse_table.py) * [Sudoku Solver](data_structures/arrays/sudoku_solver.py) * Binary Tree From d1e943c3864aca14869ce11fcf9bb6b3bd78e7ad Mon Sep 17 00:00:00 2001 From: cclauss Date: Tue, 22 Sep 2026 05:50:58 +0000 Subject: [PATCH 5/7] updating DIRECTORY.md --- DIRECTORY.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index f7af664e2c00..37ebf6952aae 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -670,9 +670,8 @@ * [Test Min Spanning Tree Prim](graphs/tests/test_min_spanning_tree_prim.py) * [Travelling Salesman Problem](graphs/travelling_salesman_problem.py) -## Greedy Methods - * [Activity Selection](greedy_methods/activity_selection.py) ## [Greedy Methods](greedy_methods) + * [Activity Selection](greedy_methods/activity_selection.py) * [Best Time To Buy And Sell Stock](greedy_methods/best_time_to_buy_and_sell_stock.py) * [Fractional Cover Problem](greedy_methods/fractional_cover_problem.py) * [Fractional Knapsack](greedy_methods/fractional_knapsack.py) From c0c95421d804e6bd992be636aa56aa3bac7e38db Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Wed, 23 Sep 2026 07:51:13 +0200 Subject: [PATCH 6/7] Refactor activity_selection function documentation Updated docstring and added a check for empty input. --- greedy_methods/activity_selection.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/greedy_methods/activity_selection.py b/greedy_methods/activity_selection.py index 6cdeff3d031e..b91938d49031 100644 --- a/greedy_methods/activity_selection.py +++ b/greedy_methods/activity_selection.py @@ -1,7 +1,7 @@ """ The Activity Selection Problem is a classic problem in which a set of activities, -each with a start and end time, needs to be scheduled in such a way that -the maximum number of non-overlapping activities is selected. +each with a start and end time, needs to be scheduled in such a way that the +maximum number of non-overlapping activities is selected. This is a greedy algorithm where at each step, we choose the activity that finishes the earliest and does not conflict with previously selected activities. @@ -34,7 +34,12 @@ def activity_selection(activities: list[tuple[int, int]]) -> list[tuple[int, int >>> activity_selection([(5, 9), (1, 2), (3, 4), (0, 6)]) [(1, 2), (3, 4), (5, 9)] + + >>> all(activity_selection == [] for x in ([], {}, None, False, 0, 0.0)) + True """ + if not activities: + return [] # Step 1: Sort the activities by their end time sorted_activities = sorted(activities, key=lambda activity: activity[1]) From 446e098d4f23b259d15bba00cee3c9bc1ee2df01 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Wed, 23 Sep 2026 07:56:51 +0200 Subject: [PATCH 7/7] Fix activity_selection function test cases --- greedy_methods/activity_selection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/greedy_methods/activity_selection.py b/greedy_methods/activity_selection.py index b91938d49031..0535eba99f74 100644 --- a/greedy_methods/activity_selection.py +++ b/greedy_methods/activity_selection.py @@ -35,7 +35,7 @@ def activity_selection(activities: list[tuple[int, int]]) -> list[tuple[int, int >>> activity_selection([(5, 9), (1, 2), (3, 4), (0, 6)]) [(1, 2), (3, 4), (5, 9)] - >>> all(activity_selection == [] for x in ([], {}, None, False, 0, 0.0)) + >>> all(activity_selection(x) == [] for x in ([], {}, None, False, 0, 0.0)) True """ if not activities: