ACSD06
ACSD06
I. COURSE OVERVIEW:
The course is designed with the fundamental programming skills and problem-solving strategies necessary to
tackle a wide range of computational challenges. Through hands-on programming exercises and projects,
students will learn how to write code, analyze problems and develop solutions using various programming
languages and tools. The course will cover fundamental programming concepts and gradually progress to more
advanced topics.
Note: Students are encouraged to bring their own laptops for laboratory
practice sessions.
Hints:
def twoSum(self, nums: List[int], target: int) -> List[int]:
a=[]
# Write code here
…
return a
Hints:
def containsDuplicate(self, nums):
a = set() # set can have only distinct elements
# Write code here
…
return False
For example, 2 is written as II in Roman numeral, just two ones added together. 12 is written as XII, which
is simply X + II. The number 27 is written as XXVII, which is XX + V + II.
Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is
not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making
four. The same principle applies to the number nine, which is written as IX. There are six instances where
subtraction is used:
I can be placed before V (5) and X (10) to make 4 and 9.
X can be placed before L (50) and C (100) to make 40 and 90.
C can be placed before D (500) and M (1000) to make 400 and 900.
Input: s = "III"
Output: 3
Input: s = "LVIII"
Output: 58
Hints:
def romanToInt(self, s: str) -> int:
# Write code here
…
return number
return digits
Hints:
def majorityElement(self, nums):
# write code here
…
Hints:
def maximumWealth(self, accounts: List[List[int]]) -> int:
# write code here
…
Hints:
def fizzBuzz(self, n: int) -> List[str]:
# write code here
…
Hints:
def numberOfSteps(self, n: int) -> int:
# write code here
…
Hints:
def runningSum(self, nums: List[int]) -> List[int]:
# write code here
…
return answer
Hints:
def removeElement(self, nums: List[int], val: int) -> int:
# write code here
…
return len(nums)
2. Matrix Operations
2.1 Add Two Matrices
Given two matrices X and Y, the task is to compute the sum of two matrices and then print it in Python.
Input:
X= [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
Y = [[9, 8, 7],
[6, 5, 4],
[3, 2, 1]]
Output:
Result = [[10, 10, 10],
[10, 10, 10],
[10, 10, 10]]
Hints:
# Program to add two matrices using nested loop
X = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
Y = [[9,8,7],
[6,5,4],
[3,2,1]]
result = [[0,0,0],
[0,0,0],
[0,0,0]]
for r in result:
print(r)
TRY
1. Take input as X = [[10, 20, 30],[41, 52, 63], [47, 58, 69]] Y = [[19,18,17],[66,35,49], [13,21,11]] and verify
the results.
Y = [[1, 1, 1, 2],
[6, 7, 3, 0],
[4, 5, 9, 1]]
Output:
Result = [[55, 65, 49, 5],
[57, 68, 72, 12],
[90, 107, 111, 21]]
Hints:
# Program to multiply two matrices using list comprehension
TRY
1. Take input as X = [[11, 0, 30],[-41, -2, 63], [41, -5, -9]] Y = [[19,-48,17],[-6,35,19], [13,1,-9]] and verify the
results.
TRY
1. Take input as X = [[11, 0, 30],[-41, -2, 63], [41, -5, -9]] and verify the results.
Input: The original list: [[1, 4, 5], [7, 3], [4], [46, 7, 3]]
Output: The total element product in lists is: 1622880
Hints:
# Matrix Product using list comprehension + loop
def prod(val):
# write code here
…
# initializing list
test_list = [[1, 4, 5], [7, 3], [4], [46, 7, 3]]
TRY
1. Take input list: [[1, 4, 5], [7, 3], [4], [46, 7, 3]] and verify the result.
3. Stack
3.1 Stack implementation using List
A stack is a linear data structure that stores items in a Last-In/First-Out (LIFO) or First-In/Last-Out (FILO)
manner. In stack, a new element is added at one end and an element is removed from that end only. The
insert and delete operations are often called push and pop.
TRY
Hints:
# Evaluate value of a postfix expression
# Function call
print("postfix evaluation: %d" % (obj.evaluatePostfix(exp)))
TRY
1. Take input str = “A B + C* D / E +” and verify the result.
2. Take input str = “XYZ- + W+ R / S -” and verify the result.
4. Queue
4.1 Linear Queue using List
Linear queue is a linear data structure that stores items in First in First out (FIFO) manner. With a queue
the least recently added item is removed first. A good example of queue is any queue of consumers for a
resource where the consumer that came first is served first.
Hints:
# Static implementation of linear queue
front=0
rear=0
mymax=5
def createQueue():
queue=[] #empty list
return queue
def isEmpty(queue):
# write code here
…
def enqueue(queue,item): # insert an element into the queue
# write code here
…
def dequeue(queue): #remove an element from the queue
# write code here
…
# Driver code
queue = createQueue()
while True:
print("1.Enqueue")
print("2.Dequeue")
print("3.Display")
print("4.Quit")
# write code here
…
TRY
Hints:
class MyStack:
def __init__(self):
# write code here
…
def push(self, x: int) -> None:
# write code here
…
def pop(self) -> int:
# write code here
…
def top(self) -> int:
# write code here
…
def empty(self) -> bool:
# write code here
…
# Your MyStack object will be instantiated and called as such:
# obj = MyStack()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.top()
# param_4 = obj.empty()
Hints:
class MyQueue:
def __init__(self):
# write code here
…
def push(self, x: int) -> None:
# write code here
…
def pop(self) -> int:
# write code here
…
def peek(self) -> int:
# write code here
…
def empty(self) -> bool:
# write code here
…
# Your MyQueue object will be instantiated and called as such:
# obj = MyQueue()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.peek()
# param_4 = obj.empty()
# constructor
def __init__(self, size): # initializing the class
self.size = size
def dequeue(self):
# Write code here
…
def display(self):
# Write code here
…
# Driver Code
ob = CircularQueue(5)
ob.enqueue(14)
ob.enqueue(22)
ob.enqueue(13)
ob.enqueue(-6)
ob.display()
print ("Deleted value = ", ob.dequeue())
print ("Deleted value = ", ob.dequeue())
ob.display()
ob.enqueue(9)
ob.enqueue(20)
ob.enqueue(5)
ob.display()
TRY
5. Graph Representation
5.1 Build a graph
You are given an integer n. Determine if there is an unconnected graph with n vertices that contains at
least two connected components and contains the number of edges that is equal to the number of
vertices. Each vertex must follow one of these conditions:
Its degree is less than or equal to 1.
It's a cut-vertex.
Note:
The graph must be simple.
Loops and multiple edges are not allowed.
Input: First line: n
Output: Print Yes if it is an unconnected graph. Otherwise, print No.
Sample Input Sample Output
3 No
Constraints: 1 ≤ n ≤ 100
Explanation: There is only one graph with the number of edges equal to the number of vertices (triangle)
which is connected.
Output: 3
The idea is to iterate through all the edges. And for each edge, mark the source node from which the
edge emerged out. Now, for each node check if it is marked or not. And count the unmarked nodes.
Algorithm:
1. Make any array A[] of size equal to the number of nodes and initialize to 1.
3. Now traverse whole array A[] and count number of unmarked nodes.
Hints:
# Program to count number if sink nodes
return count
# Driver Code
n = 4
m = 2
edgeFrom = [2, 4]
edgeTo = [3, 3]
Input: First line of input line contains two integers’ n and e. Next e line will contain two integers u and v
meaning that node u and node v are connected to each other in undirected fashion.
Output: For each input graph print an integer x denoting total number of connected components.
Explanation: We traverse the adjacency list and as we find a vertex v in the adjacency list of vertex u
which indicates an edge from u to v in main graph, we just add an edge from v to u in the transpose
graph i.e. add u in the adjacency list of vertex v of the new graph. Thus traversing lists of all vertices of
main graph we can get the transpose graph.
Hints:
# find transpose of a graph.
# function to add an edge from vertex source to vertex dest
def addEdge(adj, src, dest):
adj[src].append(dest)
# function to get Transpose of a graph taking adjacency list of given graph and that
of Transpose graph
def transposeGraph(adj, transpose, v):
# traverse the adjacency list of given graph and for each edge (u, v) add
# an edge (v, u) in the transpose graph's adjacency list
…
# Driver Code
v = 5
adj = [[] for i in range(v)]
addEdge(adj, 0, 1)
addEdge(adj, 0, 4)
addEdge(adj, 0, 3)
addEdge(adj, 2, 0)
addEdge(adj, 3, 2)
addEdge(adj, 4, 1)
addEdge(adj, 4, 3)
TRY
1. Take input operations as addEdge( A, B), addEdge( A, D), addEdge( A, C), addEdge( C, A),addEdge(A, D),
addEdge( C, B), addEdge( B, C) and verify the result.
Input:
5 5
First line: Two integers – N and M (3 ≤ N ≤ 10 , 1 ≤ M ≤ 3 * 10 )
th
(i+1) line: Two integers – ui and vi (1 ≤ ui, vi ≤ N) denoting that the edge (ui, vi) is white in color.
Note: The conditions (ui, vi) ≠ (uj, vj) and (ui, vi) ≠ (vj, uj) are satisfied for all 1 ≤ i < j ≤ M.
.Output: Print an integer that denotes the number of triples that satisfy the mentioned condition.
Explanation: The triplets are: {(1, 2, 3), (1, 2, 4), (2, 3, 4), (1, 3, 4)}
There are n nodes and m bridges in between these nodes. Print the possible path through each node
using each edges (if possible), traveling through each edges only once.
Hints:
# A Python program to print Eulerian trail in a
# given Eulerian or Semi-Eulerian Graph
from collections import defaultdict
class Graph:
# Constructor and destructor
def __init__(self, V):
self.V = V
self.adj = defaultdict(list)
# Driver code
# Let us first create and test graphs shown in above figure
g1 = Graph(4)
g1.addEdge(0, 1)
g1.addEdge(0, 2)
g1.addEdge(1, 2)
g1.addEdge(2, 3)
g1.printEulerTour()
g3 = Graph(4)
g3.addEdge(0, 1)
g3.addEdge(1, 0)
g3.addEdge(0, 2)
g3.addEdge(2, 0)
g3.addEdge(2, 3)
g3.addEdge(3, 1)
g3.printEulerTour()
TRY
1. Take input: [[1, 0, 1, 0, 1], [1, 0, 1, 0, 0], [1, 1, 0, 1, 0], [0, 0, 1, 0, 0], [1, 0, 1, 0, 0]] and verify the result.
2. Take input: [[0, 0, 1, 0, 1], [0, 0, 1, 0, 0], [1, 0, 0, 1, 0], [1, 0, 1, 0, 0], [1, 1, 1, 0, 0]] and verify the result.
th
Output: An array path [V] that should contain the Hamiltonian Path. Path [i] should represent the i
vertex in the Hamiltonian Path. The code should also return false if there is no Hamiltonian Cycle in the
graph.
| /\ |
| / \ |
| / \ |
(3)-------(4)
(0)--(1)--(2)
| /\ |
| / \ |
| / \ |
(3) (4)
Backtracking Algorithm: Create an empty path array and add vertex 0 to it. Add other vertices, starting
from the vertex 1. Before adding a vertex, check for whether it is adjacent to the previously added vertex
and not already added. If we find such a vertex, we add the vertex as part of the solution. If we do not find
a vertex then we return false.
Hints:
# Python program for solution of Hamiltonian cycle problem
class Graph():
def __init__(self, vertices):
self.graph = [[0 for column in range(vertices)]
for row in range(vertices)]
self.V = vertices
def hamCycle(self):
…
# Driver Code
TRY
1. Take a graph = [ [1, 1, 0, 1, 0], [1, 1, 1, 1, 1], [0, 1, 0, 1, 1,], [1, 1, 0, 1, 0], [0, 1, 1, 1, 0],] and verify the
results.
Complete Graph: A graph is said to be complete if each possible vertices is connected through an Edge.
Hamiltonian Cycle: It is a closed walk such that each vertex is visited at most once except the initial
vertex. and it is not necessary to visit all the edges.
Formula: (N – 1)! / 2
Input: N = 6
Output: Hamiltonian cycles = 60
Input: N = 4
Output: Hamiltonian cycles = 3
Explanation: Let us take the example of N = 4 complete undirected graph, The 3 different Hamiltonian
cycle is as shown below:
Hints:
# Number of Hamiltonian cycles
import math as mt
# Driver code
N = 5
Number = Cycles(N)
print("Hamiltonian cycles = ", Number)
TRY
1. Take an input N=7 and verify the results.
2. Take an input N=10 and verify the results.
Given a set of cities and the distance between every pair of cities, the problem is to find the shortest
possible route that visits every city exactly once and returns to the starting point. The problem statement
gives a list of cities along with the distances between each city.
Objective: To start from the origin city, visit other cities only once, and return to the original city again.
Our target is to find the shortest possible path to complete the round-trip route.
Here a graph is given where 1, 2, 3, and 4 represent the cities, and the weight associated with every edge
represents the distance between those cities. The goal is to find the shortest possible path for the tour
that starts from the origin city, traverses the graph while only visiting the other cities or nodes once, and
returns to the origin city.
For the above graph, the optimal route is to follow the minimum cost path: 1 – 2 – 4 – 3 - 1. And this
shortest route would cost 10 + 25 + 30 + 15 =80
Algorithm for Traveling Salesman Problem: We will use the dynamic programming approach to solve
the Travelling Salesman Problem (TSP).
Let’s assume S is the subset of cities and belongs to {1, 2, 3, …, n} where 1, 2, 3…n are the cities and i, j are
two cities in that subset. Now cost(i, S, j) is defined in such a way as the length of the shortest path visiting
node in S, which is exactly once having the starting and ending point as i and j respectively.
For example, cost (1, {2, 3, 4}, 1) denotes the length of the shortest path where:
Starting city is 1
Cities 2, 3, and 4 are visited only once
The ending point is 1
Now S = {1, 2, 3, 4}. There are four elements. Hence the number of subsets will be 2^4 or 16. Those
subsets are-
1) |S| = Null:
{Φ}
2) |S| = 1:
{{1}, {2}, {3}, {4}}
3) |S| = 2:
{{1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4}, {3, 4}}
4) |S| = 3:
{{1, 2, 3}, {1, 2, 4}, {2, 3, 4}, {1, 3, 4}}
5) |S| = 4:
{{1, 2, 3, 4}}
As we are starting at 1, we could discard the subsets containing city 1. The algorithm calculation steps:
1) |S| = Φ:
cost (2, Φ, 1) = dist(2, 1) = 10
cost (3, Φ, 1) = dist(3, 1) = 15
cost (4, Φ, 1) = dist(4, 1) = 20
2) |S| = 1:
cost (2, {3}, 1) = dist(2, 3) + cost (3, Φ, 1) = 35+15 = 50
cost (2, {4}, 1) = dist(2, 4) + cost (4, Φ, 1) = 25+20 = 45
cost (3, {2}, 1) = dist(3, 2) + cost (2, Φ, 1) = 35+10 = 45
cost (3, {4}, 1) = dist(3, 4) + cost (4, Φ, 1) = 30+20 = 50
cost (4, {2}, 1) = dist(4, 2) + cost (2, Φ, 1) = 25+10 = 35
cost (4, {3}, 1) = dist(4, 3) + cost (3, Φ, 1) = 30+15 = 45
3) |S| = 2:
cost (2, {3, 4}, 1) = min [ dist[2,3] + Cost(3,{4},1) = 35+50 = 85,
dist[2,4]+Cost(4,{3},1) = 25+45 = 70 ] = 70
cost (3, {2, 4}, 1) = min [ dist[3,2] + Cost(2,{4},1) = 35+45 = 80,
dist[3,4]+Cost(4,{2},1) = 30+35 = 65 ] = 65
cost (4, {2, 3}, 1) = min [ dist[4,2] + Cost(2,{3},1) = 25+50 = 75
dist[4,3] + Cost(3,{2},1) = 30+45 = 75 ] = 75
4) |S| = 3:
cost (1, {2, 3, 4}, 1) = min [ dist[1,2]+Cost(2,{3,4},1) = 10+70 = 80
dist[1,3]+Cost(3,{2,4},1) = 15+65 = 80
dist[1,4]+Cost(4,{2,3},1) = 20+75 = 95 ] = 80
Hints:
from sys import maxsize
from itertools, import permutations
V = 4
def tsp(graph, s):
…
# Driver code
graph = [[0, 10, 15, 20], [10, 0, 35, 25], [15, 35, 0, 30], [20, 25, 30, 0]]
s = 0
print(tsp(graph, s))
TRY
1. Take a below table values and verify the results.
dist(i, j) 1 2 3 4
1 0 40 25 40
2 20 0 35 25
3 25 35 0 60
4 40 25 30 0
Output: 0 4 12 19 21 11 9 8 14
Hints:
# Dijkstra's single source shortest path algorithm. The program is for adjacency
matrix representation of the graph
class Graph():
def __init__(self, vertices):
self.V = vertices
self.graph = [[0 for column in range(vertices)]
for row in range(vertices)]
g.dijkstra(0)
TRY
1. Take a below graph and verify the results.
Output: 4
Cycle 6 -> 1 -> 5 -> 0 -> 6
Hints:
from sys import maxsize as INT_MAX
from collections import deque
N = 100200
gr = [0] * N
for i in range(N):
gr[i] = []
# Driver Code
# Number of vertices
n = 7
# Add edges
add_edge(0, 6)
add_edge(0, 5)
add_edge(5, 1)
add_edge(1, 6)
add_edge(2, 6)
add_edge(2, 3)
add_edge(3, 4)
add_edge(4, 1)
# Function call
print(shortest_cycle(n))
TRY
1. Take a below graph and verify the results.
Input: M = 2, N = 2
Output: 2
Input: M = 2, N = 3
Output: 3
Count all possible paths: We can recursively move to right and down from the start until we reach the
destination and then add up all valid paths to get the answer.
Procedure:
Create a recursive function with parameters as row and column index
Call this recursive function for N-1 and M-1
In the recursive function
If N == 1 or M == 1 then return 1
else call the recursive function with (N-1, M) and (N, M-1) and return the sum of this
Print the answer
Hints:
# Python program to count all possible paths from top left to bottom right
# Function to return count of possible paths to reach cell at row number m and column
number n from the topmost leftmost cell (cell at 1, 1)
TRY
1. Take input : M = 3, N = 2 and verify the results.
2. Take input : M = 2, N = 1 and verify the results.
8. Graph Coloring
8.1 Graph Coloring using Greedy Algorithm
Greedy algorithm is used to assign colors to the vertices of a graph. It doesn’t guarantee to use minimum
colors, but it guarantees an upper bound on the number of colors. The basic algorithm never uses more
than d+1 colors where d is the maximum degree of a vertex in the given graph.
Hints:
# Implement greedy algorithm for graph coloring
# Driver Code
g1 = [[] for i in range(5)]
g1 = addEdge(g1, 0, 1)
g1 = addEdge(g1, 0, 2)
g1 = addEdge(g1, 1, 2)
g1 = addEdge(g1, 1, 3)
g1 = addEdge(g1, 2, 3)
g1 = addEdge(g1, 3, 4)
print("Coloring of graph 1 ")
greedyColoring(g1, 5)
Output:
Coloring of graph 1
Vertex 0 ---> Color 0
Vertex 1 ---> Color 1
Vertex 2 ---> Color 2
Vertex 3 ---> Color 0
Vertex 4 ---> Color 1
Coloring of graph 2
Vertex 0 ---> Color 0
Vertex 1 ---> Color 1
Vertex 2 ---> Color 2
Vertex 3 ---> Color 0
Vertex 4 ---> Color 3
Approach:
If the no. of vertices is Even then it is Even Cycle and to color such graph we require 2 colors.
If the no. of vertices is Odd then it is Odd Cycle and to color such graph we require 3 colors.
Input: Vertices = 3
Output: No. of colors require is: 3
Input: vertices = 4
Output: No. of colors require is: 2
Color required = 2
Color required = 3
Hints:
# Find the number of colors required to color a cycle graph
# Driver Code
vertices = 3
print ("No. of colors require is:", Color(vertices))
Note: Here coloring of a graph means the assignment of colors to all vertices
Following is an example of a graph that can be colored with 3 different colors:
Generate all possible configurations of colors. Since each node can be colored using any of the m
available colors, the total number of color configurations possible is mV. After generating a configuration
of color, check if the adjacent vertices have the same color or not. If the conditions are met, print the
combination and break the loop
Create a recursive function that takes the current index, number of vertices and output color array
If the current index is equal to number of vertices. Check if the output color configuration is safe, i.e
check if the adjacent vertices do not have same color. If the conditions are met, print the
configuration and break
Assign a color to a vertex (1 to m)
For every assigned color recursively call the function with next index and number of vertices
If any recursive function returns true break the loop and returns true.
Hints:
# Number of vertices in the graph
# define 4 4
def printSolution(color):
print("Solution Exists:" " Following are the assigned colors ")
for i in range(4):
print(color[i], end=" ")
# Driver code
# /* Create following graph and test whether it is 3 colorable
# (3)---(2)
# | / |
# | / |
# | / |
# (0)---(1)
# */
graph = [
[0, 1, 1, 1],
[1, 0, 1, 0],
[1, 1, 0, 1],
[1, 0, 1, 0],
]
m = 3 # Number of colors
# Function call
if (not graphColoring(graph, m, 0, color)):
print("Solution does not exist")
Input: u1 = 1, v1 = 4
u2 = 1, v2 = 2
u3 = 2, v3 = 3
u4 = 3, v4 = 4
The above input shows the pair of vertices (ui, vi) who have an edge between them. The output shows the
color assigned to the respective edges.
Edge colorings are one of several different types of graph coloring problems. The above figure of a Graph
shows an edge coloring of a graph by the colors green and black, in which no adjacent edge have the
same color.
Algorithm:
1. Use BFS traversal to start traversing the graph.
2. Pick any vertex and give different colors to all of the edges connected to it, and mark those edges as
colored.
3. Traverse one of it’s edges.
4. Repeat step to with a new vertex until all edges are colored.
Hints:
# Edge Coloring
# Driver Function
empty=set()
# declaring vector of vector of pairs, to define Graph
gra=[]
edgeColors=[]
isVisited=[False]*100000
ver = 4
edge = 4
gra=[[] for _ in range(ver)]
edgeColors=[-1]*edge
gra[0].append((1, 0))
gra[1].append((0, 0))
gra[1].append((2, 1))
gra[2].append((1, 1))
gra[2].append((3, 2))
gra[3].append((2, 2))
gra[0].append((3, 3))
gra[3].append((0, 3))
colorEdges(0, gra, edgeColors, isVisited)
TRY
1. Write a program to implement graph coloring and edge coloring by consider the below graph and
verify the results.
9. Graph Traversal
9.1 Breadth First Search
The Breadth First Search (BFS) algorithm is used to search a graph data structure for a node that meets
a set of criteria. It starts at the root of the graph and visits all nodes at the current depth level before
moving on to the nodes at the next depth level.
For a given graph G, print BFS traversal from a given source vertex.
Hints:
# BFS traversal from a given source vertex.
# Constructor
def __init__(self):
# Default dictionary to store graph
self.graph = defaultdict(list)
For a given graph G, print DFS traversal from a given source vertex.
Input: n = 4, e = 6
0 -> 1, 0 -> 2, 1 -> 2, 2 -> 0, 2 -> 3, 3 -> 3
Explanation:
DFS Diagram:
Input: n = 4, e = 6
2 -> 0, 0 -> 2, 1 -> 2, 0 -> 1, 3 -> 3, 1 -> 3
Explanation:
DFS Diagram:
Hints:
# DFS traversal from a given graph
from collections import defaultdict
# Driver's code
g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)
print("Following is Depth First Traversal (starting from vertex 2)")
# Function call
g.DFS(2)
TRY
1. Write a program to implement breadth first search and depth first search by consider the below graph
and verify the results.
10. Minimum Spanning Tree (MST)
10.1 Kruskal’s Algorithm
In Kruskal’s algorithm, sort all edges of the given graph in increasing order. Then it keeps on adding new
edges and nodes in the MST if the newly added edge does not form a cycle. It picks the minimum
weighted edge at first and the maximum weighted edge at last.
Kruskal’s algorithm to find the minimum cost spanning tree uses the greedy approach. The Greedy Choice
is to pick the smallest weight edge that does not cause a cycle in the MST constructed so far.
Input: For the given graph G find the minimum cost spanning tree.
The graph contains 9 vertices and 14 edges. So, the minimum spanning tree formed will be having (9 – 1)
= 8 edges.
After sorting:
Output:
Hints:
# Kruskal's algorithm to find minimum Spanning Tree of a given connected,
# undirected and weighted graph
def KruskalMST(self):
# write your code here
…
# Driver code
g = Graph(4)
g.addEdge(0, 1, 10)
g.addEdge(0, 2, 6)
g.addEdge(0, 3, 5)
g.addEdge(1, 3, 15)
g.addEdge(2, 3, 4)
# Function call
g.KruskalMST()
Output: Following are the edges in the constructed MST
2 -- 3 == 4
0 -- 3 == 5
0 -- 1 == 10
Prim’s Algorithm:
The working of Prim’s algorithm can be described by using the following steps:
1. Determine an arbitrary vertex as the starting vertex of the MST.
2. Follow steps 3 to 5 till there are vertices that are not included in the MST (known as fringe vertex).
3. Find edges connecting any tree vertex with the fringe vertices.
4. Find the minimum among these edges.
5. Add the chosen edge to the MST if it does not form any cycle.
6. Return the MST and exit
Input: For the given graph G find the minimum cost spanning tree.
Output: The final structure of the MST is as follows and the weight of the edges of the MST is (4 + 8 + 1
+ 2 + 4 + 2 + 7 + 9) = 37.
Hints:
# Prim's Minimum Spanning Tree (MST) algorithm.
# The program is for adjacency matrix representation of the graph
class Graph():
def __init__(self, vertices):
self.V = vertices
self.graph = [[0 for column in range(vertices)]
for row in range(vertices)]
…
def primMST(self):
…
# Driver's code
g = Graph(5)
g.graph = [[0, 2, 0, 6, 0],
[2, 0, 3, 8, 5],
[0, 3, 0, 0, 7],
[6, 8, 0, 0, 9],
[0, 5, 7, 9, 0]]
g.primMST()
Output:
Edge Weight
0-1 2
1-2 3
0-3 6
1-4 5
TRY
1. Write a program to implement kruskal’s algorithm and prim’s algorithm by consider the below graph
and verify the results.
Assumptions:
1. f(x) is a continuous function in interval [a, b]
2. f(a) * f(b) < 0
Steps:
1. Find middle point c= (a + b)/2.
2. If f(c) == 0, then c is the root of the solution.
3. Else f(c) != 0
If value f(a)*f(c) < 0 then root lies between a and c. So we recur for a and c
Else If f(b)*f(c) < 0 then root lies between b and c. So we recur b and c.
Else given function doesn’t follow one of assumptions.
Since root may be a floating point number, we repeat above steps while difference between a and b is
greater than and equal to a value? (A very small value).
Hints:
# An example function whose solution is determined using Bisection Method.
# The function is x^3 - x^2 + 2
def func(x):
return x*x*x - x*x + 2
# Driver code
# Initial values assumed
a =-200
b = 300
bisection (a, b)
TRY
1. Take an input function x^2 - x^3 + 2 and verify the results.
2. Take an input function x^3 - x^3 + 4 and verify the results.
TRY
1. Take an input function x^2 - x^3 + 2 and verify the results.
2. Take an input function x^3 - x^3 + 4 and verify the results.
Output: The value of root is: -1.00 or any other value close to root.
Algorithm:
Input: initial x, func(x), derivFunc(x)
Output: Root of Func()
Hints:
# Implementation of Newton Raphson Method for solving equations
# An example function whose solution is determined using Bisection Method.
# The function is x^3 - x^2 + 2
def func( x ):
return x * x * x - x * x + 2
# Driver program
x0 = -20
newtonRaphson(x0)
TRY
1. Take an input function x^2 - x^3 + 2 and verify the results.
2. Take an input function x^3 - x^3 + 4 and verify the results.
Input: Equation = x3 + x – 1
x1 = 0, x2 = 1, E = 0.0001
Algorithm
Initialize: x1, x2, E, n // E = convergence indicator
calculate f(x1),f(x2)
Hints:
# Find root of an equations using secant method
# Function takes value of x and returns f(x)
def f(x):
# we are taking equation as x^3+x-1
f = pow(x, 3) + x - 1;
return f;
def secant(x1, x2, E):
# Write your code here
…
# Driver code
# initializing the values
x1 = 0;
x2 = 1;
E = 0.0001;
secant(x1, x2, E);
TRY
1. Take an input function x^2 - x + 2 and verify the results.
2. Take an input function x^3 - x^2 + 4 and verify the results.
Output: The value of the root is 1.3688 or any other value within permittable deviation from the root.
Output: The value of the root is 0.4021 or any other value within permittable deviation from the root.
Hints:
# Find root of a function, f(x)
import math;
MAX_ITERATIONS = 10000;
# Driver Code
a = 0;
b = 1;
c = 2;
Muller(a, b, c);
TRY
1. Take an input function x^2 - x^3 + 2 and verify the results.
2. Take an input function x^3 - x^3 + 4 and verify the results.
Hints:
# Implement Trapezoidal rule
# Driver code
# Range of definite integral
x0 = 0
xn = 1
1. Select a value for n, which is the number of parts the interval is divided into.
2. Calculate the width, h = (b-a)/n
3. Calculate the values of x0 to xn as x0 = a, x1 = x0 + h, …..xn-1 = xn-2 + h, xn = b.
Consider y = f(x). Now find the values of y (y0 to yn) for the corresponding x (x0 to xn) values.
4. Substitute all the above found values in the Simpson’s Rule Formula to calculate the integral value.
First we will divide interval into six equal parts as number of interval should be even.
Output: Now we can calculate approximate value of integral using above formula:
= 1.84
Hints:
# Simpson's 1 / 3 rule
import math
# Driver code
lower_limit = 4 # Lower limit
upper_limit = 5.2 # Upper limit
n = 6 # Number of interval
print("%.6f"% simpsons_(lower_limit, upper_limit, n))
12.3 Simpson’s 3/8 Rule
The Simpson’s 3/8 rule was developed by Thomas Simpson. This method is used for performing numerical
integrations. This method is generally used for numerical approximation of definite integrals. Here,
parabolas are used to approximate each part of curve.
Hints:
# Implement Simpson's 3/8 rule
# driver function
interval_limit = 10
lower_limit = 1
upper_limit = 10
Euler Method:
In mathematics and computational science, the Euler method (also called forward Euler method) is a first-
order numerical procedure for solving ordinary differential equations (ODEs) with a given initial value.
Example:
Consider below differential equation dy/dx = (x + y + xy) with initial condition y(0) = 1 and step size h =
0.025. Find y(0.1).
Solution:
f(x, y) = (x + y + xy)
x0 = 0, y0 = 1, h = 0.025
Now we can calculate y1 using Euler formula
y1 = y0 + h * f(x0, y0)
y1 = 1 + 0.025 *(0 + 1 + 0 * 1)
y1 = 1.025
y(0.025) = 1.025.
Similarly we can calculate y(0.050), y(0.075), ....y(0.1).
y(0.1) = 1.11167
Hints:
# Find approximation of an ordinary differential equation using Euler method.
# Driver Code
# Initial Values
x0 = 0
y0 = 1
h = 0.025
1. An ordinary differential equation that defines the value of dy/dx in the form x and y.
2. Initial value of y, i.e., y(0).
The task is to find the value of unknown function y at a given point x, i.e. y(x).
Input: x0 = 0, y0 = 1, x = 2, h = 0.2
Input: x0 = 2, y0 = 1, x = 4, h = 0.4;
Approach:
The Runge-Kutta method finds an approximate value of y for a given x. Only first-order ordinary
differential equations can be solved by using the Runge-Kutta 2nd-order method.
Below is the formula used to compute the next value yn+1 from the previous value yn. Therefore:
yn+1 = value of y at (x = n + 1)
yn = value of y at (x = n)
where 0 ? n ? (x - x0)/h, h is step height
xn+1 = x0 + h
The essential formula to compute the value of y(n+1):
K1 = h * f(x, y)
The formula basically computes the next value yn+1 using current yn plus the weighted average of two
increments:
K1 is the increment based on the slope at the beginning of the interval, using y.
K2 is the increment based on the slope at the midpoint of the interval, using (y + h*K1/2).
Hints:
# Implement Runge-Kutta method
# Finds value of y for a given x using step size h and initial value y0 at x0.
def rungeKutta(x0, y0, x, h):
# write code here
…
# Driver Code
x0 = 0
y = 1
x = 2
h = 0.2
print("y(x) =", rungeKutta(x0, y, x, h))
14. Final Notes
The only way to learn programming is program, program and program on challenging problems. The
problems in this tutorial are certainly NOT challenging. There are tens of thousands of challenging
problems available – used in training for various programming contests (such as International Collegiate
Programming Contest (ICPC), International Olympiad in Informatics (IOI)). Check out these sites:
The ACM - ICPC International collegiate programming contest (https://icpc.global/ )
The Topcoder Open (TCO) annual programming and design contest (https://www.topcoder.com/ )
Universidad de Valladolid’s online judge (https://uva.onlinejudge.org/ ).
Peking University’s online judge (http://poj.org/ ).
USA Computing Olympiad (USACO) Training Program @ http://train.usaco.org/usacogate.
Google’s coding competitions (https://codingcompetitions.withgoogle.com/codejam,
https://codingcompetitions.withgoogle.com/hashcode )
The ICFP programming contest (https://www.icfpconference.org/ )
BME International 24-hours programming contest (https://www.challenge24.org/ )
The International Obfuscated C Code Contest (https://www0.us.ioccc.org/main.html )
Internet Problem Solving Contest (https://ipsc.ksp.sk/ )
Microsoft Imagine Cup (https://imaginecup.microsoft.com/en-us )
Hewlett Packard Enterprise (HPE) Codewars (https://hpecodewars.org/ )
OpenChallenge (https://www.openchallenge.org/ )
V. TEXT BOOKS:
1. Eric Matthes, “Python Crash Course: A Hands-On, Project-based Introduction to Programming”, No Starch
Press, 3rd Edition, 2023.
2. John M Zelle, “Python Programming: An Introduction to Computer Science”, Ingram short title, 3rd Edition,
2016.
VI. REFERENCE BOOKS:
1. Yashavant Kanetkar, Aditya Kanetkar, “Let Us Python”, BPB Publications, 2nd Edition, 2019.
2. Martin C. Brown, “Python: The Complete Reference”, Mc. Graw Hill, Indian Edition, 2018.
3. Paul Barry, “Head First Python: A Brain-Friendly Guide”, O’Reilly, 2nd Edition, 2016
4. Taneja Sheetal, Kumar Naveen, “Python Programming – A Modular Approach”, Pearson, 1st Edition, 2017.
5. R Nageswar Rao, “Core Python Programming”, Dreamtech Press, 2018.
VII. ELECTRONICS RESOURCES
1. https://realPython.com/Python3-object-oriented-programming/
2. https://Python.swaroopch.com/oop.html
3. https://Python-textbok.readthedocs.io/en/1.0/Object_Oriented_Programming.html
4. https://www.programiz.com/Python-programming/
5. https://www.geeksforgeeks.org/python-programming-language/