You are on page 1of 14

CSE – 2012 Design and Analysis of Algorithms

Name – Puneet Purohit Slot – L49+L50

Reg No.: 20BCE0191 Date - 2/12/21

#include <bits/stdc++.h>

using namespace std;

/*Name - Puneet Purohit

Reg - 20BCE0191

Given a subset we need to check if the given sum can be formed from the values of sunset.

We use dynamic programming approach to solve this. Using tabulation method and bottom-up
approach

to fill the table checking the sum in each step and marking 1 or 0 if sum is possible*/

// Function to check the sum can be obtained from subset values

void subset_sum(int a[], int n, int sum)

// i and j variables for iteration purpose

int i, j;

// Using the tabulation method to store the sum of subsets and check with given input sum.

// The rows have elements of the subset and columns have numbers ranging from 1 to sum+1.

int dp[n + 1][sum + 1];

// Initializing the first row value as 1

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

dp[i][0] = 1;
// Initializing the column row value as 0

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

dp[0][j] = 0;

// Using two for loop for iterating the table, first for loop to iterate the rows and

// second for loop to iterate over the columns.

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

for (j = 1; j <= sum; j++)

// Here, we are checking if the index of column (the numbers ranging from 1 to sum value)

// is lesser then the value of the subset for corresponding row.

if (j < a[i])

// If the subset value is less column value, then inserting the previous row value (0 or 1)

dp[i][j] = dp[i - 1][j];

// If not then performing the logical OR of previous row value with the current element index
value.

// [j-a[i]] where j is the column index and a[i] is the value present in the subset.

// The logical OR operator is denoted with || in c++.

// 0||0=0 ,0||1=1, 1||0=1, 1||1=1

// Inserting the OR reuslt in the table.

else

dp[i][j] = dp[i - 1][j] || dp[i - 1][j - a[i]];

// Our reuslt is stored in the last cell of the table. If the last cell value is 1 then

// subset values can form the sum otherwise not

// Checking in the table if the given sum found then displaying appropriate msg

if (dp[n][sum] == 1)

// If the last cell of the table is 1 then sum can be obtained from values of subset

cout << "Found a subset with given sum" << endl;


// If the last cell of the table is 0 then sum can't be formed.

else

cout << "No subset with given sum" << endl;

int main()

// Initializing the variables

int n, sum;

// Input the size of subset from user

cout << "Enter number of elements in subset : ";

cin >> n;

int a[n];

// Input the values of subset from user

cout << "Enter the values : ";

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

cin >> a[i];

// Input the sum value from user

cout << "Enter the sum to check: ";

cin >> sum;

// Calling the function

auto start=chrono::steady_clock::now();

subset_sum(a, n, sum);

auto end=chrono::steady_clock::now();

auto diff=end-start;

cout<<chrono::duration<double,milli>(diff).count()<<"ms"<<endl;

}
#include <bits/stdc++.h>

using namespace std;

/*Approach - In Karatsuba algorithm we split the numbers to multiply ito digits for

further simplification of multiplication. Here we use binary number (base 2)

Time complexeity is O(n^log(3)) which is less than genral multiplication*/

int getSize(int num) // Function to get size of number

int count = 0;

while (num > 0) // Iterating the number and consecutive division to find its length

// Dividing the number by 10 and then increment the count to calcualte number of digits

count++;

num /= 10;

return count;

int karatsuba(int X, int Y) // Function to calculating multiplication using karatuba mrthod

// Base Case

if (X < 10 && Y < 10) // If length is smaller than 10


return X * Y;

// determine the size of X and Y

int size = max(getSize(X), getSize(Y)); // Calculating the size of number

// Spliting X and Y

int n = (int)ceil(size / 2); // Breaking the digits into two

int p = (int)pow(10, n);

int a = (int)floor(X / p); // Spliting the number into digits

int b = X % p;

int c = (int)floor(Y / p); // Spliting the number into digits

int d = Y % p;

int ac = karatsuba(a, c); /*Recursively spliting the number into futher multiplication*/

int bd = karatsuba(b, d); /*Recursively spliting the number into futher multiplication*/

int e = karatsuba(a + b, c + d) - ac - bd;

// return the equation

return (int)(pow(10 , 2 * n) * ac + pow(10, n) * e + bd);

int main(){

int b1,b2;

cout<<"Enter first number"<<endl; // Input first number from user

cin>>b1;

cout<<"Enter second number"<<endl; // Input second number from user

cin>>b2;

auto start=chrono::steady_clock::now();

// Calling the function to perform multiplication

int ans=karatsuba(b1,b2);

auto end=chrono::steady_clock::now();

auto diff=end-start;
cout<<chrono::duration<double,milli>(diff).count()<<"ms"<<endl;

cout<<"Result : "<<ans<<endl; // Displaying the result

#include<bits\stdc++.h>

using namespace std;

// Maximum number of vertices

#define N 4

/*Name - Puneet Purohit

Reg No.: 20BCE0191*

A rat starts from source and has to reach the destination.

The rat can move only in two directions: forward and down.

In the maze matrix, 0 means the block is a dead end and 1 means the block can be used

in the path from source to destination*/

bool maze_solution(int maze[N][N], int x, int y, int sol[N][N]);

/* A utility function to print solution matrix sol[N][N] */

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


{

// Using two for loop to printing the solution

for (int i = 0; i < N; i++)

for (int j = 0; j < N; j++)

cout<<sol[i][j]<<" ";

cout<<endl;

/* Function to check if don't go outside the maze i.e., we don’t exit the maze */

bool isSafe(int maze[N][N], int x, int y)

// x>=0 and x<N to check the side boundary

// y>=0 and x<N to check the upper boundary

if(x >= 0 && x < N && y >= 0 && y < N && maze[x][y] == 1)

return true;

// If the above constraints fail then we come outside the maze and hence no solution

return false;

/* This function solves the Maze problem using Backtracking. It mainly

uses maze_solution() to solve the problem. It returns false if no

path is possible, otherwise return true and prints the path in the

form of 1s. There can multiple solutions possible. */

bool solveMaze(int maze[N][N])

// Declaring 2d array to store the solution and intitially all vertices are 0

int sol[N][N] = { {0, 0, 0, 0},

{0, 0, 0, 0},

{0, 0, 0, 0},
{0, 0, 0, 0}

};

// If no path possible then print no solution possible

if(maze_solution(maze, 0, 0, sol) == false)

cout<<"Solution doesn't exist";

return false;

// Printing the solution

printSolution(sol);

return true;

/* A Recursive function to generate the maze solution*/

bool maze_solution(int maze[N][N], int x, int y, int sol[N][N])

// Bae condition for recursive if we reach the last row and column of the maze then return

if(x == N-1 && y == N-1)

sol[x][y] = 1;

return true;

// Check if maze[x][y] is valid

if(isSafe(maze, x, y) == true)

// Marking x,y as part of solution path

sol[x][y] = 1;

/* Move forward in x direction so we do x+1 */

if (maze_solution(maze, x+1, y, sol) == true)


return true;

/* If moving in x direction doesn't give solution then

Move down in y direction hence we do y+1 */

if (maze_solution(maze, x, y+1, sol) == true)

return true;

/* If none of the above movements then we backtrack and again try a different

path for maze */

// Again turning solution matrix to 0 for new path and vertex

sol[x][y] = 0;

return false;

// If the maze is not valid then no solution can be generated.

return false;

int main()

// Declaring 2d array to input the maze as graph edges and vertices

int maze[N][N];

cout<<"Enter the adjacency matrix (maze) : "<<endl;

for(int i=0;i<N;i++){

for(int j=0;j<N;j++){

cin>>maze[i][j];

cout<<"Solutions : "<<endl;

auto start=chrono::steady_clock::now();

// Calling the function to get the solution

solveMaze(maze);
auto end=chrono::steady_clock::now();

auto diff=end-start;

cout<<chrono::duration<double,milli>(diff).count()<<"ms"<<endl;

return 0;

#include <bits\stdc++.h>

// Number of vertices in the graph

#define V 5

using namespace std;

/*Name - Puneet Purohit

Reg No.: 20BCE0191

Hamiltonian path is a path, that visits each vertex exactly once,

and the Hamiltonian cycle or circuit is a Hamiltonian path, that there is an edge from the last vertex
to the first vertex.*/

// Declaring a function before to print the solution

void printSolution(int path[]);

// Function to check if vertex v can be added at index position in the

// Hamiltonian cycle. Here the path array has the vertices present in cycle
bool isSafe(int v, bool graph[V][V], int path[], int pos)

/* Check if this vertex is an adjacent vertex of the previously

added vertex. */

if (graph [path[pos-1]][v] == 0)

return false;

/* Check if the vertex has already been included.

This step can be optimized by creating an array of size V */

for (int i = 0; i < pos; i++)

if (path[i] == v)

return false;

return true;

/* Function to calculate the Hamiltonian cycle problem*/

bool hamCycleUtil(bool graph[V][V], int path[], int pos)

/* Base case: If all vertices are included in Hamiltonian Cycle */

if (pos == V)

// And if there is an edge from the last included vertex to the

// first vertex

if (graph[ path[pos-1] ][ path[0] ] == 1)

return true;

else

return false;

// Try different vertices as a next candidate in Hamiltonian Cycle.

// We don't try for 0 as we included 0 as starting point in in

for (int v = 1; v < V; v++)

{
// After processing the vertex checking if we can include it in cycle

if (isSafe(v, graph, path, pos))

// Adding the vertex in cycle

path[pos] = v;

// Checking if corresponding vertex forms a continuous cycle to satisfy

// the hamiltonian cycle property

if (hamCycleUtil (graph, path, pos+1) == true)

return true;

// If the vertex is not included then marking its index as -1

path[pos] = -1;

return false;

/* Solving the Hamiltonian Cycle problem using Backtracking function. */

// Basically we process the vertex then then assuming it as main vertex checking

// If can form a Hamiltonian cycle or not

bool hamCycle(bool graph[V][V])

// Dynamically creating the path array as we before don’t know how many vertices can be there in
cycle

int *path = new int[V];

// Initializing the array to -1

for (int i = 0; i < V; i++)

path[i] = -1;

// The first node of the graph would be added in the array(Hamiltonian cycle)

path[0] = 0;

// If the vertex doesn’t create continuous circuit with other vertices, then

// don't include it in final solution


if (hamCycleUtil(graph, path, 1) == false)

cout<<"\nSolution does not exist"<<endl;

return false;

// Calling the function to print the solution

printSolution(path);

return true;

// A function to print solution, the vertices present in the Hamiltonian cycle

void printSolution(int path[])

cout<<"Following is one Hamiltonian Cycle\n"<<endl;

// The path array consists of the vertices of Hamiltonian cycle

for (int i = 0; i < V; i++)

cout<<path[i]<<" ";

cout<< path[0]<<endl;

int main()

// Declaring a 2d array to store the adjacency matrix

bool graph[V][V];

// Input the adjanceny matrix from the user

cout<<"Enter the adjancency matrix of graph : "<<endl;

for(int i=0;i<V;i++){

for(int j=0;j<V;j++){

cin>>graph[i][j];

}
}

auto start=chrono::steady_clock::now();

// Calling the function to calculate hamiltonian cycle

hamCycle(graph);

auto end=chrono::steady_clock::now();

auto diff=end-start;

cout<<chrono::duration<double,milli>(diff).count()<<"ms"<<endl;

return 0;

You might also like