Added all DAA in python
This commit is contained in:
@@ -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))
|
||||||
@@ -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)
|
||||||
@@ -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)
|
||||||
@@ -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)
|
||||||
@@ -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.")
|
||||||
Reference in New Issue
Block a user