From 4b11369278717cfa0b3483d9cb341ee28c9cdde8 Mon Sep 17 00:00:00 2001 From: bhakti-thakur Date: Wed, 5 Nov 2025 18:07:57 +0530 Subject: [PATCH] Added all DAA in python --- DAA/A1.py | 33 +++++++++++++++++++ DAA/A2.py | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ DAA/A3.py | 38 ++++++++++++++++++++++ DAA/A4.py | 31 ++++++++++++++++++ DAA/A5.py | 80 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 278 insertions(+) create mode 100644 DAA/A1.py create mode 100644 DAA/A2.py create mode 100644 DAA/A3.py create mode 100644 DAA/A4.py create mode 100644 DAA/A5.py diff --git a/DAA/A1.py b/DAA/A1.py new file mode 100644 index 0000000..2c034c2 --- /dev/null +++ b/DAA/A1.py @@ -0,0 +1,33 @@ +# Problem Statement: Write a program non-recursive and recursive program to calculate Fibonacci numbers and analyze their time and space complexity. + +# Non-recursion +def fibonacci(n): + fib_series = [] + a = 0 + b = 1 + + for i in range(n): + fib_series.append(a) + a, b = b, a + b + + return fib_series + +# Recursion +def fibonacci_recursive(n): + if n <= 0: + return [] + elif n == 1: + return [0] + elif n == 2: + return [0, 1] + else: + fib_series = fibonacci_recursive(n - 1) # Get the series up to n-1 + fib_series.append(fib_series[-1] + fib_series[-2]) # Append the next Fibonacci number + return fib_series + +# Non-recursion +n = int(input("Enter total numbers to print in fibonacci series:\t")) +print("Fibonacci Series (non-recusive):\t", fibonacci(n)) + +# Recursion +print("Fibonacci Series (recusive):\t\t", fibonacci_recursive(n)) diff --git a/DAA/A2.py b/DAA/A2.py new file mode 100644 index 0000000..cb58a1f --- /dev/null +++ b/DAA/A2.py @@ -0,0 +1,96 @@ +import heapq +from collections import Counter, namedtuple + +# Node used in heap: (frequency, unique_id, node) +# unique_id breaks ties deterministically +class Node: + def __init__(self, freq, symbol=None, left=None, right=None): + self.freq = freq + self.symbol = symbol + self.left = left + self.right = right + + def is_leaf(self): + return self.symbol is not None + +def build_huffman_tree(freqs): + """Build Huffman tree and return root node.""" + heap = [] + uid = 0 + for sym, f in freqs.items(): + node = Node(f, symbol=sym) + heapq.heappush(heap, (f, uid, node)) + uid += 1 + + # Edge case: single unique symbol -> create a dummy sibling + if len(heap) == 1: + f, _, node = heapq.heappop(heap) + dummy = Node(0, symbol=None) # zero-frequency sibling + new = Node(f + dummy.freq, left=dummy, right=node) + return new + + while len(heap) > 1: + f1, _, n1 = heapq.heappop(heap) + f2, _, n2 = heapq.heappop(heap) + merged = Node(f1 + f2, left=n1, right=n2) + heapq.heappush(heap, (merged.freq, uid, merged)) + uid += 1 + + return heapq.heappop(heap)[2] + +def generate_codes(root): + """Return dict: symbol -> code (string of '0'/'1').""" + codes = {} + def dfs(node, prefix): + if node is None: + return + if node.is_leaf(): + # If tree had single symbol, ensure code length >= 1 + codes[node.symbol] = prefix or "0" + return + dfs(node.left, prefix + "0") + dfs(node.right, prefix + "1") + dfs(root, "") + return codes + +def huffman_encode(s): + """Encode string s. Returns (encoded_bitstring, codes).""" + if not s: + return "", {} + freqs = Counter(s) + root = build_huffman_tree(freqs) + codes = generate_codes(root) + encoded = "".join(codes[ch] for ch in s) + return encoded, codes, root + +def huffman_decode(encoded_bits, root): + """Decode bitstring using Huffman tree root.""" + if not encoded_bits: + # If tree has single symbol and encoded_bits empty, return repeated symbol? + # But typically empty input -> empty output. + return "" + res_chars = [] + node = root + i = 0 + while i < len(encoded_bits): + bit = encoded_bits[i] + node = node.left if bit == "0" else node.right + if node.is_leaf(): + res_chars.append(node.symbol) + node = root + i += 1 + return "".join(res_chars) + +# Example / test +if __name__ == "__main__": + sample = "this is an example for huffman encoding" + encoded, codes, root = huffman_encode(sample) + decoded = huffman_decode(encoded, root) + + print("Original:", sample) + print("Codes:") + for k in sorted(codes, key=lambda x: (len(codes[x]), x)): + print(f" {repr(k)} : {codes[k]}") + print("Encoded bit length:", len(encoded)) + print("Encoded (first 200 bits):", encoded[:200]) + print("Decoded matches original?", decoded == sample) diff --git a/DAA/A3.py b/DAA/A3.py new file mode 100644 index 0000000..eb3b8ca --- /dev/null +++ b/DAA/A3.py @@ -0,0 +1,38 @@ +# Fractional Knapsack using Greedy Method + +class Item: + def __init__(self, value, weight): + self.value = value + self.weight = weight + +def fractional_knapsack(items, capacity): + # Step 1: Sort items by value/weight ratio (descending) + items.sort(key=lambda x: x.value / x.weight, reverse=True) + + total_value = 0.0 # total value in knapsack + remaining_capacity = capacity + + # Step 2: Pick items greedily + for item in items: + if remaining_capacity >= item.weight: + # take full item + total_value += item.value + remaining_capacity -= item.weight + else: + # take fractional part + fraction = remaining_capacity / item.weight + total_value += item.value * fraction + break # knapsack is full + + return total_value + +# Example usage +if __name__ == "__main__": + values = [60, 100, 120] + weights = [10, 20, 30] + capacity = 50 + + items = [Item(v, w) for v, w in zip(values, weights)] + max_value = fractional_knapsack(items, capacity) + + print("Maximum value in Knapsack =", max_value) diff --git a/DAA/A4.py b/DAA/A4.py new file mode 100644 index 0000000..5824507 --- /dev/null +++ b/DAA/A4.py @@ -0,0 +1,31 @@ +# 0/1 Knapsack Problem using Dynamic Programming + +def knapsack_01(values, weights, capacity): + n = len(values) + # Create DP table: (n+1) x (capacity+1) + dp = [[0 for _ in range(capacity + 1)] for _ in range(n + 1)] + + # Build table bottom-up + for i in range(1, n + 1): + for w in range(1, capacity + 1): + if weights[i - 1] <= w: + # Option 1: include the item + include = values[i - 1] + dp[i - 1][w - weights[i - 1]] + # Option 2: exclude the item + exclude = dp[i - 1][w] + dp[i][w] = max(include, exclude) + else: + dp[i][w] = dp[i - 1][w] + + # The last cell contains the maximum value + return dp[n][capacity] + + +# Example usage +if __name__ == "__main__": + values = [60, 100, 120] + weights = [10, 20, 30] + capacity = 50 + + max_value = knapsack_01(values, weights, capacity) + print("Maximum value in Knapsack =", max_value) diff --git a/DAA/A5.py b/DAA/A5.py new file mode 100644 index 0000000..b3aa462 --- /dev/null +++ b/DAA/A5.py @@ -0,0 +1,80 @@ +def solve_n_queens_with_first(n, first_pos, find_all=False): + """ + Solve n-Queens given a pre-placed queen at first_pos (r, c), 0-indexed. + Returns: + - if find_all=False: one solution as a list of rows where board[r][c] = 1 + - if find_all=True: list of all such solutions + If no solution: returns None (or empty list when find_all=True). + """ + r0, c0 = first_pos + # validate first position + if not (0 <= r0 < n and 0 <= c0 < n): + raise ValueError("first_pos must be within board bounds (0..n-1).") + + # Prepare trackers + cols = set([c0]) + diag1 = set([r0 - c0]) # r - c + diag2 = set([r0 + c0]) # r + c + board = [-1] * n # board[r] = c or -1 + board[r0] = c0 + + solutions = [] + + def place(row): + # If row already has the placed queen, skip to next row + if row == n: + # a solution found; build matrix representation + mat = [[0]*n for _ in range(n)] + for rr in range(n): + c = board[rr] + if c != -1: + mat[rr][c] = 1 + if find_all: + solutions.append(mat) + return False # continue searching + else: + solutions.append(mat) + return True # stop search (found one) + if board[row] != -1: + # fixed queen row, just advance + return place(row+1) + + for c in range(n): + if c in cols or (row - c) in diag1 or (row + c) in diag2: + continue + # choose + board[row] = c + cols.add(c); diag1.add(row - c); diag2.add(row + c) + stop = place(row + 1) + # unchoose + cols.remove(c); diag1.remove(row - c); diag2.remove(row + c) + board[row] = -1 + if stop and not find_all: + return True + return False + + # Start from row 0 + place(0) + + if find_all: + return solutions # possibly empty list + else: + return solutions[0] if solutions else None + + +# ---------- Example usage ---------- +if __name__ == "__main__": + # Example 1: n=8, first queen at row0,col0 (top-left) + n = 8 + first = (0, 0) # 0-indexed + sol = solve_n_queens_with_first(n, first, find_all=False) + if sol is None: + print("No solution found.") + else: + print("One solution matrix (1 = queen):") + for row in sol: + print(row) + + # Example 2: get all solutions with first queen at (0, 3) + # all_sols = solve_n_queens_with_first(8, (0, 3), find_all=True) + # print(f"Found {len(all_sols)} solutions.")