Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
18 views29 pages

DAA PF SIMRA 48 Final

The document discusses implementing various sorting algorithms like insertion sort, merge sort, heap sort, and randomized quick sort. Code snippets are provided to implement each algorithm along with reporting the number of comparisons. Best, worst and average case analyses are presented for different input arrays.

Uploaded by

Simi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views29 pages

DAA PF SIMRA 48 Final

The document discusses implementing various sorting algorithms like insertion sort, merge sort, heap sort, and randomized quick sort. Code snippets are provided to implement each algorithm along with reporting the number of comparisons. Best, worst and average case analyses are presented for different input arrays.

Uploaded by

Simi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

INDRAPRASTHA COLLEGE FOR WOMEN

DEPARTMENT OF COMPUTER SCIENCE

PRACTICAL FILE

Design and analysis of


Algorithm

SUBMITTED BY - SIMRAN VISHISHT


ROLL NO - 21/CS/48
SEMESTER - FOUR TH
QUESTIONS:
1. Implement Insertion Sort (The program should report the number of comparisons)
2. ii. Implement Merge Sort (The program should report the number of comparisons)
iii. Implement Bubble, Selection Sort (The program should report the number of
comparisons)

#include <iostream>
#include <cstring>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
int comp_merge = 0;
void Insertion_sort(int arr[], int size);
void Bubble_sort(int arr[], int size);
void Selection_sort(int arr[], int size);
int Merge_sort(int arr[], int l, int r);
void merge(int arr[], int l, int m, int r);
int main()
{
char ans;
do
{
int size;
cout << "Enter the size of array (begining from 500)" << endl;
cin >> size;
int arr[size], i;
cout << "------------------------------------" << endl;
cout << "1.BEST CASE" << endl;
cout << "2.WORST CASE" << endl;
cout << "3.AVERAGE CASE" << endl;
cout << "4.EXIT" << endl;
cout << "Enter your choice" << endl;
int ch, c;
cin >> c;
switch (c)
{
case 1:
{
cout << "------------------------------------" << endl;
cout << "1.Insertion sort" << endl;
cout << "2.Bubble sort" << endl;
cout << "3.Selection sort" << endl;
cout << "4.Merge sort" << endl;
cout << "Enter your choice" << endl;
cin >> ch;
arr[0] = rand() % size + 1;
for (i = 1; i < size; i++)
arr[i] = arr[i - 1] + 5;
switch (ch)
{
case 1:
Insertion_sort(arr, size);
break;
case 2:
Bubble_sort(arr, size);
break;
case 3:
Selection_sort(arr, size);
break;
case 4:
{
Merge_sort(arr, 0, size - 1);
cout << "Number of comparisons " << comp_merge << endl;
break;
}
}
break;
}
case 2:
{
cout << "------------------------------------" << endl;
cout << "1.Insertion sort" << endl;
cout << "2.Bubble sort" << endl;
cout << "3.Selection sort" << endl;
cout << "4.Merge sort" << endl;
cout << "Enter your choice" << endl;
cin >> ch;
arr[0] = rand() % size + 1;
for (i = 0; i < size; i++)
arr[i] = arr[i - 1] - 4;
switch (ch)
{
case 1:
Insertion_sort(arr, size);
break;
case 2:
Bubble_sort(arr, size);
break;
case 3:
Selection_sort(arr, size);
break;
case 4:
{
Merge_sort(arr, 0, size - 1);
cout << "Number of comparisons " << comp_merge << endl;
break;
}
}
break;
}
case 3:
{
cout << "------------------------------------" << endl;
cout << "1.Insertion sort" << endl;
cout << "2.Bubble sort" << endl;
cout << "3.Selection sort" << endl;
cout << "4.Merge sort" << endl;
cout << "Enter your choice" << endl;
cin >> ch;
for (i = 0; i < size; i++)
arr[i] = rand() % size + 1;
switch (ch)
{
case 1:
Insertion_sort(arr, size);
break;
case 2:
Bubble_sort(arr, size);
break;
case 3:
Selection_sort(arr, size);
break;
case 4:
{
Merge_sort(arr, 0, size - 1);
cout << "Number of comparisons " << comp_merge << endl;
break;
}
}
break;
}
case 4:
{
cout << "THANK YOU" << endl;
exit(0);
}
default:
cout << "WRONG CHOICE" << endl;
}
cout << "Sorted array is" << endl;
for (i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
cout << "Do you want to continue (Y/N)" << endl;
cin >> ans;
} while (ans != 'N');
return 0;
}
void Insertion_sort(int arr[], int size)
{
int i, j, key, comp = 0;
for (i = 1; i < size; i++)
{
key = arr[i];
for (j = i - 1; j >= 0 && arr[j] > key; j--)
{
arr[j + 1] = arr[j];
comp++;
}
comp++;
arr[j + 1] = key;
}
cout << "Number of comparisons " << comp << endl;
}
void Bubble_sort(int arr[], int size)
{
int i, j, temp, comp = 0, flag = 0;
for (i = 0; i < size && flag == 0; i++)
{
flag = 1;
for (j = 0; j < size - i - 1; j++)
{
comp++;
if (arr[j] > arr[j + 1])
{
flag = 0;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
cout << "Number of comparisons " << comp << endl;
}
void Selection_sort(int arr[], int size)
{
int i, j, index, min, comp = 0;
for (i = 0; i < size - 1; i++)
{
min = arr[i];
index = i;
for (j = i + 1; j < size; j++)
{
comp++;
if (arr[j] < min)
{
min = arr[j];
index = j;
}
}
arr[index] = arr[i];
arr[i] = min;
}
cout << "Number of comparisons " << comp << endl;
}
int Merge_sort(int arr[], int l, int r)
{
if (l >= r)
return 0;
int m = (l + (r - 1)) / 2;
Merge_sort(arr, l, m);
Merge_sort(arr, m + 1, r);
merge(arr, l, m, r);
}
void merge(int arr[], int l, int m, int r)
{
int n1 = m - l + 1;
int n2 = r - m;
int a1[n1], a2[n2];
for (int i = 0; i < n1; i++)
a1[i] = arr[l + i];
for (int j = 0; j < n2; j++)
a2[j] = arr[m + 1 + j];
int i = 0, j = 0;
int k = l;
while (i < n1 && j < n2)
{
if (a1[i] <= a2[j])
{
arr[k] = a1[i];
i++;
}
else
{
arr[k] = a2[j];
j++;
}
comp_merge++;
k++;
}
while (i < n1)
{
arr[k] = a1[i];
} i++;
k++;
}
while (j < n2)
{
arr[k] = a2[j];
j++;
k++;
}
}

OUTPUT:
Insertion sort
GRAPH:
Merge sort-
Graph-
2. Implement Heap Sort (The program should report the number of comparisons)
CODE-
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
void heapsort(int arr[], int size, int heap_size);
void build_max_heap(int arr[], int n, int heap_size);
void max_heapify(int arr[], int n, int heap_size);
int comp = 0;
int main()
{
cout << "enter the size of array" << endl;
int size;
cin >> size;
cout << "enter the elements" << endl;
int i, arr[size], heap_size = size - 1;
arr[0] = rand() % size + 1;
cout << "BEST CASE" << endl;
for (i = 0; i < size; i++)
arr[i] = arr[i - 1] + 5;
heapsort(arr, size, heap_size);
cout << "sorted array" << endl;
for (i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
cout << "Number of comparisons are " << comp << endl;
cout << "worst CASE" << endl;
for (i = 1; i < size; i++)
arr[i] = arr[i - 1] - 2;
heapsort(arr, size, heap_size);
cout << "sorted array" << endl;
for (i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
cout << "Number of comparisons are " << comp << endl;
cout << "AVERAGE CASE" << endl;
for (i = 0; i < size; i++)
arr[i] = rand() % size + 1;
heapsort(arr, size, heap_size);
cout << "sorted array" << endl;
for (i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
cout << "Number of comparisons are " << comp << endl;
return 4;
}
void heapsort(int arr[], int size, int heap_size)
{
build_max_heap(arr, size, heap_size);
int i, temp;
for (i = size - 1; i >= 0; i--)
{
temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heap_size -= 1;
max_heapify(arr, 0, heap_size);
}
}
void build_max_heap(int arr[], int n, int heap_size)
{
int i;
for (i = n / 2 - 1; i >= 0; i--)
max_heapify(arr, i, heap_size);
}
void max_heapify(int arr[], int n, int heap_size)
{
int largest, i = n, temp;
int l = 2 * i + 1;
int r = 2 * i + 2;
if (l <= heap_size && arr[l] > arr[i])
largest = l;
else
largest = i;
comp++;
if (r <= heap_size && arr[r] > arr[largest])
largest = r;
comp++;
if (largest != i)
{
temp = arr[i];
arr[i] = arr[largest];
arr[largest] = temp;
max_heapify(arr, largest, heap_size);
}
}

OUTPUT-
GRAPH-
Q 3. Implement Randomized Quick sort (The program should report the number of
comparisons)
CODE-
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
void quick_sort(int arr[], int p, int r);
int partition(int arr[], int p, int r);
int comp = 0;
int main()
{
cout << "enter the size of array" << endl;
int size;
cin >> size;
int i, arr[size];
arr[0] = rand() % size + 1;
cout << "best case" << endl;
for (i = 1; i < size; i++)
arr[i] = arr[i - 1] + 5;
quick_sort(arr, 0, size - 1);
cout << "sorted array" << endl;
for (i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
cout << "Number of comparisons " << comp << endl;
cout << "worst case" << endl;
for (i = 1; i < size; i++)
arr[i] = arr[i - 1] - 2;
quick_sort(arr, 0, size - 1);
cout << "sorted array" << endl;
for (i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
cout << "Number of comparisons " << comp << endl;
cout << "average case" << endl;
for (i = 0; i < size; i++)
arr[i] = rand() % size + 1;
quick_sort(arr, 0, size - 1);
cout << "sorted array" << endl;
for (i = 0; i < size; i++)
cout << arr[i] << " ";
cout << "Number of comparisons " << comp << endl;
return 3;
}
void quick_sort(int arr[], int p, int r)
{
if (p < r)
{
int q = partition(arr, p, r);
quick_sort(arr, p, q - 1);
quick_sort(arr, q + 1, r);
}
}
int partition(int arr[], int p, int r)
{
int x = arr[r];
int i = p - 1, j;
int temp;
for (j = p; j <= r - 1; j++)
{
if (arr[j] <= x)
{
comp++;
i = i + 1;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
temp = arr[i + 1];
arr[i + 1] = arr[r];
arr[r] = temp;
return i + 1;
}

OUTPUT-
GRAPH-

Q 4. Implement Breadth-First Search in a graph


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
class graph
{
int num_vertices;
list<int> *adjlist;
int tree[10][10];

public:
graph(int V)
{
num_vertices = V;
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
tree[i][j] = -1;
adjlist = new list<int>[V];
}
void addedge(int u, int w)
{
adjlist[u].push_back(w);
}
void printgraph()
{
int i;
for (i = 0; i < num_vertices; i++)
{
cout << i;
list<int>::iterator it;
for (it = adjlist[i].begin(); it != adjlist[i].end(); it++)
{
cout << "->" << (*it) << " ";
}
cout << endl;
}
}
void bfs(int s)
{
bool *discover = new bool[num_vertices];
for (int i = 0; i < num_vertices; i++)
discover[i] = false;
list<int> queue;
discover[s] = true;
queue.push_back(s);
list<int>::iterator i;
int t = 0;
while (!queue.empty())
{
int j = 0;
s = queue.front();
queue.pop_front();
for (i = adjlist[s].begin(); i != adjlist[s].end(); i++)
{
if (!discover[*i])
{
discover[*i] = true;
queue.push_back(*i);
tree[t][j++] = s;
tree[t][j] = (*i);
j++;
}
}
t++;
}
}
void display()
{
int i = 0, j = 0;
while (tree[i][j] != -1)
{
while (tree[i][j] != -1)
{
cout << tree[i][j] << ",";
j++;
}
cout << endl;
j = 0;
i++;
}
}
};
int main()
{
graph g(4);
g.addedge(0, 1);
g.addedge(3, 1);
g.addedge(2, 3);
g.addedge(0, 2);
g.addedge(3, 0);
cout << "VALUES IN THE GRAPH" << endl;
g.printgraph();
g.bfs(2);
cout << endl;
cout << "IN BREADTH FIRST SEARCH TRAVERSAL EDGES ARE IN BETWEEN" << endl;
g.display();
return 8;
}

OUTPUT-
Q.5 Implement Depth-First search in a graph.
CODE-
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
class graph
{
int V;
list<int> *adj;
int tree[10][10];

public:
graph(int v)
{
V = v;
adj = new list<int>[v];
}
void addedge(int u, int w)
{
adj[u].push_back(w);
}
void printgraph()
{
int i;
for (i = 0; i < V; i++)
{
cout << i;
list<int>::iterator it;
for (it = adj[i].begin(); it != adj[i].end(); it++)
{
cout << "->" << (*it) << " ";
}
cout << endl;
}
}
void dfs(int s)
{
int e1;
bool explored[V];
int i, parent[V];
for (i = 0; i < V; i++)
explored[i] = false;
for (i = 0; i < V; i++)
parent[i] = -1;
list<int> stack;
stack.push_back(s);
list<int>::iterator it;
i = 0;
while (!stack.empty())
{
int j = 0;
s = stack.front();
stack.pop_front();
if (!explored[s])
{
explored[s] = true;
e1 = parent[s];
if (e1 != -1)
{
tree[i][j] = s;
j++;
tree[i][j] = e1;
i++;
j++;
}
for (it = adj[s].begin(); it != adj[s].end(); it++)
{
stack.push_back(*it);
parent[(*it)] = s;
}
}
}
}
void display()
{
int i;
for (i = 0; i < V - 1; i++)
{
for (int j = 0; j < 2; j++)
cout << tree[i][j] << " ";
cout << endl;
}
}
};
int main()
{
graph g(4);
g.addedge(0, 1);
g.addedge(1, 2);
g.addedge(2, 3);
g.addedge(1, 3);
g.addedge(3, 0);
cout << "VALUES IN THE GRAPH" << endl;
g.printgraph();
g.dfs(2);
cout << "IN DEPTH FIRST SEARCH TRAVERSAL EDGES ARE BETWEEN THESE NODES" <<
endl;
g.display();
return 8;
}

OUTPUT-
Q 6. Write a program to solve the weighted interval scheduling
problem

CODE-
#include <iostream>
using namespace std;
int p[10], m[10], v[10];
void sort(int detail[][3], int n);
int M_compute(int j);
int find_solution(int j);
int main()
{
cout << "Enter the number of intervals" << endl;
int n;
cin >> n;
int detail[n][3];
cout << "Enter the start, finish and weight of intervals" << endl;
int i, j;
for (i = 0; i < n; i++)
m[i] = -1;
for (i = 0; i < n; i++)
{
cout << "job " << i << " ";
for (j = 0; j < 3; j++)
{
cin >> detail[i][j];
}
cout << endl;
}
sort(detail, n);
for (i = 0; i < n; i++)
{
for (j = 0; j < 3; j++)
{
cout << detail[i][j] << " ";
}
cout << endl;
}
v[0] = detail[0][2];
int flag = 1;
for (i = n - 1; i >= 0; i--)
{
flag = 1;
v[i] = detail[i][2];
for (j = i - 1; j >= 0; j--)
{
if (detail[i][0] >= detail[j][1])
{
p[i] = j;
flag = 0;
break;
}
}
if (flag == 1)
p[i] = -1;
}
cout << "The optimal value " << M_compute(3) << endl;
cout << "intervals in the optimum solution" << endl;
find_solution(3);
return 0;
}
void sort(int detail[][3], int n)
{
int i, j, min, temp, temp1, index, k = 0;
for (i = 0; i < n - 1; i++)
{
min = detail[i][1];
index = i;
for (j = i + 1; j < n; j++)
{
if (min > detail[j][1])
{
min = detail[j][1];
index = j;
}
}
detail[index][1] = detail[i][1];
detail[i][1] = min;
temp = detail[index][2];
detail[index][2] = detail[i][2];
detail[i][2] = temp;
temp1 = detail[index][0];
detail[index][0] = detail[i][0];
detail[i][0] = temp1;
}
}
int M_compute(int j)
{
if (j == -1)
return 0;
else if (m[j] != -1)
return m[j];
else
{
m[j] = max(v[j] + M_compute(p[j]), M_compute(j - 1));
return m[j];
}
}
int find_solution(int j)
{
if (j == -1)
return 0;
else if (v[j] + m[p[j]] >= m[j - 1])
{
cout << j << " ";
return find_solution(p[j]);
}
else
cout << j - 1 << endl;
return find_solution(j - 1);
}

OUTPUT-

Q 7. Write a program to solve the 0-1 knapsack problem.


CODE-
#include <iostream>
using namespace std;
int knap_sack(int val[], int wei[], int cap, int num);
int main()
{
cout << "Enter the number of items" << endl;
int num;
cin >> num;
cout << "Enter the value for each item" << endl;
int val[num], i, wei[num];
for (i = 0; i < num; i++)
cin >> val[i];
cout << "Enter the weight for each item respectively" << endl;
for (i = 0; i < num; i++)
cin >> wei[i];
cout << "Enter the KNAPSACK limit" << endl;
int maxi;
cin >> maxi;
cout << "maximum value" << endl;
cout << knap_sack(val, wei, maxi, num);
return 0;
}
int knap_sack(int val[], int wei[], int cap, int num)
{
int opt[num + 1][cap + 1], i, j;
for (i = 0; i < cap + 1; i++)
{
opt[0][i] = 0;
}
for (i = 0; i < num + 1; i++)
{
opt[i][0] = 0;
}
for (i = 1; i < num + 1; i++)
{
for (j = 0; j < cap + 1; j++)
{
if (wei[i - 1] < j)
opt[i][j] = max(opt[i - 1][j], val[i] + opt[i - 1][j - wei[i -
1]]);
else
opt[i][j] = opt[i - 1][j];
}
}
return opt[num][cap];
}
OUTPUT-
Q 8. Implement Radix Sort’
CODE-
#include <iostream>
using namespace std;
int getMax(int arr[], int n)
{
int mx = arr[0];
for (int i = 1; i < n; i++)
if (arr[i] > mx)
mx = arr[i];
return mx;
}
void countSort(int arr[], int n, int exp)
{
int output[n];
int i, count[10] = {0};
for (i = 0; i < n; i++)
count[(arr[i] / exp) % 10]++;
for (i = 1; i < 10; i++)
count[i] += count[i - 1];
for (i = n - 1; i >= 0; i--)
{
output[count[(arr[i] / exp) % 10] - 1] = arr[i];
count[(arr[i] / exp) % 10]--;
}
for (i = 0; i < n; i++)
arr[i] = output[i];
}
void radixsort(int arr[], int n)
{
int m = getMax(arr, n);
for (int exp = 1; m / exp > 0; exp *= 10)
countSort(arr, n, exp);
}
void print(int arr[], int n)
{
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
}
int main()
{
int arr[] = {111, 25, 60, 150, 1111, 74, 1, 45};
int n = sizeof(arr) / sizeof(arr[0]);
radixsort(arr, n);
print(arr, n);
return 0;
}

OUTPUT-
Q 9.Implement prim’s algorithm
CODE-
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define V 5
int minKey(int key[], bool mstSet[])
{
int min = INT_MAX, min_index;
for (int v = 0; v < V; v++)
if (mstSet[v] == false && key[v] < min)
min = key[v], min_index = v;
return min_index;
}
void printMST(int parent[], int graph[V][V])
{
cout << "Edge \tWeight\n";
for (int i = 1; i < V; i++)
cout << parent[i] << " - " << i << " \t" << graph[i][parent[i]] << "
\n";
}
void primMST(int graph[V][V])
{
int parent[V];
int key[V];
bool mstSet[V];
for (int i = 0; i < V; i++)
key[i] = INT_MAX, mstSet[i] = false;
key[0] = 0;
parent[0] = -1;
for (int count = 0; count < V - 1; count++)
{
int u = minKey(key, mstSet);
mstSet[u] = true;
for (int v = 0; v < V; v++)
if (graph[u][v] && mstSet[v] == false && graph[u][v] < key[v])
parent[v] = u, key[v] = graph[u][v];
}
// print the constructed MST
printMST(parent, graph);
}
// Driver code
int main()
{
int graph[V][V] = {{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}};
// Print the solution
primMST(graph);
return 0;
}

OUTPUT-

Q 10. Implement randomized-select algorithm.


CODE-
#include <iostream>
using namespace std;
int randomized_parition(int A[], int p, int r)
{
int x = A[r];
int i = p - 1, j;
int temp;
for (j = p; j <= r - 1; j++)
{
if (A[j] <= x)
{
i = i + 1;
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
temp = A[i + 1];
A[i + 1] = A[r];
A[r] = temp;
return i + 1;
}
int randomized_select(int A[], int p, int r, int i)
{
if (p == r)
return A[p];
int q = randomized_parition(A, p, r);
int k = q - p + 1;
if (i == k)
return A[q];
else if (i < k)
return randomized_select(A, p, q - 1, i);
else
return randomized_select(A, q + 1, r, i - k);
}
int main()
{
cout << "enter the size of array" << endl;
int size;
cin >> size;
int A[size], i;
cout << "Enter the number of elements" << endl;
for (i = 0; i < size; i++)
{
cin >> A[i];
}
cout << "Enter the order of statistics" << endl;
int os;
cin >> os;
cout << "Element at given order of statistics is " << randomized_select(A,
0, size - 1, os) << endl;
return 2;
}

OUTPUT-
Q 11. Implement Kruskal’s algorithm.
CODE-
#include <iostream>
using namespace std;
#define V 5
int parent[V];
int find(int i)
{
while (parent[i] != i)
i = parent[i];
return i;
}
void union1(int i, int j)
{
int a = find(i);
int b = find(j);
parent[a] = b;
}
void kruskalMST(int cost[][V])
{
int mincost = 0;
for (int i = 0; i < V; i++)
parent[i] = i;
int edge_count = 0;
while (edge_count < V - 1)
{
int min = INT_MAX, a = -1, b = -1;
for (int i = 0; i < V; i++)
{
for (int j = 0; j < V; j++)
{
if (find(i) != find(j) && cost[i][j] < min)
{
min = cost[i][j];
a = i;
b = j;
}
}
}
union1(a, b);
cout << "Edge" << edge_count++ << "(" << a << "," << b << ") cost : "
<< min << endl;
mincost += min;
}
cout << " Minimum cost=" << mincost << endl;
}
int main()
{
int cost[][V] = {
{INT_MAX, 2, INT_MAX, 6, INT_MAX},
{2, INT_MAX, 3, 8, 5},
{INT_MAX, 3, INT_MAX, INT_MAX, 7},
{6, 8, INT_MAX, INT_MAX, 9},
{INT_MAX, 5, 7, 9, INT_MAX},
};
kruskalMST(cost);
return 0;
}

OUTPUT-

You might also like