├── 01_knapsack_greedy.py ├── Activiry_selection.py ├── Binary_search.py ├── Bubble_sort.py ├── Counting_sort.py ├── Fractional_knapsack.py ├── Insertion_sort.py ├── Karatsuba_Algorithm.py ├── Knapsack_Dynamic.py ├── LCS.py ├── Linear_search.py ├── Matrix_Chain_Multiplication_DP.py ├── Merge_Sort.py ├── Power_function2.py ├── Power_function_1.py ├── Quick_Sort.py ├── README.md ├── Selection_sort copy.py ├── bfs.py ├── jobScheduling.py ├── knapsack_greedy.py ├── min_max.py └── weighted_job_scheduling.py /01_knapsack_greedy.py: -------------------------------------------------------------------------------- 1 | def knapsack_greedy(weights, values, capacity): 2 | ratios = [v / w for v, w in zip(values, weights)] 3 | sorted_items = sorted(zip(ratios, weights, values), reverse=True) 4 | total_value = 0 5 | selected_items = [] 6 | 7 | for ratio, weight, value in sorted_items: 8 | if capacity >= weight: 9 | selected_items.append((weight, value)) 10 | total_value += value 11 | capacity -= weight 12 | 13 | return total_value, selected_items 14 | 15 | weights = [10, 20, 30] 16 | values = [60, 100, 120] 17 | capacity = 50 18 | max_value, selected_items = knapsack_greedy(weights, values, capacity) 19 | 20 | print("Maximum value:", max_value) 21 | print("Selected items:", selected_items) 22 | 23 | -------------------------------------------------------------------------------- /Activiry_selection.py: -------------------------------------------------------------------------------- 1 | def activity_selection(activities): 2 | activities.sort(key=lambda x: x[0]) 3 | 4 | selected_activities = [] 5 | selected_activity = activities[0] 6 | 7 | for activity in activities[1:]: 8 | if activity[0] >= selected_activity[1]: 9 | selected_activities.append(selected_activity) 10 | selected_activity = activity 11 | 12 | selected_activities.append(selected_activity) 13 | 14 | return selected_activities 15 | 16 | activities = [(1, 3), (2, 5),(1, 6), (3, 6), (5, 8), (7, 10)] 17 | selected = activity_selection(activities) 18 | print("Selected Activities :", selected) 19 | 20 | -------------------------------------------------------------------------------- /Binary_search.py: -------------------------------------------------------------------------------- 1 | # Binary Search 2 | # Assume : Already Sorted Arrray 3 | # Time Complexity = [log(n)] => Master's Theorem 1T(n/2)+1 4 | # Space Complexity = 1 5 | # In-Place Searching 6 | 7 | def binary_search(arr, key, left, right): 8 | # Check if the left pointer is still less than or equal to the right pointer 9 | if left <= right: 10 | mid = (left + right) // 2 # Calculate the middle index using integer division 11 | 12 | if arr[mid] == key: 13 | return mid # Key found at the middle index 14 | elif arr[mid] > key: 15 | # If the middle element is greater than the key, search in the left half 16 | return binary_search(arr, key, left, mid - 1) 17 | else: 18 | # If the middle element is smaller than the key, search in the right half 19 | return binary_search(arr, key, mid + 1, right) 20 | else: 21 | return -1 # Key not found in the array 22 | 23 | arr = [56, 67, 89, 105, 199, 199] 24 | key = 67 25 | 26 | result = binary_search(arr, key, 0, len(arr) - 1) 27 | if result == -1: 28 | print("Key Not Found!!!") 29 | else: 30 | print("Key is Found at Index:", result) 31 | -------------------------------------------------------------------------------- /Bubble_sort.py: -------------------------------------------------------------------------------- 1 | def bubbleSort(array): 2 | 3 | # loop to access each array element 4 | for i in range(len(array)): 5 | 6 | # loop to compare array elements 7 | for j in range(0, len(array) - i - 1): 8 | 9 | # compare two adjacent elements 10 | # change > to < to sort in descending order 11 | if array[j] > array[j + 1]: 12 | 13 | # swapping elements if elements 14 | # are not in the intended order 15 | temp = array[j] 16 | array[j] = array[j+1] 17 | array[j+1] = temp 18 | 19 | 20 | data = [-9, 10, -2, 56, 67] 21 | 22 | bubbleSort(data) 23 | 24 | print('Sorted Array in Ascending Order:') 25 | print(data) 26 | 27 | # # https://poe.com/chat/2jom8az8uwykigklym9 -------------------------------------------------------------------------------- /Counting_sort.py: -------------------------------------------------------------------------------- 1 | def counting_sort(arr): 2 | # Find the range of input elements 3 | max_element = max(arr) 4 | min_element = min(arr) 5 | range_of_elements = max_element - min_element + 1 6 | 7 | # Initialize count array and sorted array 8 | count_array = [0] * range_of_elements 9 | sorted_array = [0] * len(arr) 10 | 11 | # Count the occurrences of each element 12 | for num in arr: 13 | count_array[num - min_element] += 1 14 | 15 | # Modify the count array to store cumulative counts 16 | for i in range(1, len(count_array)): 17 | count_array[i] += count_array[i - 1] 18 | 19 | # Create the sorted array 20 | for num in reversed(arr): 21 | sorted_array[count_array[num - min_element] - 1] = num 22 | count_array[num - min_element] -= 1 23 | 24 | return sorted_array 25 | 26 | # Example usage 27 | input_array = [4,56,67,99,89] 28 | sorted_array = counting_sort(input_array) 29 | print(sorted_array) 30 | -------------------------------------------------------------------------------- /Fractional_knapsack.py: -------------------------------------------------------------------------------- 1 | def fractional_knapsack(pr, wt, W, n): 2 | # Sort the items in decreasing order of value per weight. 3 | items = sorted(zip(pr, wt), key=lambda x: x[0] / x[1], reverse=True) 4 | 5 | # Initialize the total value and the total weight. 6 | total_value = 0 7 | total_weight = 0 8 | 9 | # Add items to the knapsack in order of value per weight, until the knapsack is 10 | # full or there are no more items to add. 11 | for item in items: 12 | if total_weight + item[1] <= W: 13 | total_value += item[0] 14 | total_weight += item[1] 15 | else: 16 | # Add a fraction of the last item to the knapsack until the knapsack is 17 | # full. 18 | fraction = (W - total_weight) / item[1] 19 | total_value += fraction * item[0] 20 | total_weight += fraction * item[1] 21 | break 22 | 23 | return total_value 24 | 25 | pr = [7,6,67,56,98,1] 26 | wt = [2,3,4,2,9,5] 27 | W = 10 28 | n = len(pr) 29 | print(fractional_knapsack(pr, wt, W, n)) 30 | 31 | -------------------------------------------------------------------------------- /Insertion_sort.py: -------------------------------------------------------------------------------- 1 | def insertion(arr): 2 | for i in range(1,len(arr)): 3 | key = arr[i] 4 | j = i-1 5 | while(key0): 6 | arr[j-1] = arr[j] 7 | j=j-1 8 | arr[j+1] = key 9 | 10 | Arr = [56,67,44,55,84,11,1] 11 | insertion(Arr) 12 | print(Arr) 13 | 14 | # Bubble sort -------------------------------------------------------------------------------- /Karatsuba_Algorithm.py: -------------------------------------------------------------------------------- 1 | def karatsuba(x, y): 2 | # Base case: If the numbers are small, use standard multiplication 3 | if x < 10 or y < 10: 4 | return x * y 5 | 6 | # Calculate the number of digits in the numbers 7 | n = max(len(str(x)), len(str(y))) 8 | n2 = n // 2 9 | 10 | # Split the input numbers into two halves 11 | a = x // 10**n2 12 | b = x % 10**n2 13 | c = y // 10**n2 14 | d = y % 10**n2 15 | 16 | # Recursively compute the three products required by Karatsuba 17 | ac = karatsuba(a, c) 18 | bd = karatsuba(b, d) 19 | ad_bc = karatsuba(a + b, c + d) - ac - bd 20 | 21 | # Combine the results to get the final product 22 | result = ac * 10**(2 * n2) + (ad_bc * 10**n2) + bd 23 | return result 24 | 25 | x = 12345678901234567890 26 | y = 98765432109876543210 27 | result = karatsuba(x, y) 28 | print(result) 29 | 30 | -------------------------------------------------------------------------------- /Knapsack_Dynamic.py: -------------------------------------------------------------------------------- 1 | def knapsack(pr,wt,W,n): 2 | if(n==0 or W==0): 3 | return 0 4 | else: 5 | if(wt[n-1]>W): 6 | return knapsack(pr,wt,W,n-1) 7 | else: 8 | return (max(knapsack(pr,wt,W,n-1),pr[n-1]+knapsack(pr,wt,W-wt[n-1],n-1))) 9 | 10 | pr=[5,7,8,10,3,6] 11 | wt=[3,2,5,3,1,4] 12 | W=10 13 | n=len(pr) 14 | print(knapsack(pr,wt,W,n)) 15 | 16 | 17 | -------------------------------------------------------------------------------- /LCS.py: -------------------------------------------------------------------------------- 1 | def lcs(s1, s2): 2 | m = len(s1) 3 | n = len(s2) 4 | dp = [[0 for i in range(n + 1)] for i in range(m + 1)] 5 | 6 | for i in range(1, m + 1): 7 | for j in range(1, n + 1): 8 | if s1[i - 1] == s2[j - 1]: 9 | dp[i][j] = 1 + dp[i - 1][j - 1] 10 | else: 11 | dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) 12 | 13 | print("The Longest Common Subsequence is:", dp[m][n]) 14 | return dp 15 | 16 | s1 = "LONGEST" 17 | s2 = "STONE" 18 | dp = lcs(s1, s2) 19 | 20 | for i in range(len(s1) + 1): 21 | for j in range(len(s2) + 1): 22 | print(dp[i][j], end=" ") 23 | print() 24 | 25 | 26 | -------------------------------------------------------------------------------- /Linear_search.py: -------------------------------------------------------------------------------- 1 | def linearSearch(array, n, x): 2 | 3 | # Going through array sequencially 4 | for i in range(0, n): 5 | if (array[i] == x): 6 | return i 7 | return -1 8 | 9 | array = [92, 4, 0, 56, 67] 10 | x = 56 11 | n = len(array) 12 | result = linearSearch(array, n, x) 13 | if(result == -1): 14 | print("Element not found") 15 | else: 16 | print("Element found at index :", result) -------------------------------------------------------------------------------- /Matrix_Chain_Multiplication_DP.py: -------------------------------------------------------------------------------- 1 | def matrixChain(arr, n): 2 | m = [[0 for i in range(n)] for i in range(n)] 3 | 4 | for d in range(2, n): 5 | for i in range(1, n - d + 1): 6 | j = i + d - 1 7 | m[i][j] = float('inf') 8 | 9 | for k in range(i, j): 10 | q = m[i][k] + m[k + 1][j] + (arr[i - 1] * arr[k] * arr[j]) 11 | if q < m[i][j]: 12 | m[i][j] = q 13 | 14 | return m[1][n - 1] 15 | 16 | arr = [5, 4, 6, 2, 7] 17 | n = len(arr) 18 | result = matrixChain(arr, n) 19 | print(result) 20 | 21 | -------------------------------------------------------------------------------- /Merge_Sort.py: -------------------------------------------------------------------------------- 1 | def merge_sort(arr): 2 | if len(arr) > 1: # Base Case: If the array has more than one element 3 | mid = len(arr) // 2 # Calculate the middle index 4 | left = arr[:mid] # Divide the array into two halves 5 | right = arr[mid:] 6 | 7 | merge_sort(left) # Recursively sort the left half 8 | merge_sort(right) # Recursively sort the right half 9 | 10 | # Merge the sorted halves 11 | i = j = k = 0 12 | while i < len(left) and j < len(right): 13 | if left[i] < right[j]: 14 | arr[k] = left[i] 15 | i += 1 16 | else: 17 | arr[k] = right[j] 18 | j += 1 19 | k += 1 20 | 21 | # Handle remaining elements in the left and right halves 22 | while i < len(left): 23 | arr[k] = left[i] 24 | i += 1 25 | k += 1 26 | while j < len(right): 27 | arr[k] = right[j] 28 | j += 1 29 | k += 1 30 | 31 | 32 | arr = [67,56,99,10,105,56,67] 33 | merge_sort(arr) 34 | print(arr) 35 | -------------------------------------------------------------------------------- /Power_function2.py: -------------------------------------------------------------------------------- 1 | #python code to demonstrate the above approach 2 | def power(x, y): 3 | if y==0: 4 | return 1 5 | 6 | temp = power(x, y // 2) 7 | # if y is even 8 | if y % 2 == 0: 9 | return temp * temp 10 | else: 11 | return x * temp * temp 12 | x = 3 13 | y = 5 14 | print("Power is : ", power(x,y)) -------------------------------------------------------------------------------- /Power_function_1.py: -------------------------------------------------------------------------------- 1 | base = 5 2 | exponent = 3 3 | result = base 4 | if exponent != 0: 5 | for i in range(exponent - 1): 6 | result = result * base 7 | else: 8 | result == 1 9 | print("Exponential value is : ", result) # 125 10 | -------------------------------------------------------------------------------- /Quick_Sort.py: -------------------------------------------------------------------------------- 1 | def quicksort(array): 2 | if len(array) <= 1: 3 | return array 4 | pivot = array[0] 5 | smaller = [] 6 | larger = [] 7 | for i in range(1, len(array)): 8 | if array[i] < pivot: 9 | smaller.append(array[i]) 10 | else: 11 | larger.append(array[i]) 12 | return quicksort(smaller) + [pivot] + quicksort(larger) 13 | 14 | array = [93, 71, 56, 67, 94] 15 | print(quicksort(array)) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Algorithms 2 | -------------------------------------------------------------------------------- /Selection_sort copy.py: -------------------------------------------------------------------------------- 1 | Arr = [5,56,67,88,22,3,4] 2 | for i in range(len(Arr)): # position index 3 | min_idx = i 4 | for j in range(i+1,len(Arr)): # finding the min value 5 | if(Arr[min_idx]>Arr[j]): 6 | min_idx = j # swapping 7 | Arr[min_idx],Arr[i] = Arr[i],Arr[min_idx] 8 | print(Arr) -------------------------------------------------------------------------------- /bfs.py: -------------------------------------------------------------------------------- 1 | import collections 2 | def BFS(graph, root): 3 | visited = set() 4 | queue = collections.deque([root]) 5 | visited.add(root) 6 | 7 | while queue: 8 | vertex = queue.popleft() 9 | print(vertex, end=' ') 10 | 11 | for vert in graph[vertex]: 12 | if vert not in visited: 13 | visited.add(vert) 14 | queue.append(vert) 15 | graph = { 16 | 0: [1, 3, 4], 17 | 1: [0, 2], 18 | 2: [1, 3, 5], 19 | 3: [0, 2, 4, 5], 20 | 4: [0, 3, 6], 21 | 5: [2, 3, 6], 22 | 6: [4, 5] 23 | } 24 | root = 0 25 | BFS(graph, root) 26 | 27 | 28 | -------------------------------------------------------------------------------- /jobScheduling.py: -------------------------------------------------------------------------------- 1 | def jobScheduling(jobs, d, n): 2 | job_seq = ['-1'] * d 3 | index = list(range(n)) 4 | index.sort(key=lambda i: jobs[i][2], reverse=True) 5 | 6 | for i in index: 7 | for j in range(jobs[i][1] - 1, -1, -1): 8 | if job_seq[j] == '-1': 9 | job_seq[j] = jobs[i][0] 10 | break 11 | 12 | print(job_seq) 13 | 14 | jobs = [['a', 2, 15], ['b', 1, 13], ['c', 2, 17], ['d', 2, 18], ['e', 3, 12], ['f', 3, 14]] 15 | n = len(jobs) 16 | deadline = [jobs[i][1] for i in range(n)] 17 | d = max(deadline) 18 | 19 | jobScheduling(jobs, d, n) 20 | 21 | -------------------------------------------------------------------------------- /knapsack_greedy.py: -------------------------------------------------------------------------------- 1 | def knapsack_greedy(values, weights, capacity): 2 | n = len(values) 3 | value_per_weight = [(values[i] / weights[i], values[i], weights[i], i) for i in range(n)] 4 | value_per_weight.sort(reverse=True) 5 | 6 | total_value = 0 7 | knapsack = [0] * n 8 | 9 | for i in range(n): 10 | value, weight, index = value_per_weight[i] 11 | if weight <= capacity: 12 | knapsack[index] = 1 13 | total_value += value 14 | capacity -= weight 15 | else: 16 | knapsack[index] = capacity / weight 17 | total_value += capacity / weight * value 18 | break 19 | 20 | return total_value, knapsack 21 | 22 | values = [60, 100, 120] 23 | weights = [10, 20, 30] 24 | capacity = 50 25 | max_value, selected_items = knapsack_greedy(values, weights, capacity) 26 | print("Maximum value:", max_value) 27 | print("Selected items:", selected_items) 28 | -------------------------------------------------------------------------------- /min_max.py: -------------------------------------------------------------------------------- 1 | def minmaxproblem(arr, l, r): 2 | if l == r: 3 | return (arr[l], arr[l]) # Base case: single element, return as min and max 4 | 5 | elif r == l + 1: 6 | if arr[l] < arr[r]: 7 | return (arr[l], arr[r]) # Compare two elements and return as min and max 8 | else: 9 | return (arr[r], arr[l]) 10 | 11 | else: 12 | mid = (l + r) // 2 # Corrected the calculation of mid using integer division 13 | 14 | # Divide the array into two parts and find min/max for each part 15 | arr_min1, arr_max1 = minmaxproblem(arr, l, mid) # for the left part 16 | arr_min2, arr_max2 = minmaxproblem(arr, mid + 1, r) # for the right part 17 | 18 | # Return the overall min and max of both parts 19 | return (min(arr_min1, arr_min2), max(arr_max1, arr_max2)) 20 | 21 | arr = [1, 23, -5, 67, 56] 22 | result_min, result_max = minmaxproblem(arr, 0, len(arr) - 1) 23 | print("Minimum:", result_min) 24 | print("Maximum:", result_max) 25 | -------------------------------------------------------------------------------- /weighted_job_scheduling.py: -------------------------------------------------------------------------------- 1 | def weighted_job_scheduling(jobs, processing_time_limit): 2 | 3 | # Sort the jobs in decreasing order of weight. 4 | jobs.sort(key=lambda job: job[0], reverse=True) 5 | 6 | # Initialize the total weight and the current time. 7 | total_weight = 0 8 | current_time = 0 9 | 10 | for job in jobs: 11 | if current_time + job[1] <= processing_time_limit: 12 | total_weight += job[0] 13 | current_time += job[1] 14 | return total_weight 15 | 16 | jobs = [(10, 2), (5, 1), (3, 3)] 17 | processing_time_limit = 5 18 | max_total_weight = weighted_job_scheduling(jobs, processing_time_limit) 19 | print(max_total_weight) 20 | 21 | 22 | --------------------------------------------------------------------------------