From 95cea5c566b74ef84f66eb67283279e9ed66f344 Mon Sep 17 00:00:00 2001 From: Om Gedam Date: Wed, 29 Oct 2025 14:32:45 +0530 Subject: [PATCH 1/2] Add combinationfile.py with algorithm implementations This file implements various algorithms including sorting, searching, graph algorithms, dynamic programming, and mathematical algorithms. --- dynamic_programming/combinationfile.py | 431 +++++++++++++++++++++++++ 1 file changed, 431 insertions(+) create mode 100644 dynamic_programming/combinationfile.py diff --git a/dynamic_programming/combinationfile.py b/dynamic_programming/combinationfile.py new file mode 100644 index 000000000000..98ff2f8a1664 --- /dev/null +++ b/dynamic_programming/combinationfile.py @@ -0,0 +1,431 @@ +""" +The Algorithms - Python +A comprehensive collection of algorithm implementations +""" + +# ============================================================================ +# SORTING ALGORITHMS +# ============================================================================ + +def bubble_sort(arr): + """Bubble Sort - O(n^2)""" + n = len(arr) + for i in range(n): + swapped = False + for j in range(0, n - i - 1): + if arr[j] > arr[j + 1]: + arr[j], arr[j + 1] = arr[j + 1], arr[j] + swapped = True + if not swapped: + break + return arr + + +def quick_sort(arr): + """Quick Sort - O(n log n) average""" + if len(arr) <= 1: + return arr + pivot = arr[len(arr) // 2] + left = [x for x in arr if x < pivot] + middle = [x for x in arr if x == pivot] + right = [x for x in arr if x > pivot] + return quick_sort(left) + middle + quick_sort(right) + + +def merge_sort(arr): + """Merge Sort - O(n log n)""" + if len(arr) <= 1: + return arr + + mid = len(arr) // 2 + left = merge_sort(arr[:mid]) + right = merge_sort(arr[mid:]) + + return merge(left, right) + + +def merge(left, right): + """Helper function for merge sort""" + result = [] + i = j = 0 + + while i < len(left) and j < len(right): + if left[i] <= right[j]: + result.append(left[i]) + i += 1 + else: + result.append(right[j]) + j += 1 + + result.extend(left[i:]) + result.extend(right[j:]) + return result + + +def insertion_sort(arr): + """Insertion Sort - O(n^2)""" + for i in range(1, len(arr)): + key = arr[i] + j = i - 1 + while j >= 0 and arr[j] > key: + arr[j + 1] = arr[j] + j -= 1 + arr[j + 1] = key + return arr + + +# ============================================================================ +# SEARCHING ALGORITHMS +# ============================================================================ + +def binary_search(arr, target): + """Binary Search - O(log n) - requires sorted array""" + left, right = 0, len(arr) - 1 + + while left <= right: + mid = (left + right) // 2 + if arr[mid] == target: + return mid + elif arr[mid] < target: + left = mid + 1 + else: + right = mid - 1 + + return -1 + + +def linear_search(arr, target): + """Linear Search - O(n)""" + for i, val in enumerate(arr): + if val == target: + return i + return -1 + + +def jump_search(arr, target): + """Jump Search - O(√n) - requires sorted array""" + import math + n = len(arr) + step = int(math.sqrt(n)) + prev = 0 + + while arr[min(step, n) - 1] < target: + prev = step + step += int(math.sqrt(n)) + if prev >= n: + return -1 + + while arr[prev] < target: + prev += 1 + if prev == min(step, n): + return -1 + + if arr[prev] == target: + return prev + + return -1 + + +# ============================================================================ +# GRAPH ALGORITHMS +# ============================================================================ + +def bfs(graph, start): + """Breadth-First Search""" + visited = set() + queue = [start] + result = [] + + while queue: + vertex = queue.pop(0) + if vertex not in visited: + visited.add(vertex) + result.append(vertex) + queue.extend([n for n in graph[vertex] if n not in visited]) + + return result + + +def dfs(graph, start, visited=None): + """Depth-First Search""" + if visited is None: + visited = set() + + visited.add(start) + result = [start] + + for neighbor in graph[start]: + if neighbor not in visited: + result.extend(dfs(graph, neighbor, visited)) + + return result + + +def dijkstra(graph, start): + """Dijkstra's Shortest Path Algorithm""" + import heapq + + distances = {node: float('inf') for node in graph} + distances[start] = 0 + pq = [(0, start)] + visited = set() + + while pq: + curr_dist, curr_node = heapq.heappop(pq) + + if curr_node in visited: + continue + + visited.add(curr_node) + + for neighbor, weight in graph[curr_node].items(): + distance = curr_dist + weight + + if distance < distances[neighbor]: + distances[neighbor] = distance + heapq.heappush(pq, (distance, neighbor)) + + return distances + + +# ============================================================================ +# DYNAMIC PROGRAMMING +# ============================================================================ + +def fibonacci(n, memo={}): + """Fibonacci with Memoization - O(n)""" + if n in memo: + return memo[n] + if n <= 2: + return 1 + + memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo) + return memo[n] + + +def knapsack(weights, values, capacity): + """0/1 Knapsack Problem""" + n = len(weights) + dp = [[0] * (capacity + 1) for _ in range(n + 1)] + + for i in range(1, n + 1): + for w in range(1, capacity + 1): + if weights[i - 1] <= w: + dp[i][w] = max( + values[i - 1] + dp[i - 1][w - weights[i - 1]], + dp[i - 1][w] + ) + else: + dp[i][w] = dp[i - 1][w] + + return dp[n][capacity] + + +def longest_common_subsequence(s1, s2): + """Longest Common Subsequence""" + m, n = len(s1), len(s2) + dp = [[0] * (n + 1) for _ in range(m + 1)] + + for i in range(1, m + 1): + for j in range(1, n + 1): + if s1[i - 1] == s2[j - 1]: + dp[i][j] = dp[i - 1][j - 1] + 1 + else: + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + + return dp[m][n] + + +# ============================================================================ +# STRING ALGORITHMS +# ============================================================================ + +def kmp_search(text, pattern): + """Knuth-Morris-Pratt String Matching""" + def compute_lps(pattern): + lps = [0] * len(pattern) + length = 0 + i = 1 + + while i < len(pattern): + if pattern[i] == pattern[length]: + length += 1 + lps[i] = length + i += 1 + else: + if length != 0: + length = lps[length - 1] + else: + lps[i] = 0 + i += 1 + return lps + + lps = compute_lps(pattern) + i = j = 0 + indices = [] + + while i < len(text): + if pattern[j] == text[i]: + i += 1 + j += 1 + + if j == len(pattern): + indices.append(i - j) + j = lps[j - 1] + elif i < len(text) and pattern[j] != text[i]: + if j != 0: + j = lps[j - 1] + else: + i += 1 + + return indices + + +def is_palindrome(s): + """Check if string is palindrome""" + return s == s[::-1] + + +# ============================================================================ +# MATHEMATICAL ALGORITHMS +# ============================================================================ + +def gcd(a, b): + """Greatest Common Divisor - Euclidean Algorithm""" + while b: + a, b = b, a % b + return a + + +def lcm(a, b): + """Least Common Multiple""" + return abs(a * b) // gcd(a, b) + + +def is_prime(n): + """Check if number is prime""" + if n < 2: + return False + if n == 2: + return True + if n % 2 == 0: + return False + + for i in range(3, int(n**0.5) + 1, 2): + if n % i == 0: + return False + return True + + +def sieve_of_eratosthenes(limit): + """Generate all primes up to limit""" + primes = [True] * (limit + 1) + primes[0] = primes[1] = False + + for i in range(2, int(limit**0.5) + 1): + if primes[i]: + for j in range(i * i, limit + 1, i): + primes[j] = False + + return [i for i in range(limit + 1) if primes[i]] + + +def power(base, exp): + """Fast Exponentiation - O(log n)""" + if exp == 0: + return 1 + if exp == 1: + return base + + if exp % 2 == 0: + half = power(base, exp // 2) + return half * half + else: + return base * power(base, exp - 1) + + +# ============================================================================ +# DATA STRUCTURE IMPLEMENTATIONS +# ============================================================================ + +class Stack: + """Stack Implementation""" + def __init__(self): + self.items = [] + + def push(self, item): + self.items.append(item) + + def pop(self): + return self.items.pop() if self.items else None + + def peek(self): + return self.items[-1] if self.items else None + + def is_empty(self): + return len(self.items) == 0 + + +class Queue: + """Queue Implementation""" + def __init__(self): + self.items = [] + + def enqueue(self, item): + self.items.append(item) + + def dequeue(self): + return self.items.pop(0) if self.items else None + + def is_empty(self): + return len(self.items) == 0 + + +# ============================================================================ +# DEMONSTRATION +# ============================================================================ + +if __name__ == "__main__": + print("=" * 60) + print("THE ALGORITHMS - PYTHON IMPLEMENTATION") + print("=" * 60) + + # Sorting + print("\n--- SORTING ALGORITHMS ---") + arr = [64, 34, 25, 12, 22, 11, 90] + print(f"Original: {arr}") + print(f"Quick Sort: {quick_sort(arr.copy())}") + print(f"Merge Sort: {merge_sort(arr.copy())}") + + # Searching + print("\n--- SEARCHING ALGORITHMS ---") + sorted_arr = [1, 3, 5, 7, 9, 11, 13, 15] + target = 7 + print(f"Array: {sorted_arr}, Target: {target}") + print(f"Binary Search: Index {binary_search(sorted_arr, target)}") + + # Graph Algorithms + print("\n--- GRAPH ALGORITHMS ---") + graph = { + 'A': ['B', 'C'], + 'B': ['A', 'D', 'E'], + 'C': ['A', 'F'], + 'D': ['B'], + 'E': ['B', 'F'], + 'F': ['C', 'E'] + } + print(f"BFS from 'A': {bfs(graph, 'A')}") + print(f"DFS from 'A': {dfs(graph, 'A')}") + + # Dynamic Programming + print("\n--- DYNAMIC PROGRAMMING ---") + print(f"Fibonacci(10): {fibonacci(10)}") + print(f"LCS('ABCDGH', 'AEDFHR'): {longest_common_subsequence('ABCDGH', 'AEDFHR')}") + + # Mathematical + print("\n--- MATHEMATICAL ALGORITHMS ---") + print(f"GCD(48, 18): {gcd(48, 18)}") + print(f"Is 17 prime? {is_prime(17)}") + print(f"Primes up to 30: {sieve_of_eratosthenes(30)}") + + print("\n" + "=" * 60) From 26ccca0979e2f9feabc8ae7d5f32f2b1ce0874dd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 29 Oct 2025 09:32:36 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- dynamic_programming/combinationfile.py | 126 +++++++++++++------------ 1 file changed, 68 insertions(+), 58 deletions(-) diff --git a/dynamic_programming/combinationfile.py b/dynamic_programming/combinationfile.py index 98ff2f8a1664..a7c2e2803db5 100644 --- a/dynamic_programming/combinationfile.py +++ b/dynamic_programming/combinationfile.py @@ -7,6 +7,7 @@ # SORTING ALGORITHMS # ============================================================================ + def bubble_sort(arr): """Bubble Sort - O(n^2)""" n = len(arr) @@ -36,11 +37,11 @@ def merge_sort(arr): """Merge Sort - O(n log n)""" if len(arr) <= 1: return arr - + mid = len(arr) // 2 left = merge_sort(arr[:mid]) right = merge_sort(arr[mid:]) - + return merge(left, right) @@ -48,7 +49,7 @@ def merge(left, right): """Helper function for merge sort""" result = [] i = j = 0 - + while i < len(left) and j < len(right): if left[i] <= right[j]: result.append(left[i]) @@ -56,7 +57,7 @@ def merge(left, right): else: result.append(right[j]) j += 1 - + result.extend(left[i:]) result.extend(right[j:]) return result @@ -78,10 +79,11 @@ def insertion_sort(arr): # SEARCHING ALGORITHMS # ============================================================================ + def binary_search(arr, target): """Binary Search - O(log n) - requires sorted array""" left, right = 0, len(arr) - 1 - + while left <= right: mid = (left + right) // 2 if arr[mid] == target: @@ -90,7 +92,7 @@ def binary_search(arr, target): left = mid + 1 else: right = mid - 1 - + return -1 @@ -105,24 +107,25 @@ def linear_search(arr, target): def jump_search(arr, target): """Jump Search - O(√n) - requires sorted array""" import math + n = len(arr) step = int(math.sqrt(n)) prev = 0 - + while arr[min(step, n) - 1] < target: prev = step step += int(math.sqrt(n)) if prev >= n: return -1 - + while arr[prev] < target: prev += 1 if prev == min(step, n): return -1 - + if arr[prev] == target: return prev - + return -1 @@ -130,19 +133,20 @@ def jump_search(arr, target): # GRAPH ALGORITHMS # ============================================================================ + def bfs(graph, start): """Breadth-First Search""" visited = set() queue = [start] result = [] - + while queue: vertex = queue.pop(0) if vertex not in visited: visited.add(vertex) result.append(vertex) queue.extend([n for n in graph[vertex] if n not in visited]) - + return result @@ -150,41 +154,41 @@ def dfs(graph, start, visited=None): """Depth-First Search""" if visited is None: visited = set() - + visited.add(start) result = [start] - + for neighbor in graph[start]: if neighbor not in visited: result.extend(dfs(graph, neighbor, visited)) - + return result def dijkstra(graph, start): """Dijkstra's Shortest Path Algorithm""" import heapq - - distances = {node: float('inf') for node in graph} + + distances = {node: float("inf") for node in graph} distances[start] = 0 pq = [(0, start)] visited = set() - + while pq: curr_dist, curr_node = heapq.heappop(pq) - + if curr_node in visited: continue - + visited.add(curr_node) - + for neighbor, weight in graph[curr_node].items(): distance = curr_dist + weight - + if distance < distances[neighbor]: distances[neighbor] = distance heapq.heappush(pq, (distance, neighbor)) - + return distances @@ -192,13 +196,14 @@ def dijkstra(graph, start): # DYNAMIC PROGRAMMING # ============================================================================ + def fibonacci(n, memo={}): """Fibonacci with Memoization - O(n)""" if n in memo: return memo[n] if n <= 2: return 1 - + memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo) return memo[n] @@ -207,17 +212,16 @@ def knapsack(weights, values, capacity): """0/1 Knapsack Problem""" n = len(weights) dp = [[0] * (capacity + 1) for _ in range(n + 1)] - + for i in range(1, n + 1): for w in range(1, capacity + 1): if weights[i - 1] <= w: dp[i][w] = max( - values[i - 1] + dp[i - 1][w - weights[i - 1]], - dp[i - 1][w] + values[i - 1] + dp[i - 1][w - weights[i - 1]], dp[i - 1][w] ) else: dp[i][w] = dp[i - 1][w] - + return dp[n][capacity] @@ -225,14 +229,14 @@ def longest_common_subsequence(s1, s2): """Longest Common Subsequence""" m, n = len(s1), len(s2) dp = [[0] * (n + 1) for _ in range(m + 1)] - + for i in range(1, m + 1): for j in range(1, n + 1): if s1[i - 1] == s2[j - 1]: dp[i][j] = dp[i - 1][j - 1] + 1 else: dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) - + return dp[m][n] @@ -240,13 +244,15 @@ def longest_common_subsequence(s1, s2): # STRING ALGORITHMS # ============================================================================ + def kmp_search(text, pattern): """Knuth-Morris-Pratt String Matching""" + def compute_lps(pattern): lps = [0] * len(pattern) length = 0 i = 1 - + while i < len(pattern): if pattern[i] == pattern[length]: length += 1 @@ -259,16 +265,16 @@ def compute_lps(pattern): lps[i] = 0 i += 1 return lps - + lps = compute_lps(pattern) i = j = 0 indices = [] - + while i < len(text): if pattern[j] == text[i]: i += 1 j += 1 - + if j == len(pattern): indices.append(i - j) j = lps[j - 1] @@ -277,7 +283,7 @@ def compute_lps(pattern): j = lps[j - 1] else: i += 1 - + return indices @@ -290,6 +296,7 @@ def is_palindrome(s): # MATHEMATICAL ALGORITHMS # ============================================================================ + def gcd(a, b): """Greatest Common Divisor - Euclidean Algorithm""" while b: @@ -310,7 +317,7 @@ def is_prime(n): return True if n % 2 == 0: return False - + for i in range(3, int(n**0.5) + 1, 2): if n % i == 0: return False @@ -321,12 +328,12 @@ def sieve_of_eratosthenes(limit): """Generate all primes up to limit""" primes = [True] * (limit + 1) primes[0] = primes[1] = False - + for i in range(2, int(limit**0.5) + 1): if primes[i]: for j in range(i * i, limit + 1, i): primes[j] = False - + return [i for i in range(limit + 1) if primes[i]] @@ -336,7 +343,7 @@ def power(base, exp): return 1 if exp == 1: return base - + if exp % 2 == 0: half = power(base, exp // 2) return half * half @@ -348,35 +355,38 @@ def power(base, exp): # DATA STRUCTURE IMPLEMENTATIONS # ============================================================================ + class Stack: """Stack Implementation""" + def __init__(self): self.items = [] - + def push(self, item): self.items.append(item) - + def pop(self): return self.items.pop() if self.items else None - + def peek(self): return self.items[-1] if self.items else None - + def is_empty(self): return len(self.items) == 0 class Queue: """Queue Implementation""" + def __init__(self): self.items = [] - + def enqueue(self, item): self.items.append(item) - + def dequeue(self): return self.items.pop(0) if self.items else None - + def is_empty(self): return len(self.items) == 0 @@ -389,43 +399,43 @@ def is_empty(self): print("=" * 60) print("THE ALGORITHMS - PYTHON IMPLEMENTATION") print("=" * 60) - + # Sorting print("\n--- SORTING ALGORITHMS ---") arr = [64, 34, 25, 12, 22, 11, 90] print(f"Original: {arr}") print(f"Quick Sort: {quick_sort(arr.copy())}") print(f"Merge Sort: {merge_sort(arr.copy())}") - + # Searching print("\n--- SEARCHING ALGORITHMS ---") sorted_arr = [1, 3, 5, 7, 9, 11, 13, 15] target = 7 print(f"Array: {sorted_arr}, Target: {target}") print(f"Binary Search: Index {binary_search(sorted_arr, target)}") - + # Graph Algorithms print("\n--- GRAPH ALGORITHMS ---") graph = { - 'A': ['B', 'C'], - 'B': ['A', 'D', 'E'], - 'C': ['A', 'F'], - 'D': ['B'], - 'E': ['B', 'F'], - 'F': ['C', 'E'] + "A": ["B", "C"], + "B": ["A", "D", "E"], + "C": ["A", "F"], + "D": ["B"], + "E": ["B", "F"], + "F": ["C", "E"], } print(f"BFS from 'A': {bfs(graph, 'A')}") print(f"DFS from 'A': {dfs(graph, 'A')}") - + # Dynamic Programming print("\n--- DYNAMIC PROGRAMMING ---") print(f"Fibonacci(10): {fibonacci(10)}") print(f"LCS('ABCDGH', 'AEDFHR'): {longest_common_subsequence('ABCDGH', 'AEDFHR')}") - + # Mathematical print("\n--- MATHEMATICAL ALGORITHMS ---") print(f"GCD(48, 18): {gcd(48, 18)}") print(f"Is 17 prime? {is_prime(17)}") print(f"Primes up to 30: {sieve_of_eratosthenes(30)}") - + print("\n" + "=" * 60)