You are on page 1of 67

DESIGN AND ANALYSIS OF ALGORITHM

LAB RECORD
EXPERIMENT NO .1
Using a stack of characters, convert an infix string to post-fix string

Algorithm :-

1. Scan all the symbols one by one from left to right in the given
Infix Expression.
2. If the reading symbol is an operand, then immediately append it
to the Post-fix Expression.
3. If the reading symbol is left parenthesis ‘( ‘, then Push it onto the
Stack.
4. If the reading symbol is right parenthesis ‘)’, then Pop all the
contents of the stack until the respective left parenthesis is popped
and append each popped symbol to Post-fix Expression.
5. If the reading symbol is an operator (+, –, *, /), then Push it onto
the Stack. However, first, pop the operators which are already on
the stack that have higher or equal precedence than the current
operator and append them to the post-fix. If an open parenthesis
is there on top of the stack then push the operator into the stack.
6. If the input is over, pop all the remaining symbols from the stack
and append them to the post-fix.

Program:-
#include<stdio.h>
#include<ctype.h>
char stack[100];
int top = -1;
void push(char x)
{
stack[++top] = x;
}
char pop()
{
if(top == -1)
return -1;
else
return stack[top--];
}
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD

int priority(char x)
{
if(x == '(')
return 0;
if(x == '+' || x == '-')
return 1;
if(x == '*' || x == '/')
return 2;
return 0;
}

int main()
{
char exp[100];
char *e, x;
printf("Enter the expression : ");
scanf("%s",exp);
printf("\n");
e = exp;

while(*e != '\0')
{
if(isalnum(*e))
printf("%c ",*e);
else if(*e == '(')
push(*e);
else if(*e == ')')
{
while((x = pop()) != '(')
printf("%c ", x);
}
else
{
while(priority(stack[top]) >= priority(*e))
printf("%c ",pop());
push(*e);
}
e++;
}

while(top != -1)
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
{
printf("%c ",pop());
}return 0;
}

Output Test Case 1:


Enter the expression : a+b*c

abc*+
Case 2:

Enter the expression : (a+b)*c+(d-a)

ab+c*da-+

Case 3:

Enter the expression : ((4+8)(6-5))/((3-2)(2+2))

48+65-32-22+/
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
EXPERIMENT NO.2
Implement insertion, deletion, searching of a BST

ALGORITHM:-

Insertion sort
 Call insert to insert the element that starts at index
1 into the sorted subarray in index 0.
 Call insert to insert the element that starts at index 2
into the sorted subarray in indices 0 through 1.
 Call insert to insert the element that starts at index 3
into the sorted subarray in indices 0 through 2.

 Finally, call insert to insert the element that starts at
index
 into the sorted subarray in indices 0 through

Deletion sort
Case 1- Node with zero children: this is the easiest
situation, you just need to delete the node which has no
further children on the right or left.
Case 2 – Node with one child: once you delete the node,
simply connect its child node with the parent node of the
deleted value.
Case 3 Node with two children: this is the most difficult
situation, and it works on the following two rules
3a – In Order Predecessor: you need to delete the node
with two children and replace it with the largest value on
the left-subtree of the deleted node
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
3b – In Order Successor: you need to delete the node
with two children and replace it with the largest value on
the right-subtree of the deleted node
searching of a BST

The element to be searched is 10


Compare the element with the root node 12, 10 <
12, hence you move to the left subtree. No need to
analyze the right-subtree
Now compare 10 with node 7, 10 > 7, so move to
the right-subtree
Then compare 10 with the next node, which is 9, 10
> 9, look in the right subtree child
10 matches with the value in the node, 10 = 10,
return the value to the user.

pseudo code:-

Insertion sort
insert (element, root)
Node x = root
Node y = NULL
while x:
y=x
if x.value < element.value
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
x = x.right
else
x = x.left
if y.value < element
y.right = element
else
y.left = element
Deletion sort
delete (value, root):
Node x = root
Node y = NULL
while x:
y=x
if x.value < value
x = x.right
else if x.value > value
x = x.left
else if value == x
break
if y.left or y.right:
newNode = GetInOrderSuccessor(y)
root.value = newNode.value
free(newNode)
else
free(y)

searching of a BST
search(element, root)
if !root
return -1
if root.value == element
return 1
if root.value < element
search(element, root.right)
else
search(element, root.left)
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD

PROGRAM:-

#include <stdio.h>
#include <stdlib.h>

typedef struct node {


int data;
struct node *left;
struct node *right;
struct node *parent;
}node;

typedef struct binary_search_tree {


node *root;
}binary_search_tree;

node* new_node(int data) {


node *n = malloc(sizeof(node));
n->data = data;
n->left = NULL;
n->right = NULL;
n->parent = NULL;

return n;
}

binary_search_tree* new_binary_search_tree() {
binary_search_tree *t = malloc(sizeof(binary_search_tree));
t->root = NULL;

return t;
}

node* minimum(binary_search_tree *t, node *x) {


while(x->left != NULL)
x = x->left;
return x;
}

void insert(binary_search_tree *t, node *n) {


DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
node *y = NULL;
node *temp = t->root;
while(temp != NULL) {
y = temp;
if(n->data < temp->data)
temp = temp->left;
else
temp = temp->right;
}
n->parent = y;

if(y == NULL) //newly added node is root


t->root = n;
else if(n->data < y->data)
y->left = n;
else
y->right = n;
}

void transplant(binary_search_tree *t, node *u, node *v) {


if(u->parent == NULL) //u is root
t->root = v;
else if(u == u->parent->left) //u is left child
u->parent->left = v;
else //u is right child
u->parent->right = v;

if(v != NULL)
v->parent = u->parent;
}

void delete(binary_search_tree *t, node *z) {


if(z->left == NULL) {
transplant(t, z, z->right);
free(z);
}
else if(z->right == NULL) {
transplant(t, z, z->left);
free(z);
}
else {
node *y = minimum(t, z->right); //minimum element in right subtree
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
if(y->parent != z) {
transplant(t, y, y->right);
y->right = z->right;
y->right->parent = y;
}
transplant(t, z, y);
y->left = z->left;
y->left->parent = y;
free(z);
}
}

void inorder(binary_search_tree *t, node *n) {


if(n != NULL) {
inorder(t, n->left);
printf("%d\n", n->data);
inorder(t, n->right);
}
}

int main() {
binary_search_tree *t = new_binary_search_tree();

node *a, *b, *c, *d, *e, *f, *g, *h, *i, *j, *k, *l, *m;

a = new_node(10);
b = new_node(20);
c = new_node(30);
d = new_node(100);
e = new_node(90);
f = new_node(40);
g = new_node(50);
h = new_node(60);
i = new_node(70);
j = new_node(80);
k = new_node(150);
l = new_node(110);
m = new_node(120);

insert(t, a);
insert(t, b);
insert(t, c);
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
insert(t, d);
insert(t, e);
insert(t, f);
insert(t, g);
insert(t, h);
insert(t, i);
insert(t, j);
insert(t, k);
insert(t, l);
insert(t, m);

delete(t, a);
delete(t, m);

inorder(t, t->root);

return 0;
}

OUTPUT:-

20
30
40
50
60
70
80
90
100
110
150
EXPERIMENT NO .3
3. (a) Implement binary search and linear search in a
program
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
Algorithm:-
Linear Search

Step 1 − Start from the 0th index of the input array,


compare the key value with the value present in the 0th
index.

Step 2 − If the value matches with the key, return the


position at which the value was found.

Step 3 − If the value does not match with the key,


compare the next element in the array.

Step 4 − Repeat Step 3 until there is a match found.


Return the position at which the match was found.

Step 5 − If it is an unsuccessful search, print that the


element is not present in the array and exit the program.

Binary Search
Let’s say we want to search for the number X, We start at
the root. Then:

We compare the value to be searched with the value of


the root.
If it’s equal we are done with the search if it’s smaller we
know that we need to go to the left sub tree because in a
binary search tree all the elements in the left sub tree are
smaller and all the elements in the right sub tree are
larger.
Repeat the above step till no more traversal is possible
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
If at any iteration, key is found, return True. Else False.

Pseudo code:-
Linear Search:-
procedure linear_search (list, value)
for each item in the list
if match item == value
return the item's location
end if
end for
end procedure
Binary Search:-
function binary_search(list, target):
left = 0
right = length(list) - 1
while left <= right:
mid = (left + right) // 2
if list[mid] == target:
return mid
elif list[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1

PROGRAM:-

LINEAR SEARCH:-
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
#include <stdio.h>

int search(int array[], int n, int x)


{

// Going through array sequencially


for (int i = 0; i < n; i++)
if (array[i] == x)
return i;
return -1;
}

int main()
{
int array[] = { 12, 114, 0, 4, 9 };
int x = 4;
int n = sizeof(array) / sizeof(array[0]);

int result = search(array, n, x);

(result == -1)
? printf("Element not found")
: printf("Element found at index: %d", result);
}
OUTPUT:-
Element found at index: 3
BINARY SEARCH:-

#include <stdio.h>

int binarySearch(int array[], int x, int low, int high)


{
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
// Repeat until the pointers low and high meet each
// other
while (low <= high) {
int mid = low + (high - low) / 2;

if (array[mid] == x)
return mid;

if (array[mid] < x)
low = mid + 1;

else
high = mid - 1;
}

return -1;
}

int main( )
{
int array[] = { 2, 4, 5, 7, 14, 17, 19, 22 };
int n = sizeof(array) / sizeof(array[0]);
int x = 22;
int result = binarySearch(array, x, 0, n - 1);
if (result == -1)
printf("Not found");
else
printf(" %d", result);
return 0;
}

OUTPUT:_
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD

7
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
EXPERIMENT NO .3(B)
3(b)Implement a heap sort using a max heap.

ALGORITHM:-
 First convert the array into heap data structure
using heapify, then one by one delete the root
node of the Max-heap and replace it with the last
node in the heap and then heapify the root of the
heap.
 Repeat this process until size of heap is greater
than 1.

 Build a heap from the given input array.


Repeat the following steps until the heap
contains only one element:
 Swap the root element of the heap (which is the
largest element) with the last element of the
heap.
 Remove the last element of the heap (which is
now in the correct position).
 Heapify the remaining elements of the heap.
 The sorted array is obtained by reversing the
order of the elements in the input array.

PSEDOCODE:-
Heapify(A as array, n as int, i as int)
{
max = i
leftchild = 2i + 1
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
rightchild = 2i + 2

if (leftchild <= n) and (A[i] < A[leftchild])


max = leftchild
else
max = i

if (rightchild <= n) and (A[max] > A[rightchild])


max = rightchild

if (max != i)
swap(A[i], A[max])
Heapify(A, n, max)
}

Heapsort(A as array)
{
n = length(A)
for i = n/2 downto 1
Heapify(A, n ,i)
for i = n downto 2
exchange A[1] with A[i]
A.heapsize = A.heapsize - 1
Heapify(A, i, 0)
}

PROGRAM:-
#include <stdio.h>
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
void heapify(int arr[], int N, int i)
{
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < N && arr[left] > arr[largest])
largest = left;
if (right < N && arr[right] > arr[largest])
largest = right;
if (largest != i) {
swap(&arr[i], &arr[largest]);
heapify(arr, N, largest);
}
}

void heapSort(int arr[], int N)


{
for (int i = N / 2 - 1; i >= 0; i--)
heapify(arr, N, i);
for (int i = N - 1; i >= 0; i--) {
swap(&arr[0], &arr[i]);
heapify(arr, i, 0);
}
}
void printArray(int arr[], int N)
{
for (int i = 0; i < N; i++)
printf("%d ", arr[i]);
printf("\n");
}
int main()
{
int arr[] = { 12, 11, 13, 5, 6, 7 };
int N = sizeof(arr) / sizeof(arr[0]);
heapSort(arr, N);
printf("Sorted array is\n");
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
printArray(arr, N);
}
Output:-
Sorted array is
5 6 7 11 12 13
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
EXPERIMENT NO .4(A)

4(a) .Implement DFS/ BFS for a connected


graph.

Depth First Search Algorithm:-


 A standard DFS implementation puts each vertex
of the graph into one of two categories:
I. Visited
II. Not Visited
 The purpose of the algorithm is to mark each
vertex as visited while avoiding cycles.
 The DFS algorithm works as follows:
Start by putting any one of the graph's vertices
on top of a stack.
 Take the top item of the stack and add it to the
visited list.
 Create a list of that vertex's adjacent nodes. Add
the ones which aren't in the visited list to the top of
the stack.Keep repeating steps 2 and 3 until the
stack is empty.
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
DFS Pseudocode:-
DFS(G, u)
u.visited = true
for each v ∈ G.Adj[u]
if v.visited == false
DFS(G,v)
init() {
For each u ∈ G
u.visited = false
For each u ∈ G
DFS(G, u)
}

PROGRAM:-
#include <stdio.h>
#include <stdlib.h>

struct node {
int vertex;
struct node* next;
};

struct node* createNode(int v);

struct Graph {
int numVertices;
int* visited;

Linked lists
struct node** adjLists;
};
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD

void DFS(struct Graph* graph, int vertex) {


struct node* adjList = graph->adjLists[vertex];
struct node* temp = adjList;

graph->visited[vertex] = 1;
printf("Visited %d \n", vertex);

while (temp != NULL) {


int connectedVertex = temp->vertex;

if (graph->visited[connectedVertex] == 0) {
DFS(graph, connectedVertex);
}
temp = temp->next;
}
}

struct node* createNode(int v) {


struct node* newNode = malloc(sizeof(struct node));
newNode->vertex = v;
newNode->next = NULL;
return newNode;
}

struct Graph* createGraph(int vertices) {


struct Graph* graph = malloc(sizeof(struct Graph));
graph->numVertices = vertices;

graph->adjLists = malloc(vertices * sizeof(struct


node*));
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
graph->visited = malloc(vertices * sizeof(int));

int i;
for (i = 0; i < vertices; i++) {
graph->adjLists[i] = NULL;
graph->visited[i] = 0;
}
return graph;
}

void addEdge(struct Graph* graph, int src, int dest) {


struct node* newNode = createNode(dest);
newNode->next = graph->adjLists[src];
graph->adjLists[src] = newNode;
newNode = createNode(src);
newNode->next = graph->adjLists[dest];
graph->adjLists[dest] = newNode;
}

void printGraph(struct Graph* graph) {


int v;
for (v = 0; v < graph->numVertices; v++) {
struct node* temp = graph->adjLists[v];
printf("\n Adjacency list of vertex %d\n ", v);
while (temp) {
printf("%d -> ", temp->vertex);
temp = temp->next;
}
printf("\n");
}
}
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
int main() {
struct Graph* graph = createGraph(4);
addEdge(graph, 0, 1);
addEdge(graph, 0, 2);
addEdge(graph, 1, 2);
addEdge(graph, 2, 3);

printGraph(graph);

DFS(graph, 2);

return 0;

OUT PUT:-
Adjacency list of vertex 0
2 -> 1 ->
Adjacency list of vertex 1
2 -> 0 ->
Adjacency list of vertex 2
3 -> 1 -> 0 ->
Adjacency list of vertex 3
2 ->
Visited 2 Visited 3 Visited 1 Visited 0
Breadth First Search (BFS) for a Graph
Algorithm:
Let’s discuss the algorithm for the BFS:
Initialization: Enqueue the starting node into a queue and mark it as
visited.
Exploration: While the queue is not empty:
Dequeue a node from the queue and visit it (e.g., print its value).
For each unvisited neighbor of the dequeued node:
Enqueue the neighbor into the queue.
Mark the neighbor as visited.
Termination: Repeat step 2 until the queue is empty.
PROGRAM:-
#include <stdio.h>
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
struct Node* createNode(int data)
{
struct Node* newNode
= (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
void addEdge(struct Node* adjList[], int u, int v)
{
struct Node* newNode = createNode(v);
newNode->next = adjList[u];
adjList[u] = newNode;
}
void bfs(struct Node* adjList[], int vertices,
int startNode, int visited[])
{
int queue[MAX_VERTICES];
int front = 0, rear = 0;

visited[startNode] = 1;
queue[rear++] = startNode;
while (front != rear) {
int currentNode = queue[front++];
printf("%d ", currentNode);
struct Node* temp = adjList[currentNode];
while (temp != NULL)
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
{
int neighbor = temp->data;
if (!visited[neighbor]) {
visited[neighbor] = 1;
queue[rear++] = neighbor;
}
temp = temp->next;
}
}
}

int main()
{
int vertices = 5;
struct Node* adjList[vertices];
for (int i = 0; i < vertices; ++i)
adjList[i] = NULL;
addEdge(adjList, 0, 1);
addEdge(adjList, 0, 2);
addEdge(adjList, 1, 3);
addEdge(adjList, 1, 4);
addEdge(adjList, 2, 4);
int visited[vertices];
for (int i = 0; i < vertices; ++i)
visited[i] = 0;
printf("Breadth First Traversal starting from vertex
0: ");
bfs(adjList, vertices, 0, visited);
return 0;
}

Output:-
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
Breadth First Traversal starting from vertex 0: 0 1 2
34

EXPERIMENT NO .4(B)

AIM OF THE EXPERIME:-

Implement Dijkstra’s shortest path algorithm using BFS.

Djikstra's algorithm :-

 We need to maintain the path distance of every vertex.


We can store that in an array of size v, where v is the
number of vertices.
 We also want to be able to get the shortest path, not
only know the length of the shortest path. For this, we
map each vertex to the vertex that last updated its path
length.
 Once the algorithm is over, we can backtrack from the
destination vertex to the source vertex to find the path.
 A minimum priority queue can be used to efficiently
receive the vertex with least path distance.
Pseudocode:-
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
function dijkstra(G, S)
for each vertex V in G
distance[V] <- infinite
previous[V] <- NULL
If V != S, add V to Priority Queue Q
distance[S] <- 0
while Q IS NOT EMPTY
U <- Extract MIN from Q
for each unvisited neighbour V of U
tempDistance <- distance[U] + edge_weight(U,
V)
if tempDistance < distance[V]
distance[V] <- tempDistance
previous[V] <- U
return distance[], previous[]

PROGRAM:-
#include <stdio.h>
#define INFINITY 9999
#define MAX 10
void Dijkstra(int Graph[MAX][MAX], int n, int start);
void Dijkstra(int Graph[MAX][MAX], int n, int start)
{
int cost[MAX][MAX], distance[MAX], pred[MAX];
int visited[MAX], count, mindistance, nextnode, i, j;

for (i = 0; i < n; i++)


for (j = 0; j < n; j++)
if (Graph[i][j] == 0)
cost[i][j] = INFINITY;
else
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
cost[i][j] = Graph[i][j];

for (i = 0; i < n; i++) {


distance[i] = cost[start][i];
pred[i] = start;
visited[i] = 0;
}

distance[start] = 0;
visited[start] = 1;
count = 1;

while (count < n - 1) {


mindistance = INFINITY;

for (i = 0; i < n; i++)


if (distance[i] < mindistance && !visited[i]) {
mindistance = distance[i];
nextnode = i;
}

visited[nextnode] = 1;
for (i = 0; i < n; i++)
if (!visited[i])
if (mindistance + cost[nextnode][i] < distance[i])
{
distance[i] = mindistance + cost[nextnode][i];
pred[i] = nextnode;
}
count++;
}
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
for (i = 0; i < n; i++)
if (i != start) {
printf("\nDistance from source to %d: %d", i,
distance[i]);
}
}
int main() {
int Graph[MAX][MAX], i, j, n, u;
n = 7;

Graph[0][0] = 0;
Graph[0][1] = 0;
Graph[0][2] = 1;
Graph[0][3] = 2;
Graph[0][4] = 0;
Graph[0][5] = 0;
Graph[0][6] = 0;

Graph[1][0] = 0;
Graph[1][1] = 0;
Graph[1][2] = 2;
Graph[1][3] = 0;
Graph[1][4] = 0;
Graph[1][5] = 3;
Graph[1][6] = 0;

Graph[2][0] = 1;
Graph[2][1] = 2;
Graph[2][2] = 0;
Graph[2][3] = 1;
Graph[2][4] = 3;
Graph[2][5] = 0;
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
Graph[2][6] = 0;

Graph[3][0] = 2;
Graph[3][1] = 0;
Graph[3][2] = 1;
Graph[3][3] = 0;
Graph[3][4] = 0;
Graph[3][5] = 0;
Graph[3][6] = 1;

Graph[4][0] = 0;
Graph[4][1] = 0;
Graph[4][2] = 3;
Graph[4][3] = 0;
Graph[4][4] = 0;
Graph[4][5] = 2;
Graph[4][6] = 0;

Graph[5][0] = 0;
Graph[5][1] = 3;
Graph[5][2] = 0;
Graph[5][3] = 0;
Graph[5][4] = 2;
Graph[5][5] = 0;
Graph[5][6] = 1;

Graph[6][0] = 0;
Graph[6][1] = 0;
Graph[6][2] = 0;
Graph[6][3] = 1;
Graph[6][4] = 0;
Graph[6][5] = 1;
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
Graph[6][6] = 0;

u = 0;
Dijkstra(Graph, n, u);

return 0;
}

OUT PUT:-

Distance from source to 1: 3


Distance from source to 2: 1
Distance from source to 3: 2
Distance from source to 4: 4
Distance from source to 5: 4
Distance from source to 6: 3

EXPERIMENT NO .5(A)

AIM OF THE EXPERIME:-


Write a program to implement Huffman’s algorithm.
Huffman Coding Algorithm
ALGORITM:-
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
create a priority queue Q consisting of each unique
character.
sort then in ascending order of their frequencies.
for all the unique characters:
create a newNode
extract minimum value from Q and assign it to
leftChild of newNode
extract minimum value from Q and assign it to
rightChild of newNode
calculate the sum of these two minimum values and
assign it to the value of newNode
insert this newNode into the tree
return rootNode
PROGRAM:-
#include <stdio.h>
#include <stdlib.h>

#define MAX_TREE_HT 50

struct MinHNode {
char item;
unsigned freq;
struct MinHNode *left, *right;
};

struct MinHeap {
unsigned size;
unsigned capacity;
struct MinHNode **array;
};

struct MinHNode *newNode(char item, unsigned freq) {


DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
struct MinHNode *temp = (struct MinHNode
*)malloc(sizeof(struct MinHNode));

temp->left = temp->right = NULL;


temp->item = item;
temp->freq = freq;

return temp;
}

struct MinHeap *createMinH(unsigned capacity) {


struct MinHeap *minHeap = (struct MinHeap
*)malloc(sizeof(struct MinHeap));

minHeap->size = 0;

minHeap->capacity = capacity;

minHeap->array = (struct MinHNode


**)malloc(minHeap->capacity * sizeof(struct MinHNode
*));
return minHeap;
}

void swapMinHNode(struct MinHNode **a, struct


MinHNode **b) {
struct MinHNode *t = *a;
*a = *b;
*b = t;
}

void minHeapify(struct MinHeap *minHeap, int idx) {


DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
int smallest = idx;
int left = 2 * idx + 1;
int right = 2 * idx + 2;

if (left < minHeap->size && minHeap->array[left]-


>freq < minHeap->array[smallest]->freq)
smallest = left;

if (right < minHeap->size && minHeap->array[right]-


>freq < minHeap->array[smallest]->freq)
smallest = right;

if (smallest != idx) {
swapMinHNode(&minHeap->array[smallest],
&minHeap->array[idx]);
minHeapify(minHeap, smallest);
}
}

int checkSizeOne(struct MinHeap *minHeap) {


return (minHeap->size == 1);
}

struct MinHNode *extractMin(struct MinHeap


*minHeap) {
struct MinHNode *temp = minHeap->array[0];
minHeap->array[0] = minHeap->array[minHeap->size -
1];

--minHeap->size;
minHeapify(minHeap, 0);
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
return temp;
}

void insertMinHeap(struct MinHeap *minHeap, struct


MinHNode *minHeapNode) {
++minHeap->size;
int i = minHeap->size - 1;

while (i && minHeapNode->freq < minHeap->array[(i


- 1) / 2]->freq) {
minHeap->array[i] = minHeap->array[(i - 1) / 2];
i = (i - 1) / 2;
}
minHeap->array[i] = minHeapNode;
}

void buildMinHeap(struct MinHeap *minHeap) {


int n = minHeap->size - 1;
int i;

for (i = (n - 1) / 2; i >= 0; --i)


minHeapify(minHeap, i);
}

int isLeaf(struct MinHNode *root) {


return !(root->left) && !(root->right);
}

struct MinHeap *createAndBuildMinHeap(char item[],


int freq[], int size) {
struct MinHeap *minHeap = createMinH(size);
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
for (int i = 0; i < size; ++i)
minHeap->array[i] = newNode(item[i], freq[i]);

minHeap->size = size;
buildMinHeap(minHeap);

return minHeap;
}

struct MinHNode *buildHuffmanTree(char item[], int


freq[], int size) {
struct MinHNode *left, *right, *top;
struct MinHeap *minHeap =
createAndBuildMinHeap(item, freq, size);

while (!checkSizeOne(minHeap)) {
left = extractMin(minHeap);
right = extractMin(minHeap);

top = newNode('$', left->freq + right->freq);

top->left = left;
top->right = right;

insertMinHeap(minHeap, top);
}
return extractMin(minHeap);
}

void printHCodes(struct MinHNode *root, int arr[], int


top) {
if (root->left) {
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
arr[top] = 0;
printHCodes(root->left, arr, top + 1);
}
if (root->right) {
arr[top] = 1;
printHCodes(root->right, arr, top + 1);
}
if (isLeaf(root)) {
printf(" %c | ", root->item);
printArray(arr, top);
}
}

void HuffmanCodes(char item[], int freq[], int size) {


struct MinHNode *root = buildHuffmanTree(item, freq,
size);

int arr[MAX_TREE_HT], top = 0;

printHCodes(root, arr, top);


}

void printArray(int arr[], int n) {


int i;
for (i = 0; i < n; ++i)
printf("%d", arr[i]);

printf("\n");
}

int main() {
char arr[] = {'A', 'B', 'C', 'D'};
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
int freq[] = {5, 1, 6, 3};
int size = sizeof(arr) / sizeof(arr[0]);
printf(" Char | Huffman code ");
printf("\n--------------------\n");
HuffmanCodes(arr, freq, size);
}
OUTPUT:-
C |0
B | 100
D | 101
A | 11

EXPERIMENT NO .5(B)

AIM OF THE EXPERIME:-

Implement MST using Kruskal /Prim algorithm.

ALGORITHM:-

Sort all the edges from low weight to high


Take the edge with the lowest weight and add it to the
spanning tree. If adding the edge created a cycle, then
reject this edge.
Keep adding edges until we reach all vertices.

PSEDOCODE:-
KRUSKAL(G):
A=∅
For each vertex v ∈ G.V:
MAKE-SET(v)
For each edge (u, v) ∈ G.E ordered by increasing order by
weight(u, v):
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
if FIND-SET(u) ≠ FIND-SET(v):
A = A ∪ {(u, v)}
UNION(u, v)
return A

PROGRAM:-
// Kruskal's algorithm in C

#include <stdio.h>

#define MAX 30

typedef struct edge {


int u, v, w;
} edge;

typedef struct edge_list {


edge data[MAX];
int n;
} edge_list;

edge_list elist;

int Graph[MAX][MAX], n;
edge_list spanlist;

void kruskalAlgo();
int find(int belongs[], int vertexno);
void applyUnion(int belongs[], int c1, int c2);
void sort();
void print();

// Applying Krushkal Algo


void kruskalAlgo() {
int belongs[MAX], i, j, cno1, cno2;
elist.n = 0;
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
for (i = 1; i < n; i++)
for (j = 0; j < i; j++) {
if (Graph[i][j] != 0) {
elist.data[elist.n].u = i;
elist.data[elist.n].v = j;
elist.data[elist.n].w = Graph[i][j];
elist.n++;
}
}

sort();

for (i = 0; i < n; i++)


belongs[i] = i;

spanlist.n = 0;

for (i = 0; i < elist.n; i++) {


cno1 = find(belongs, elist.data[i].u);
cno2 = find(belongs, elist.data[i].v);

if (cno1 != cno2) {
spanlist.data[spanlist.n] = elist.data[i];
spanlist.n = spanlist.n + 1;
applyUnion(belongs, cno1, cno2);
}
}
}

int find(int belongs[], int vertexno) {


return (belongs[vertexno]);
}

void applyUnion(int belongs[], int c1, int c2) {


int i;
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
for (i = 0; i < n; i++)
if (belongs[i] == c2)
belongs[i] = c1;
}

// Sorting algo
void sort() {
int i, j;
edge temp;

for (i = 1; i < elist.n; i++)


for (j = 0; j < elist.n - 1; j++)
if (elist.data[j].w > elist.data[j + 1].w) {
temp = elist.data[j];
elist.data[j] = elist.data[j + 1];
elist.data[j + 1] = temp;
}
}

// Printing the result


void print() {
int i, cost = 0;

for (i = 0; i < spanlist.n; i++) {


printf("\n%d - %d : %d", spanlist.data[i].u, spanlist.data[i].v,
spanlist.data[i].w);
cost = cost + spanlist.data[i].w;
}

printf("\nSpanning tree cost: %d", cost);


}

int main() {
int i, j, total_cost;

n = 6;
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD

Graph[0][0] = 0;
Graph[0][1] = 4;
Graph[0][2] = 4;
Graph[0][3] = 0;
Graph[0][4] = 0;
Graph[0][5] = 0;
Graph[0][6] = 0;

Graph[1][0] = 4;
Graph[1][1] = 0;
Graph[1][2] = 2;
Graph[1][3] = 0;
Graph[1][4] = 0;
Graph[1][5] = 0;
Graph[1][6] = 0;

Graph[2][0] = 4;
Graph[2][1] = 2;
Graph[2][2] = 0;
Graph[2][3] = 3;
Graph[2][4] = 4;
Graph[2][5] = 0;
Graph[2][6] = 0;

Graph[3][0] = 0;
Graph[3][1] = 0;
Graph[3][2] = 3;
Graph[3][3] = 0;
Graph[3][4] = 3;
Graph[3][5] = 0;
Graph[3][6] = 0;

Graph[4][0] = 0;
Graph[4][1] = 0;
Graph[4][2] = 4;
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
Graph[4][3] = 3;
Graph[4][4] = 0;
Graph[4][5] = 0;
Graph[4][6] = 0;

Graph[5][0] = 0;
Graph[5][1] = 0;
Graph[5][2] = 2;
Graph[5][3] = 0;
Graph[5][4] = 3;
Graph[5][5] = 0;
Graph[5][6] = 0;

kruskalAlgo();
print();
}

OUT PUT:-

2-1:2
5-2:2
3-2:3
4-3:3
1-0:4
Spanning tree cost: 14
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
EXPERIMENT NO .6(B)

AIM OF THE EXPERIME:-

6.(a) Write a program on Quick sort algorithm.

Quicksort Algorithm:-
 Quicksort is a sorting algorithm based on the divide
and conquer approach where
 An array is divided into subarray by selecting a pivot
element (element selected from the array).
 While dividing the array, the pivot element should be
positioned in such a way that elements less than pivot
are kept on the left side and elements greater than
pivot are on the right side of the pivot.
 The left and right subarrays are also divided using the
same approach. This process continues until each
subarray contains a single element.
 At this point, elements are already sorted. Finally,
elements are combined to form a sorted array.
Program :-
#include <stdio.h>
void swap(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}

int partition(int array[], int low, int high) {


int pivot = array[high];
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
int i = (low - 1);
for (int j = low; j < high; j++) {
if (array[j] <= pivot) {
i++;
swap(&array[i], &array[j]);
}
}
swap(&array[i + 1], &array[high]);
return (i + 1);
}

void quick Sort(int array[], int low, int high) {


if (low < high) {
int pi = partition(array, low, high);
quickSort(array, low, pi - 1);
quickSort(array, pi + 1, high);
}
}
void printArray(int array[], int size) {
for (int i = 0; i < size; ++i) {
printf("%d ", array[i]);
}
printf("\n");
}

int main() {
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
int data[] = {8, 7, 2, 1, 0, 9, 6};
int n = sizeof(data) / sizeof(data[0]);
printf("Unsorted Array\n");
printArray(data, n);
quick Sort(data, 0, n - 1);
printf("Sorted array in ascending order: \n");
printArray(data, n);
}

OUT PUT:-
Unsorted Array
8 7 2 1 0 9 6
Sorted array in ascending order:
0 1 2 6 7 8 9

EXPERIMENT NO .6(B)

AIM OF THE EXPERIME:-

6(b)Write a program on merge sort algorithm. Take


different input instances for both the algorithm and show
the running time
Merge Sort Algorithm;-
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
Merge Sort is one of the most popular sorting algorithms
that is based on the principle of Divide and Conquer
Algorithm.
Here, a problem is divided into multiple sub-problems.
Each sub-problem is solved individually. Finally, sub-
problems are combined to form the final solution.

Program:-
#include <stdio.h>
#include <stdlib.h>
void merge(int arr[], int l, int m, int r)
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
int L[n1], R[n2];
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];

i = 0;
j = 0;
k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
}
else {
arr[k] = R[j];
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
j++;
}
k++;
}

while (i < n1) {


arr[k] = L[i];
i++;
k++;
}

while (j < n2) {


arr[k] = R[j];
j++;
k++;
}
}

void mergeSort(int arr[], int l, int r)


{
if (l < r) {
int m = l + (r - l) / 2;
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);

merge(arr, l, m, r);
}
}

void printArray(int A[], int size)


{
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
int i;
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
}

int main()
{
int arr[] = { 12, 11, 13, 5, 6, 7 };
int arr_size = sizeof(arr) / sizeof(arr[0]);

printf("Given array is \n");


printArray(arr, arr_size);

mergeSort(arr, 0, arr_size - 1);

printf("\nSorted array is \n");


printArray(arr, arr_size);
return 0;
}

OUT PUT:-

Given array is
12 11 13 5 6 7

Sorted array is
5 6 7 11 12 13

 Go TO NEXT PAGE:- EXP 7


DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD

EXPERIMENT NO .7

AIM OF THE EXPERIME:-


Implement Strassen’s matrix multiplication algorithm.

Strassen’s Matrix Multiplication Algorithm:-

In this context, using Strassen’s Matrix multiplication


algorithm, the time consumption can be improved a little
bit.
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD

Strassen’s Matrix multiplication can be performed only


on square matrices where n is a power of 2. Order of
both of the matrices are n × n.

Divide X, Y and Z into four (n/2)×(n/2) matrices as


represented below −

Z=[IKJL]
X=[ACBD]
and Y=[EGFH]

Using Strassen’s Algorithm compute the following −

M1:=(A+C)×(E+F)
M2:=(B+D)×(G+H)
M3:=(A−D)×(E+H)
M4:=A×(F−H)
M5:=(C+D)×(E)
M6:=(A+B)×(H)
M7:=D×(G−E)
Then,

I:=M2+M3−M6−M7
J:=M4+M6
K:=M5+M7
L:=M1−M3−M4−M5
Analysis
T(n)={c7xT(n2)+dxn2ifn=1otherwisewherecanddarecons
tants
Using this recurrence relation, we get T(n)=O(nlog7)
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
Hence, the complexity of Strassen’s matrix
multiplication algorithm is O(nlog7)
.
Program:-
#include<stdio.h>
int main(){
int z[2][2];
int i, j;
int m1, m2, m3, m4 , m5, m6, m7;
int x[2][2] = {
{12, 34},
{22, 10}
};
int y[2][2] = {
{3, 4},
{2, 1}
};
printf("The first matrix is: ");
for(i = 0; i < 2; i++) {
printf("\n");
for(j = 0; j < 2; j++)
printf("%d\t", x[i][j]);
}
printf("\nThe second matrix is: ");
for(i = 0; i < 2; i++) {
printf("\n");
for(j = 0; j < 2; j++)
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
printf("%d\t", y[i][j]);
}
m1= (x[0][0] + x[1][1]) * (y[0][0] + y[1]
[1]);
m2= (x[1][0] + x[1][1]) * y[0][0];
m3= x[0][0] * (y[0][1] - y[1][1]);
m4= x[1][1] * (y[1][0] - y[0][0]);
m5= (x[0][0] + x[0][1]) * y[1][1];
m6= (x[1][0] - x[0][0]) * (y[0][0]+y[0][1]);
m7= (x[0][1] - x[1][1]) * (y[1][0]+y[1][1]);
z[0][0] = m1 + m4- m5 + m7;
z[0][1] = m3 + m5;
z[1][0] = m2 + m4;
z[1][1] = m1 - m2 + m3 + m6;
printf("\nProduct achieved using Strassen's
algorithm: ");
for(i = 0; i < 2 ; i++) {
printf("\n");
for(j = 0; j < 2; j++)
printf("%d\t", z[i][j]);
}
return 0;
}
OUTPUT:-
The first matrix is:
12 34
22 10
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
The second matrix is:
3 4
2 1
Product achieved using Strassen's algorithm:
104 82
86 98

EXPERIMENT NO .8

AIM OF THE EXPERIME:-


Write down a program to find out a solution for 0 / 1 Knapsack problem.

Algorithm:-
The maximum value obtained from ‘N’ items is the
max of the following two values.
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
Case 1 (include the Nth item): Value of the Nth
item plus maximum value obtained by remaining
N-1 items and remaining weight i.e. (W-weight of
the Nth item).
Case 2 (exclude the Nth item): Maximum value
obtained by N-1 items and W weight.
If the weight of the ‘Nth‘ item is greater than ‘W’,
then the Nth item cannot be included and Case 2 is
the only possibility.
Program:-
#include <stdio.h>
int max(int a, int b) { return (a > b) ? a : b; }
int knapSack(int W, int wt[], int val[], int n)
{
if (n == 0 || W == 0)
return 0;
if (wt[n - 1] > W)
return knapSack(W, wt, val, n - 1);
else
return max(
val[n - 1]
+ knapSack(W - wt[n - 1], wt, val, n - 1),
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
knapSack(W, wt, val, n - 1));
}
int main()
{
int profit[] = { 60, 100, 120 };
int weight[] = { 10, 20, 30 };
int W = 50;
int n = sizeof(profit) / sizeof(profit[0]);
printf("%d", knapSack(W, weight, profit, n));
return 0;
}
Output
220

EXPERIMENT NO .9

AIM OF THE EXPERIME:-


Using dynamic programming implement LCS.
Algorithm:-
X and Y be two given sequences
Initialize a table LCS of dimension X.length * Y.length
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
X.label = X
Y.label = Y
LCS[0][] = 0
LCS[][0] = 0
Start from LCS[1][1]
Compare X[i] and Y[j]
If X[i] = Y[j]
LCS[i][j] = 1 + LCS[i-1, j-1]
Point an arrow to LCS[i][j]
Else
LCS[i][j] = max(LCS[i-1][j], LCS[i][j-1])
Point an arrow to max(LCS[i-1][j], LCS[i][j-1])

PROGRAM;-
#include <stdio.h>
#include <string.h>

int i, j, m, n, LCS_table[20][20];
char S1[20] = "ACADB", S2[20] = "CBDA", b[20][20];

void lcsAlgo() {
m = strlen(S1);
n = strlen(S2);

for (i = 0; i <= m; i++)


LCS_table[i][0] = 0;
for (i = 0; i <= n; i++)
LCS_table[0][i] = 0;

for (i = 1; i <= m; i++)


for (j = 1; j <= n; j++) {
if (S1[i - 1] == S2[j - 1]) {
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
LCS_table[i][j] = LCS_table[i - 1][j - 1] + 1;
} else if (LCS_table[i - 1][j] >= LCS_table[i][j - 1]) {
LCS_table[i][j] = LCS_table[i - 1][j];
} else {
LCS_table[i][j] = LCS_table[i][j - 1];
}
}

int index = LCS_table[m][n];


char lcsAlgo[index + 1];
lcsAlgo[index] = '\0';

int i = m, j = n;
while (i > 0 && j > 0) {
if (S1[i - 1] == S2[j - 1]) {
lcsAlgo[index - 1] = S1[i - 1];
i--;
j--;
index--;
}

else if (LCS_table[i - 1][j] > LCS_table[i][j - 1])


i--;
else
j--;
}

printf("S1 : %s \nS2 : %s \n", S1, S2);


printf("LCS: %s", lcsAlgo);
}

int main() {
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
lcsAlgo();
printf("\n");
}

OUTPUT:-

S1 : ACADB
S2 : CBDA
LCS: CB

EXPERIMENT NO .10(A)

AIM OF THE EXPERIME:-


10. (a) Find out the solution to the N-Queen problem.

ALGORITHM:-

Start in the leftmost column


DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
If all queens are placed return true
Try all rows in the current column. Do the following for
every row.
If the queen can be placed safely in this row
Then mark this [row, column] as part of the solution and
recursively check if placing queen here leads to a
solution.
If placing the queen in [row, column] leads to a solution
then return true.
If placing queen doesn’t lead to a solution then unmark
this [row, column] then backtrack and try other rows.
If all rows have been tried and valid solution is not found
return false to trigger backtracking.

PROGRAM:-
#define N 4
#include <stdbool.h>
#include <stdio.h>

void printSolution(int board[N][N])


{
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if(board[i][j])
printf("Q ");
else
printf(". ");
}
printf("\n");
}
}
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
bool isSafe(int board[N][N], int row, int col)
{
int i, j;

for (i = 0; i < col; i++)


if (board[row][i])
return false;
for (i = row, j = col; i >= 0 && j >= 0; i--, j--)
if (board[i][j])
return false;

for (i = row, j = col; j >= 0 && i < N; i++, j--)


if (board[i][j])
return false;

return true;
}

bool solveNQUtil(int board[N][N], int col)


{
if (col >= N)
return true;
for (int i = 0; i < N; i++) {
if (isSafe(board, i, col)) {
board[i][col] = 1;

if (solveNQUtil(board, col + 1))


return true;
board[i][col] = 0; // BACKTRACK
}
}
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD

return false;
}

bool solveNQ()
{
int board[N][N] = { { 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 } };

if (solveNQUtil(board, 0) == false) {
printf("Solution does not exist");
return false;
}

printSolution(board);
return true;
}

int main()
{
solveNQ();
return 0;
}

OUTPUT;-
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
..Q.
Q...
...Q
.Q..

EXPERIMENT NO .10(B)

AIM OF THE EXPERIME:

(b)Implement back tracking using game trees.

ALGORITHM:-
Backtrack(x)
if x is not a solution
return false
if x is a new solution
add to list of solutions
backtrack(expand x)
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD

PROGRAM:-
class NQueens:
def __init__(self, n):
self.n = n
self.board = [['.'] * n for _ in range(n)]
self.solutions = []

def is_safe(self, row, col):


for i in range(self.n):
if self.board[i][col] == 'Q' or
self.board[row][i] == 'Q':
return False
if 0 <= row - i < self.n and 0 <= col - i
< self.n and self.board[row - i][col - i] == 'Q':
return False
if 0 <= row - i < self.n and 0 <= col + i
< self.n and self.board[row - i][col + i] == 'Q':
return False
return True

def solve(self, row):


if row == self.n:
self.solutions.append([''.join(row) for
row in self.board])
return
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD
for col in range(self.n):
if self.is_safe(row, col):
self.board[row][col] = 'Q'
self.solve(row + 1)
self.board[row][col] = '.'

def find_all_solutions(self):
self.solve(0)
return self.solutions

# Example usage:
n_queens = NQueens(4)
solutions = n_queens.find_all_solutions()
for i, solution in enumerate(solutions, start=1):
print(f"Solution {i}:")
for row in solution:
print(row)
print()

OUT PUT:-
Solution 1:
.Q..
...Q
Q...
..Q.
DESIGN AND ANALYSIS OF ALGORITHM
LAB RECORD

Solution 2:
..Q.
Q...
...Q
.Q..

ENDDDDDDDDDDDDDDDDDDDDDDD

You might also like