About
Introducing Sanjay: A Skilled and Passionate Coder
Sanjay is a highly talented and dedicated individual with a passion for coding and a drive to create innovative solutions. With a strong background in programming and a natural aptitude for problem-solving, Sanjay brings a unique set of skills to the table.
From an early age, Sanjay demonstrated a keen interest in technology and its limitless possibilities. This fascination evolved into a deep passion for coding, leading Sanjay to delve into various programming languages and frameworks. With a solid foundation in programming concepts and a commitment to continuous learning, Sanjay has honed their skills to an impressive level.
One of Sanjay's notable strengths is their ability to approach complex problems with a systematic and analytical mindset. They excel at breaking down intricate tasks into manageable components and devising efficient algorithms to solve them. Sanjay's keen eye for detail allows them to spot potential bugs or optimizations, ensuring the delivery of high-quality code.
Beyond technical expertise, Sanjay is a collaborative team player who thrives in a dynamic and fast-paced environment. They are adept at communicating complex ideas effectively, making them an invaluable asset for team projects. Sanjay brings a proactive and positive attitude, always eager to learn from others and contribute their own unique insights.
Throughout their coding journey, Sanjay has worked on a diverse range of projects, showcasing their adaptability and versatility. Whether it's developing robust web applications, creating intuitive user interfaces, or implementing efficient algorithms, Sanjay consistently demonstrates a commitment to excellence and a passion for innovation.
With an insatiable curiosity and a drive for continuous improvement, Sanjay remains up-to-date with the latest trends and advancements in the coding world. They actively seek new challenges to expand their skill set and embrace opportunities to explore emerging technologies.
In summary, Sanjay is a talented and passionate coder who possesses the technical expertise, problem-solving prowess, and collaborative spirit to thrive in any coding environment. Their commitment to delivering outstanding results and their constant drive to learn and grow make them an exceptional asset to any coding team or project.
counting sort
def counting_sort(arr): max_element = max(arr) count = [0] * (max_element+1) for i in (arr): count[i]=count[i]+1 for i in range(1,max_element+1): count[i]=count[i]+count[i-1]
print(count)
sorted_array=[0]*len(arr) for i in range(len(arr)-1,-1,-1): count[arr[i]]=count[arr[i]]-1 ele=count[arr[i]] sorted_array[ele]=arr[i] print(sorted_array) arr=[1,4,1,2,7,5,2] print(arr) counting_sort(arr)
radix sort
def Radixsort(arr): m = max(arr) digit = 1 while (m // digit > 0): buckets = [] for i in range(10): buckets.append([])
print(buckets)
for i in range(len(arr)): index = arr[i]//digit buckets[index % 10].append(arr[i]) digit = digit * 10 arr=[] for container in buckets: for elements in container: arr.append(elements) print(arr) arr = [170, 45, 75, 90, 802, 24, 2, 66] Radixsort(arr)
merge sort
Python program for implementation of MergeSort
import time begin=time.time() def mergeSort(arr): if len(arr) > 1: print(" -- ",arr)
Finding the mid of the array
mid = len(arr) // 2
Dividing the array elements
L = arr[:mid]
into 2 halves
R = arr[mid:]
Sorting the first half
mergeSort(L)
Sorting the second half
mergeSort(R) print(L," ",R) print("array is :",arr) i = j = k = 0
Copy data to temp arrays L[] and R[]
while i < len(L) and j < len(R): if L[i] <= R[j]: arr[k] = L[i] i += 1 else: arr[k] = R[j] j += 1 k += 1
print(i," ",j," "," ",k,)
Checking if any element was left
while i < len(L): arr[k] = L[i] i += 1 k += 1 while j < len(R): arr[k] = R[j] j += 1 k += 1 print(" :", arr) arr = [1,7,3,2] print("Given array is", end="\n") print(arr) mergeSort(arr) print("Sorted array is: ", end="\n") print(arr) end=time.time() print(end-begin)
quick sort
import time begin=time.time() def partition(array,low,high): pivot=array[high] i=low - 1 for j in range(low,high): if(array[j]<= pivot): i=i+1 array[i],array[j]=array[j],array[i] array[i+1],array[high]=array[high],array[i+1] SORTING 7 return i+1
def partition(arr,low,high):
pivot=arr[high]
i=low
for j in range(low,high):
if(arr[j]<=pivot):
arr[i],arr[j]=arr[j],arr[i]
i=i+1
arr[i],arr[high]=arr[high],arr[i]
return i
def quick_sort(array,low,high): if(low < high): pi=partition(array,low,high) quick_sort(array,low,pi-1) quick_sort(array,pi+1,high) array=[1, 7, 4, 10, 9, -2] print(array) quick_sort(array,0,len(array)-1) print(array) end=time.time() print(end-begin)
bubble sort
bubble sort
import time begin=time.time() a=[2,3,1,6,4,5] print(a) print("The sorted list is") for i in range(0,len(a)): for j in range(0,i): if(a[j]>a[j+1]): a[j],a[j+1]=a[j+1],a[j] print(a) end=time.time() print(end-begin)
insertion sort
insertion sort
import time begin=time.time() a=[2,3,1,6,4,5] print(a) print("The sorted list is") for i in range(1,len(a)): t=a[i] j=i-1 while j>=0 and t<a[j]: a[j+1]=a[j] j-=1 a[j+1]=t print(a) end=time.time() print(end-begin)
selection sort
selection sort
A=[2,3,1,6,4,5] print(A) for i in range(0,len(A)): min=i for j in range(i+1,len(A)): if(A[min]>A[j]): min=j A[i],A[min]=A[min],A[i] print(A)
Kruskal + Prim's
import heapq
class Graph: def _init_(self): self.adList = {} self.edges = [] self.weights = {}
def add_vertex(self, vertex):
self.adList[vertex] = []
def add_edge(self, vertex1, vertex2, weight):
self.adList[vertex1].append(vertex2)
self.adList[vertex2].append(vertex1)
self.weights[vertex1, vertex2] = weight
self.weights[vertex2, vertex1] = weight
self.edges.append((weight, vertex1, vertex2))
def find(self, parent, vertex):
if parent[vertex] != vertex:
parent[vertex] = self.find(parent, parent[vertex])
return parent[vertex]
def union(self, rank, parent, vertex1, vertex2):
root1 = self.find(parent, vertex1)
root2 = self.find(parent, vertex2)
if rank[root1] > rank[root2]:
parent[root2] = root1
elif rank[root2] > rank[root1]:
parent[root1] = root2
else:
parent[root2] = root1
rank[root1] += 1
def kruskal(self):
mst = []
parent = {_: _ for _ in self.adList}
rank = {_: 0 for _ in self.adList}
priority_queue = []
for _ in self.edges:
heapq.heappush(priority_queue, _)
while priority_queue:
weight, vertex1, vertex2 = heapq.heappop(priority_queue)
if self.find(parent, vertex1) != self.find(parent, vertex2):
mst.append((vertex1, vertex2, weight))
self.union(rank, parent, vertex1, vertex2)
return mst
def prims(self, source):
visited = []
priority_queue = [(0, source, None)]
mst = []
while priority_queue:
weight, popVertex, parentVertex = heapq.heappop(priority_queue)
if popVertex not in visited:
visited.append(popVertex)
if parentVertex is not None:
mst.append((parentVertex, popVertex, weight))
for adjacent_v in self.adList[popVertex]:
if adjacent_v not in visited:
heapq.heappush(priority_queue, (self.weights[popVertex, adjacent_v], adjacent_v, popVertex))
return mst
graph = Graph() graph.add_vertex('A') graph.add_vertex('B') graph.add_vertex('C') graph.add_vertex('D') graph.add_vertex('E') graph.add_vertex('F')
graph.add_edge('A', 'B', 7) graph.add_edge('A', 'C', 8) graph.add_edge('C', 'D', 4) graph.add_edge('C', 'B', 3) graph.add_edge('C', 'E', 3) graph.add_edge('B', 'D', 6) graph.add_edge('D', 'E', 2) graph.add_edge('D', 'F', 5) graph.add_edge('E', 'F', 2)
print(graph.prims('A'))
print(graph.kruskal())
DFS + BFS + Topological Sort + Dijkstra's
import heapq class Graph: def _init_(self): self.adList = {} self.weights = {}
def add_vertex(self, vertex):
self.adList[vertex] = []
def add_edge(self, vertex1, vertex2, weight):
self.adList[vertex1].append(vertex2)
self.weights[(vertex1, vertex2)] = weight
def bfs(self, source):
visited = [source]
queue = [source]
while queue:
popVertex = queue.pop(0)
print(popVertex)
for adjacent_v in self.adList[popVertex]:
if adjacent_v not in visited:
queue.append(adjacent_v)
visited.append(adjacent_v)
def dfs(self, source):
visited = [source]
stack = [source]
while stack:
popVertex = stack.pop()
print(popVertex)
for adjacent_v in self.adList[popVertex]:
if adjacent_v not in visited:
stack.append(adjacent_v)
visited.append(adjacent_v)
def djikstras(self, source):
distance = {v: float('inf') for v in self.adList}
distance[source] = 0
priority_queue = [(0, source)]
while priority_queue:
weight, popVertex = heapq.heappop(priority_queue)
for adjacent_v in self.adList[popVertex]:
new_dist = weight + self.weights[popVertex, adjacent_v]
if new_dist < distance[adjacent_v]:
distance[adjacent_v] = new_dist
heapq.heappush(priority_queue, (new_dist, adjacent_v))
return distance
def topologicalsort(self):
in_degree = {v: 0 for v in self.adList}
for vertex in self.adList:
for adjacent_v in self.adList[vertex]:
in_degree[adjacent_v] += 1
queue = []
topological_sort_array = []
for vertex in in_degree:
if in_degree[vertex] == 0:
queue.append(vertex)
while queue:
popVertex = queue.pop(0)
topological_sort_array.append(popVertex)
for adjacent_v in self.adList[popVertex]:
in_degree[adjacent_v] -= 1
if in_degree[adjacent_v] == 0:
queue.append(adjacent_v)
return topological_sort_array
graph=Graph() graph.add_vertex('A') graph.add_vertex('B') graph.add_vertex('C') graph.add_vertex('D') graph.add_vertex('E')
graph.add_edge('A', 'B', 4) graph.add_edge('A', 'C', 1) graph.add_edge('C', 'D', 4) graph.add_edge('C', 'B', 2) graph.add_edge('B', 'E', 4) graph.add_edge('D', 'E', 4)
print(graph.adList) print()
graph.bfs('A')
print()
graph.dfs('A')
print(graph.topologicalsort())
print(graph.djikstras('A'))
Bellman-Ford
class Graph: def _init_(self, vertices): self.V = vertices self.graph = []
def add_edge(self, u, v, w):
self.graph.append([u, v, w])
def bellman_ford(self, src):
# Initialize distances from the source vertex to all other vertices as infinity
distance = [float("inf")] * self.V
distance[src] = 0
# Relax all edges |V| - 1 times, where |V| is the number of vertices
for _ in range(self.V - 1):
print(_)
for u, v, w in self.graph:
if distance[u] != float("inf") and distance[u] + w < distance[v]:
distance[v] = distance[u] + w
# Check for negative-weight cycles
for u, v, w in self.graph:
if distance[u] != float("inf") and distance[u] + w < distance[v]:
print("Graph contains negative-weight cycle")
return
# Print the shortest distances
self.print_solution(distance)
def print_solution(self, distance):
print("Vertex \tDistance from Source")
for i in range(self.V):
print(f"{i}\t{distance[i]}")
Example usage:
g = Graph(5) g.add_edge(0, 1, -1) g.add_edge(0, 2, 4) g.add_edge(1, 2, 3) g.add_edge(1, 3, 2) g.add_edge(1, 4, 2) g.add_edge(3, 2, 5) g.add_edge(3, 1, 1) g.add_edge(4, 3, -3)
g.bellman_ford(0)
Activity Selection
def sort_key(a): return a[1] # sorting by finish time
def activity_selector(activities): select = [] activities.sort(key=sort_key) print(activities)
k = 0
select.append(activities[k])
for i in range(1, len(activities)):
if activities[i][0] >= activities[k][1]: # if start_time[i] >= finish_time[k]
select.append(activities[i])
k = i
return select
if _name_ == '_main_': list_acts = [(5, 9), (1, 2), (3, 4), (0, 6), (5, 7), (8, 9)] print("The selected activities are: ", activity_selector(list_acts)) print() print("The selected activities are: ", activity_selector_mod(list_acts))
Knapsack
def sort_keys(x): return x[1] / x[0]
def knapsack(bag_cap, valuables): valuables.sort(reverse=True, key=sort_keys) print(valuables) selected = [] profit = 0 current_cap = 0 for i in valuables: if current_cap+i[0] <= bag_cap: current_cap += i[0] selected.append(str(i[0])) profit += i[1] else: remaining = bag_cap - current_cap current_cap += remaining selected.append(str(remaining) + "/" + str(i[0])) profit += (remaining / i[0]) * i[1]
print("Profit: ", profit)
return selected
if _name_ == '_main_': items = [(2, 20), (3, 25), (4, 40), (5, 50)] W = 10 print(knapsack(W, items))
Job Sequencing
Given an array of jobs where every job has a deadline and associated profit if the job is finished before the
deadline. It is also given that every job takes a single unit of time, so the minimum possible deadline for any job
is 1. Maximize the total profit if only one job can be scheduled at a time.
def job_sequence(jobs):
# let's start by sorting the tasks by deadline (desc)
jobs.sort(reverse=True, key=lambda x: x[2])
# print(jobs)
max_slots = max(task[1] for task in jobs)
busy = [False] * max_slots
total_profit = 0
for job in jobs:
deadline, profit = job[1], job[2]
for i in range(deadline - 1, -1, -1):
if not busy[i]:
busy[i] = job[0]
total_profit += profit
break
return total_profit, busy
if _name_ == '_main_':
# tasks are stored in the format:
# [0] -> task_no
# [1] -> deadline
# [2] -> profit
tasks = [[1, 7, 15],
[2, 2, 20],
[3, 5, 30],
[4, 3, 18],
[5, 4, 18],
[6, 5, 10],
[7, 2, 23],
[8, 7, 16],
[9, 3, 25]]
print("Profit: ", job_sequence(tasks)[0])
print("Schedule: ", job_sequence(tasks)[1])
Huffman code
class Huffman: def _init_(self, char, count): self.symbol = char self.freq = count self.left = None self.right = None
def huffman_tree_gen(data): count_dict = {} for i in list(data): count_dict[i] = list(data).count(i) print(count_dict)
node_list = [Huffman(symbol, freq) for symbol, freq in count_dict.items()]
while len(node_list) > 1:
# using > 1 because at last iteration we just need one element in the list which will
# be the root of the tree
node_list.sort(key=lambda x: x.freq)
left = node_list.pop(0) # first pop goes to the left
right = node_list.pop(0) # second pop goes to the right
new_merge = Huffman(char=None, count=left.freq + right.freq)
new_merge.left, new_merge.right = left, right
node_list.append(new_merge)
return node_list[0] # 0th index contains the root node to the Huffman tree
def huffman_code_gen(start, code, huffman_code): if start is None: return
if start.symbol:
huffman_code[start.symbol] = code
huffman_code_gen(start.left, code + "0", huffman_code) # moving left adds "0" to the string representing the code
huffman_code_gen(start.right, code + "1", huffman_code) # moving right adds "0" to the string representing the code
def huffman_encoding(data): if len(data) is None: return None, None
root = huffman_tree_gen(data) # nested fn - 1 : builds the Huffman tree and returns the root
huffman_code = {}
huffman_code_gen(root, "", huffman_code)
return huffman_code, root
if _name_ == '_main_':
# input case from lecture
data = "bbbbbeeeeeeeeeeccccccccccccaaaaaaaaaaaaaaaadddddddddddddddddffffffffffffffffffffffffff"
# data = "huffman code"
encoded, tree = huffman_encoding(data)
print(encoded)