diff --git a/AKS_Primarility_Test/AKS.dart b/AKS_Primarility_Test/AKS.dart new file mode 100644 index 000000000..aabf1e7c8 --- /dev/null +++ b/AKS_Primarility_Test/AKS.dart @@ -0,0 +1,55 @@ +// Importing required libraries +import 'dart:io'; + +// Function to fill the coefficients array +void coef(int number, List c){ + c[0] = 1; + for (int i = 0; i < number; c[0] = -c[0], i ++){ + c[i + 1] = 1; + for (int j = i; j > 0; j --){ + c[j] = c[j - 1] - c[j]; + } + } +} + +// Function to find the primality of a given number using AKS primality test +bool aks_primality(int number){ + List c = List(100); + coef(number, c); + c[0] ++; + c[number] --; + int i = number; + while ((i --) > 0 && c[i] % number == 0); + return i < 0; +} + +// Driver method of the program +void main(){ + // Input of the number + print("Enter a number for primality test:"); + var input = stdin.readLineSync(); + int number = int.parse(input); + + // Respective output + if (number > 64){ + print("This number is out of scope of this algorithm. This works only till 64"); + return; + } + if (aks_primality(number)){ + print("It is a prime number"); + } + else { + print("It is not a prime number"); + } +} + +/** + * Sample Input and Output + * --------------------------------- + * Enter a number for primality test: + * 37 + * It is a prime number + * Enter a number for primality test: + * 24 + * It is not a prime number + */ diff --git a/AVL_Tree/AVL_Tree.cpp b/AVL_Tree/AVL_Tree.cpp new file mode 100644 index 000000000..3c68347ee --- /dev/null +++ b/AVL_Tree/AVL_Tree.cpp @@ -0,0 +1,202 @@ +#include +using namespace std; + +struct tnode +{ + int data; + tnode * L, * R; + tnode() + { + L = R = NULL; + } +}; + +class AVL +{ + private: + tnode * root; + public: + AVL() { root = NULL; } + tnode * LL(tnode *); + tnode * RR(tnode *); + tnode * LR(tnode *); + tnode * RL(tnode *); + + int height(tnode *); + int MAX(int, int); + + void create(); + tnode * insert(tnode *, int); + void display(); + void inorder(tnode *); + void preorder(tnode *); +}; + +tnode * AVL :: LL(tnode * parent) +{ + tnode * temp; + temp = parent -> L; + parent -> L = temp -> R; + temp -> R = parent; + return temp; +} + +tnode * AVL :: RR(tnode * parent) +{ + tnode * temp; + temp = parent -> R; + parent -> R = temp -> L; + temp -> L = parent; + return temp; +} + +tnode * AVL :: LR(tnode * parent) +{ + parent -> L = RR(parent -> L); + parent = LL(parent); + return parent; +} + +tnode * AVL :: RL(tnode * parent) +{ + parent -> R = LL(parent -> R); + parent = RR(parent); + return parent; +} + +int AVL :: MAX(int a, int b) +{ + if(a > b) + return a; + else + return b; +} + +int AVL :: height(tnode * temp ) +{ + if(temp == NULL) //height of empty node(subtree) + return -1; + + if(temp -> L == NULL and temp -> R == NULL) //height of leaf node + return 0; + + return (1 + MAX( height(temp -> L), height(temp -> R))); +} + +void AVL :: create() +{ + int val; + char ch; + do + { + cout << "Enter Number : "; + cin >> val; + root = insert(root, val); + cout << "Continue : "; + cin >> ch; + }while(ch == 'y'); +} + +tnode * AVL :: insert(tnode * temp, int val) +{ + if(temp == NULL) + { + temp = new tnode; + temp -> data = val; + } + else + { + if(val < temp -> data) + { + temp -> L = insert(temp -> L, val); + if( ( height(temp -> L) - height(temp -> R) == 2 ) ) + { + if(val < temp -> L -> data) + temp = LL(temp); + else + temp = LR(temp); + } + } + else + { + temp -> R = insert(temp -> R, val); + if( ( height(temp -> L) - height(temp -> R)== -2 ) ) + { + if(val > temp -> R -> data) + temp = RR(temp); + else + temp = RL(temp); + } + } + } + return temp; +} + +void AVL :: inorder(tnode * temp) +{ + if(temp != NULL) + { + inorder(temp -> L); + cout << "\n" << temp -> data; + inorder(temp -> R); + } +} + +void AVL :: preorder(tnode * temp) +{ + if(temp != NULL) + { + cout << "\n"< data; + preorder(temp -> L); + preorder(temp -> R); + } +} + +void AVL :: display() +{ + cout << "\n Data in Sorted way : "; + inorder(root); + cout << "\n Preorder : "; + preorder(root); +} + +int main() +{ + AVL t; + t.create(); + t.display(); + cout << endl; + return 0; +} + +/* + Initially putting data in increasing order to form right skewed tree + +Enter Number : 5 +Continue : y +Enter Number : 6 +Continue : y +Enter Number : 7 +Continue : y +Enter Number : 8 +Continue : y +Enter Number : 9 +Continue : y +Enter Number : 10 +Continue : n + + Data in Sorted way : +5 +6 +7 +8 +9 +10 + Preorder : +8 +6 +5 +7 +9 +10 + */ diff --git a/AVL_Tree/AVL_Tree.dart b/AVL_Tree/AVL_Tree.dart new file mode 100644 index 000000000..a0e496ebd --- /dev/null +++ b/AVL_Tree/AVL_Tree.dart @@ -0,0 +1,321 @@ +/** + * ------------------------------------------------ + * AVL Tree implementation in Dart + * ------------------------------------------------ + * + * AVL Tree is a binary search tree that provides insertion, deletion + * and search in O(logn) time in all cases. It is an improvement over BST as a BST can + * take O(n) time when the tree takes a linear shape whereas AVL tree takes O(logn) time + * in all cases as it balances the tree using various rotations. + * + * AVL tree is preferred when insertions and deletions are less frequent and search is a + * more frequent operation. + * + * References - Geeksforgeeks + * + */ + +// Importing required libraries +import 'dart:io'; +import 'dart:math'; + +// Class definition for a tree node. +class Node{ + int value; + Node left , right; + int height; + + Node(value){ + this.value = value; + this.left = null; + this.right = null; + this.height = 1; + } +} + +// Class defintion for an AVL tree. +class AVL_Tree{ + Node root; + + // Utility function to print the tree in preorder traversal. + void print_AVL(Node root){ + if(root != null){ + print(root.value); + print_AVL(root.left); + print_AVL(root.right); + } + } + + // Utility function to find the height of the tree. + int height(Node node){ + if(node == null){ + return 0; + } + return node.height; + } + + // Utility function ro find the balance of the tree. + int balance(Node node){ + if(node == null){ + return 0; + } + return height(node.left) - height(node.right); + } + + //Utility function for right rotation + Node rightRotate(Node root){ + Node z = root , y = root.left , x = y.left; + Node c2 = root.left.right; + y.right = z; + y.left = x; + z.left = c2; + y.height = 1 + max(height(y.left) , height(y.right)); + x.height = 1 + max(height(x.left) , height(x.right)); + z.height = 1 + max(height(z.left) , height(z.right)); + return y; + } + + // Utility function for left rotation + Node leftRotate(Node root){ + Node z = root , y = root.right , x = y.right; + Node c2 = y.left; + y.left = z; + y.right = x; + z.right = c2; + y.height = 1 + max(height(y.left) , height(y.right)); + x.height = 1 + max(height(x.left) , height(x.right)); + z.height = 1 + max(height(z.left) , height(z.right)); + return y; + } + + // Utility function for leftRight rotation + Node leftRightRotate(Node root){ + Node z = root , y = root.left , x = y.right; + Node c1 = z.right , c2 = y.left , c3 = x.left , c4 = x.right; + x.right = z; + x.left = y; + y.left = c2; + y.right = c3; + z.left = c4; + z.right = c1; + y.height = 1 + max(height(y.left) , height(y.right)); + x.height = 1 + max(height(x.left) , height(x.right)); + z.height = 1 + max(height(z.left) , height(z.right)); + return x; + } + + // Utility function for rightLeft rotation + Node rightLeftRotate(Node root){ + Node z = root , y = z.right , x = y.left; + Node c1 = z.left , c2 = x.left , c3 = x.right , c4 = y.right; + x.left = z; + x.right = y; + z.left = c1; + z.right = c2; + y.left = c3; + y.right = c4; + y.height = 1 + max(height(y.left) , height(y.right)); + x.height = 1 + max(height(x.left) , height(x.right)); + z.height = 1 + max(height(z.left) , height(z.right)); + return x; + } + + // Utility function to find the successor of a node. + Node successor(Node root){ + Node temp = root; + while(temp.left != null){ + temp = temp.left; + } + return temp; + } + + // Function to delete a node in the tree. + Node delete_AVL(Node root , int key){ + if(root == null){ + return root; + } + else if(key > root.value){ + root.right = delete_AVL(root.right , key); + } + else if(key < root.value){ + root.left = delete_AVL(root.left , key); + } + else{ + Node temp; + if(root.left == null || root.right == null){ + if(root.left == null && root.right != null){ + temp = root.right; + } + else if(root.right == null && root.left != null){ + temp = root.left; + } + + if(temp == null){ + temp = root; + root = null; + } + else{ + root = temp; + } + } + else{ + Node temp1 = successor(root.right); + root.value = temp1.value; + root.right = delete_AVL(root.right , temp1.value); + } + } + + if(root == null){ + return root; + } + + root.height = 1 + max(height(root.left) , height(root.right)); + int difference = balance(root); + + if(difference > 1 && balance(root.left)>=0){ + return rightRotate(root); + } + + if(difference > 1 && balance(root.left)<0){ + return leftRightRotate(root); + } + + if(difference < -1 && balance(root.right)<=0){ + return leftRotate(root); + } + + if(difference < -1 && balance(root.left)>0){ + return rightLeftRotate(root); + } + + return root; + } + + // Function to insert a value as a node into a tree. + Node insert_AVL(Node root , int key){ + if(root == null){ + return Node(key); + } + else if(key < root.value){ + root.left = insert_AVL(root.left, key); + } + else{ + root.right = insert_AVL(root.right, key); + } + + root.height = 1 + max(height(root.left), height(root.right)); + int difference = balance(root); + + if(difference > 1 && key < root.left.value){ + return rightRotate(root); + } + + if(difference > 1 && key > root.left.value){ + return leftRightRotate(root); + } + + if(difference < -1 && key > root.right.value){ + return leftRotate(root); + } + + if(difference < -1 && key < root.right.value){ + return rightLeftRotate(root); + } + + return root; + } + +} + +void main(){ + + int continued = 1; + AVL_Tree tree = AVL_Tree(); + + while(continued == 1){ + print("Enter 1 to insert , 2 to delete and 3 to print the AVL tree:"); + var input = stdin.readLineSync(); + int operation = int.parse(input); + + if(operation == 1){ + input = stdin.readLineSync(); + int value = int.parse(input); + tree.root = tree.insert_AVL(tree.root , value); + } + else if(operation == 3){ + tree.print_AVL(tree.root); + } + else{ + input = stdin.readLineSync(); + int value = int.parse(input); + tree.root = tree.delete_AVL(tree.root , value); + } + + print("Enter 1 to continue:"); + input = stdin.readLineSync(); + continued = int.parse(input); + } + +} + +/** + * ------------------------------------------------ + * Sample Input and Output + * ------------------------------------------------ + * + * Enter 1 to insert , 2 to delete and 3 to print the AVL tree: + * 1 + * 10 + * Enter 1 to continue: + * 1 + * Enter 1 to insert , 2 to delete and 3 to print the AVL tree: + * 1 + * 20 + * Enter 1 to continue: + * 1 + * Enter 1 to insert , 2 to delete and 3 to print the AVL tree: + * 1 + * 30 + * Enter 1 to continue: + * 1 + * Enter 1 to insert , 2 to delete and 3 to print the AVL tree: + * 1 + * 40 + * Enter 1 to continue: + * 1 + * Enter 1 to insert , 2 to delete and 3 to print the AVL tree: + * 1 + * 50 + * Enter 1 to continue: + * 1 + * Enter 1 to insert , 2 to delete and 3 to print the AVL tree: + * 1 + * 25 + * Enter 1 to continue: + * 1 + * Enter 1 to insert , 2 to delete and 3 to print the AVL tree: + * 3 + * 30 + * 20 + * 10 + * 25 + * 40 + * 50 + * Enter 1 to continue: + * 1 + * Enter 1 to insert , 2 to delete and 3 to print the AVL tree: + * 2 + * 50 + * Enter 1 to continue: + * 1 + * Enter 1 to insert , 2 to delete and 3 to print the AVL tree: + * 3 + * 30 + * 20 + * 10 + * 25 + * 40 + * Enter 1 to continue: + * 0 + * + */ diff --git a/AVL_Tree/avl_tree.php b/AVL_Tree/avl_tree.php new file mode 100644 index 000000000..761a4d828 --- /dev/null +++ b/AVL_Tree/avl_tree.php @@ -0,0 +1,192 @@ +left = NULL; + $this->right = NULL; + $this->depth = 0; + $this->data = NULL; + } + + function balance() + { + $ldepth = $this->left !== NULL + ? $this->left->depth + : 0; + + $rdepth = $this->right !== NULL + ? $this->right->depth + : 0; + + + if( $ldepth > $rdepth + 1 ) + { // LR or LL rotation + $lldepth = $this->left->left !== NULL + ? $this->left->left->depth + : 0; + + $lrdepth = $this->left->right !== NULL + ? $this->left->right->depth + : 0; + + if( $lldepth < $lrdepth ) + { // LR rotation + $this->left->rotateRR(); // consist of a RR rotation of the left child ... + } // ... plus a LL rotation of this node, which happens anyway + + $this->rotateLL(); + } + else if( $ldepth + 1 < $rdepth ) + { // RR or RL rorarion + $rrdepth = $this->right->right !== NULL + ? $this->right->right->depth + : 0; + + $rldepth = $this->right->left !== NULL + ? $this->right->left->depth + : 0; + + if( $rldepth > $rrdepth ) + { // RR rotation + $this->right->rotateLL(); // consist of a LL rotation of the right child ... + } // ... plus a RR rotation of this node, which happens anyway + + $this->rotateRR(); + } + } + + function rotateLL() + { // the left side is too long => rotate from the left (_not_ leftwards) + $data_before =& $this->data; + $right_before =& $this->right; + + $this->data =& $this->left->data; + $this->right =& $this->left; + $this->left =& $this->left->left; + $this->right->left =& $this->right->right; + $this->right->right =& $right_before; + $this->right->data =& $data_before; + $this->right->updateInNewLocation(); + $this->updateInNewLocation(); + } + + function rotateRR() + { // the right side is too long => rotate from the right (_not_ rightwards) + $data_before =& $this->data; + $left_before =& $this->left; + + $this->data =& $this->right->data; + $this->left =& $this->right; + $this->right =& $this->right->right; + $this->left->right =& $this->left->left; + $this->left->left =& $left_before; + $this->left->data =& $data_before; + $this->left->updateInNewLocation(); + $this->updateInNewLocation(); + } + + // -- updateInNewLocation + // may be overloaded by derived class + function updateInNewLocation() + { + $this->getDepthFromChildren(); + } + + + function getDepthFromChildren() + { + $this->depth = $this->data !== NULL ? 1 : 0; + if( $this->left !== NULL ) + $this->depth = $this->left->depth+1; + if( $this->right !== NULL && $this->depth <= $this->right->depth ) + $this->depth = $this->right->depth+1; + } + + // --- debugging functions + + function toString() + { + $s = "\n".$this->toTD(0)."\n"; + $depth = $this->depth - 1; + for( $d = 0; $d < $depth; ++$d ) + { + $s .= ""; + + $s .= $this->left !== NULL + ? $this->left->toTD( $d ) + : ""; + + $s .= $this->right !== NULL + ? $this->right->toTD( $d ) + : ""; + + $s .= "\n"; + } + + $s .= "
\n"; + return $s; + } + + function toTD( $depth ) + { + if( $depth == 0 ) + { + $s = ""; + $s .= $this->data."[".$this->depth."]\n"; + } + else + { + if( $this->left !== NULL ) + { + $s = $this->left->toTD( $depth-1); + } + else + { + $s=""; + } + + if( $this->right !== NULL ) + { + $s .= $this->right->toTD( $depth-1); + } + else + { + if( $this->left !== NULL ) + $s.=""; + } + } + + return $s; + } + + function getNLeafs() + { + if( $this->left !== NULL ) + { + $nleafs = $this->left->getNLeafs(); + + if( $this->right !== NULL ) + $nleafs += $this->right->getNLeafs(); + else + ++$nleafs; // lus one for the right "stump" + } + else + { + if( $this->right !== NULL ) + $nleafs = $this->right->getNLeafs() + 1; // plus one for the left "stump" + else + $nleafs = 1; // this node is a leaf + } + + return $nleafs; + } + +} +?> diff --git a/Aggressive_Cows/Aggressive_Cows.java b/Aggressive_Cows/Aggressive_Cows.java new file mode 100644 index 000000000..1cdb49723 --- /dev/null +++ b/Aggressive_Cows/Aggressive_Cows.java @@ -0,0 +1,76 @@ +import java.util.Arrays; +import java.util.Scanner; + +public class Aggressive_Cows { + + public static void main(String[] args) { + + /* in this problem we have to maximise the minimum distance between the + * cows since minimum distance is being linearly checked we apply + * binary search on minimum distance */ + + Scanner scn = new Scanner(System.in); + int nos = scn.nextInt(); // input for no. of stalls + int noc = scn.nextInt(); // input for no. of cows + + int[] arr = new int[nos]; // storing the position of stalls in an array + + for (int i = 0; i < arr.length; i++) { + arr[i] = scn.nextInt(); + } + + Arrays.sort(arr); // to sort the positions of stalls in ascending order + + int finalAns = 0; + + int lo = 0; + int hi = arr[arr.length - 1] - arr[0]; + + while (lo <= hi) { + + int mid = (lo + hi) / 2; + + if (isItPossible(nos, noc, arr, mid)) { + + finalAns = mid; + lo = mid + 1; + + }else{ + hi = mid - 1; + } + } + + System.out.println(finalAns); + + } + + // function to check if a particular arrangement of cows is possible or not + private static boolean isItPossible(int nos, int noc, int[] arr, int mid) { + + int cowsPlaced = 1; + int lastCowPos = arr[0]; // position at which cow is placed + + for (int i = 1; i < arr.length; i++) { + + if (arr[i] - lastCowPos >= mid) { + cowsPlaced++; + lastCowPos = arr[i]; + + if (cowsPlaced == noc) { + return true; + } + } + } + return false; + } +} + +// SAMPLE INPUT: 5 3 +// 1 +// 2 +// 8 +// 4 +// 9 +// +// Output: +// 3 diff --git a/Aho-Corasick/Aho-Corasick.py b/Aho-Corasick/Aho-Corasick.py new file mode 100644 index 000000000..91f96f169 --- /dev/null +++ b/Aho-Corasick/Aho-Corasick.py @@ -0,0 +1,89 @@ +# AhoNode class +class AhoNode: + def __init__(self): + self.goto = {} + self.out = [] + self.fail = None + + +# creating aho forest +def aho_create_forest(patterns): + root = AhoNode() + + for path in patterns: + node = root + for symbol in path: + node = node.goto.setdefault(symbol, AhoNode()) + node.out.append(path) + return root + + +# Creating aho automata +def aho_create_statemachine(patterns): + root = aho_create_forest(patterns) + queue = [] + for node in root.goto.values(): + queue.append(node) + node.fail = root + + while len(queue) > 0: + rnode = queue.pop(0) + + for key, unode in rnode.goto.items(): + queue.append(unode) + fnode = rnode.fail + while fnode is not None and key not in fnode.goto: + fnode = fnode.fail + unode.fail = fnode.goto[key] if fnode else root + unode.out += unode.fail.out + + return root + + +def aho_find_all(s, root, callback): + node = root + + for i in range(len(s)): + while node is not None and s[i] not in node.goto: + node = node.fail + if node is None: + node = root + continue + node = node.goto[s[i]] + for pattern in node.out: + callback(i - len(pattern) + 1, pattern) + + +# Printing the position of pattern found +def print_pattern(pos, patterns): + print("At pos %s found pattern: %s" % (pos, patterns)) + + +if __name__ == "__main__": + patterns = [] + + # taking inputs + n = int(input("Enter no. of elements :- ")) + for i in range(0, n): + ele = input("Enter element :- ") + patterns.append(ele) + s = input("Enter text :- ") + + root = aho_create_statemachine(patterns) + aho_find_all(s, root, print_pattern) + + +""" +INPUT: +n=6 +patterns = ['a', 'ab', 'abc', 'bc', 'c', 'cba'] +s = "abcba" + +OUTPUT: +At pos 0 found pattern: a +At pos 0 found pattern: ab +At pos 0 found pattern: abc +At pos 1 found pattern: bc +At pos 2 found pattern: c +At pos 2 found pattern: cba +""" \ No newline at end of file diff --git a/Armstrong_Number/Armstrong_Number.cs b/Armstrong_Number/Armstrong_Number.cs new file mode 100644 index 000000000..4ba4bed30 --- /dev/null +++ b/Armstrong_Number/Armstrong_Number.cs @@ -0,0 +1,38 @@ +using System; +public class Armstrong +{ + public static void Main(string[] args) + { + // initialising variables + int n, r, sum = 0, temp; + // asking for user input for the number to be checked + Console.Write("Enter the Number = "); + // storing the number in variable n + n = int.Parse(Console.ReadLine()); + // storing the number in a temporary variable + temp = n; + // running while loop to get the condition number + while(n > 0) + { + r = n % 10; + sum = sum + (r * r * r); + n = n / 10; + } + // checking if the number found using the condition of finding armstrong number is equal to the given number + // printing the statement according to the result of the condition + if(temp == sum) + Console.Write("The Entered Number is an Armstrong Number."); + else + Console.Write("The Entered number is not an Armstrong Number."); + } +} + +/* +Sample inputs and outputs: + +Enter the Number = 153 +The Entered Number is an Armstrong Number. + +Enter the Number = 121 +The Entered number is not an Armstrong Number. +*/ diff --git a/Armstrong_Number/Armstrong_Number.rb b/Armstrong_Number/Armstrong_Number.rb new file mode 100644 index 000000000..fb0e193e6 --- /dev/null +++ b/Armstrong_Number/Armstrong_Number.rb @@ -0,0 +1,44 @@ +# A positive integer of n digits is called an Armstrong number of order n (order is number of digits) if +# abcd... = pow(a,n) + pow(b,n) + pow(c,n) + pow(d,n) + .... + +# To calculate the order of the number +def order(num) + # variable to store of the number + count = 0 + while (num != 0) + count = count + 1 + num = num / 10 + end + return count +end + +# Function to check whether the given number is +# Armstrong number or not +def Armstrong(num) + count = order(num) + temp = num + sum = 0 + boolean = false + while (temp != 0) + d = temp % 10 + sum = sum + d ** count + temp = temp / 10 + end + return num == sum +end + +# Driver Program +num = gets.chomp.to_i +print(Armstrong(num)) + +#True + +#num = 134 +#print(Armstrong(num)) + +#False + +#num = 370 +#print(Armstrong(num)) + +#True diff --git a/Ascii_Subsequences/ASCII_Subsequences.c b/Ascii_Subsequences/ASCII_Subsequences.c new file mode 100644 index 000000000..69d4c5a9e --- /dev/null +++ b/Ascii_Subsequences/ASCII_Subsequences.c @@ -0,0 +1,110 @@ +/*ASCII SUBSEQUENCES PROBLEM +This problem is same as the "Subsequences" question just instead of two function calls, three function calls will be made : +- One with the same string. +- One with a letter added. +- One with the ASCII code of the letter added to the string. +*/ + +#include +#include +#include +#include + +char str[100]; + +void subseq(char s[], int i, char str[]) +{ + if(i == strlen(str)) + { + printf("%s\n", s); + return; + } + + // The 3 function calls in the same order as explained above. + // First function call + subseq(s, i + 1, str); + + int i1; + char s2[strlen(s) + 2]; + + for(i1 = 0; i1 < strlen(s); i1++) + { + // Copy string from s to s2 + s2[i1] = s[i1]; + } + + // Concatinate ith character of string str to s2 + s2[i1++] = str[i]; + s2[i1] = '\0'; + + // Second function call + subseq(s2, i + 1, str); + + // Integer n stores the ASCII value of the ith character of string str + int i2, n = (int)str[i]; + char s3[strlen(s) + 2]; + + // Create AsciiString to store the ASCII value of the ith character of string str + char AsciiString[5]; + + if(n < 10) + { + AsciiString[0] = (char)(n + 48); + AsciiString[1] = '\0'; + } + else if(n<100) + { + AsciiString[0] = (char)(((n - (n % 10)) / 10) + 48); + AsciiString[1] = (char)((n % 10) + 48); + AsciiString[2] = '\0'; + } + else + { + AsciiString[0] = (char)(((n - (n % 100)) / 100) + 48); + AsciiString[1] = (char)((((n - (n % 10)) / 10) % 10) + 48); + AsciiString[2] = (char)((n % 10) + 48); + AsciiString[3] = '\0'; + } + + for(i2 = 0; i2 < strlen(s); i2++) + { + // Copy string from s to s3 + s3[i2] = s[i2]; + } + + int i3 = i2; + + for(; i2 < strlen(AsciiString) + strlen(s); i2++) + { + // Concatinate AsciiString into s3 + s3[i2] = AsciiString[i2 - i3]; + } + + s3[i2] = '\0'; + // Third function call + subseq(s3, i + 1, str); +} + +int main() +{ + printf("Enter the string\n"); + scanf("%s", str); + printf("Number of Subsequences : %d\n", (int)pow(3, strlen(str))); + subseq("", 0, str); + return 0; +} + +/*Sample Input: Enter the string: +ab +Sample Output: +Number of Subsequences : 9 + +b +98 +a +ab +a98 +97 +97b +9798 +*/ diff --git a/Ascii_Subsequences/ASCII_Subsequences.js b/Ascii_Subsequences/ASCII_Subsequences.js new file mode 100644 index 000000000..b3ed3fe56 --- /dev/null +++ b/Ascii_Subsequences/ASCII_Subsequences.js @@ -0,0 +1,46 @@ +/*ASCII SUBSEQUENCES PROBLEM +This problem is same as the "Subsequences" question just instead of two function calls, three function calls will be made : +- One with the same string. +- One with a letter added. +- One with the ascii code of the letter added to the string. +*/ + +function subseq(s, i, str) +{ + if(i === str.length) + { + console.log(s); + return; + } + + // The 3 function calls in the same order as explained above. + // First function call + subseq(s, i + 1, str); + // Second function call + subseq(s + str[i], i + 1, str); + var n = str.charCodeAt(i); + // Third function call with the ASCII value of the ith element of the string + subseq(s + n.toString(), i + 1, str); +} + +( function IIFE() { + var str = prompt("Enter the string"); + console.log( "Number of Subsequences : ", Math.pow(3, str.length)); + subseq("", 0, str); + return 0; +})(); + +/*Sample Input: Enter the string: +ab +Sample Output: +Number of Subsequences : 9 + +b +98 +a +ab +a98 +97 +97b +9798 +*/ diff --git a/Ascii_Subsequences/ASCII_Subsequences.py b/Ascii_Subsequences/ASCII_Subsequences.py new file mode 100644 index 000000000..5981573eb --- /dev/null +++ b/Ascii_Subsequences/ASCII_Subsequences.py @@ -0,0 +1,36 @@ +"""ASCII SUBSEQUENCES PROBLEM +This problem is same as the "Subsequences" question just instead of two function calls, three function calls will be made : +- One with the same string. +- One with a letter added. +- One with the ASCII code of the letter added to the string.""" + +def subseq(s, i, string1): + if (i == len(string1)): + print(s) + return + #The 3 function calls in the same order as explained above. + # First function call + subseq(s, i + 1, string1) + # Second function call + subseq(s + string1[i], i + 1, string1) + #Third function call in which ord(string1[i]) gives the ASCII value which is then converted to string for concatenation + subseq(s + str(ord(string1[i])),i + 1, string1) + +string1 = input("Enter the string") +print("Number of Subsequences :", pow(3, len(string1))) +subseq("", 0, string1) + +"""Sample Input: Enter the string +ab +Sample Output: +Number of Subsequences : 9 + +b +98 +a +ab +a98 +97 +97b +9798 +""" diff --git a/Backtracking_using_bitmask/Backtrack_using_bitmask.cpp b/Backtracking_using_bitmask/Backtrack_using_bitmask.cpp new file mode 100644 index 000000000..430594811 --- /dev/null +++ b/Backtracking_using_bitmask/Backtrack_using_bitmask.cpp @@ -0,0 +1,48 @@ +#include +using namespace std; + +#define d (1 << n) - 1 +int cnt = 0; + +/*This is an optimised approach than the normal backtracking approach. +Here we don’t need to write is Safe Position Function +which works in linear time instead we use bitsets which work in O(1) time.*/ + +void solve(int row, int left, int right, int n) +{ + //All rows are occupied,so the solution must be complete + if(row == d) + { + cnt++; + return; + } + + //Gets a bit sequence with "1"s whereever there is an open "slot" + int pos = d & ~(left | row | right); + + //Loops as long as there is a valid place to put another queen. + while(pos > 0) + { + int bit = pos & (-pos); + pos -= bit; + solve(row | bit, (left | bit) << 1, (right | bit) >> 1, n); + } +} + +int main() { + int n; + cin >> n; + solve(0, 0, 0, n); + cout << cnt; +} + +/* +Sample Input: +4 +Sample Output: +2 +Sample Input: +5 +Sample Output: +10 +*/ \ No newline at end of file diff --git a/Backtracking_using_bitmask/Backtrack_using_bitmask.java b/Backtracking_using_bitmask/Backtrack_using_bitmask.java new file mode 100644 index 000000000..20c064bfb --- /dev/null +++ b/Backtracking_using_bitmask/Backtrack_using_bitmask.java @@ -0,0 +1,59 @@ +import java.util.*; +class Solution +{ + //Keeps track of the # of valid solutions + static int ans = 0; + + public static int power(int x, int y) + { + if(y == 0) + return 1; + int result = power(x,y / 2); + if(y % 2 == 0) + return result * result; + else + return x * result * result; + } + //Checks all possible board configurations + public static void solveNQueens(int left, int col, int right, int n, int done) + { + //All columns are occupied, so the solution must be complete + if(col == done) + { + ans++; + return; + } + + //Gets a bit sequence with "1"s where ever there is an open "slot" + int pos = ~(left | col | right) & done; + + //Loops as long as there is a valid place to put another queen. + while(pos > 0) + { + int bit = pos & (-pos); + pos = pos - bit; + solveNQueens((left | bit) >> 1, col | bit, (right | bit) << 1, n, done); + } + } + public static void main(String[] args) + { + Scanner input = new Scanner(System.in); + int n = input.nextInt(); + //Helps identify valid solutions + int done = power(2, n) - 1; + solveNQueens(0, 0, 0, n, done); + System.out.print(ans); + input.close(); + } +}; + +/* +Sample Input: +4 +Sample Output: +2 +Sample Input: +5 +Sample Output: +10 +*/ \ No newline at end of file diff --git a/Backtracking_using_bitmask/Backtrack_using_bitmask.py b/Backtracking_using_bitmask/Backtrack_using_bitmask.py new file mode 100644 index 000000000..c43de7811 --- /dev/null +++ b/Backtracking_using_bitmask/Backtrack_using_bitmask.py @@ -0,0 +1,46 @@ +# Here we use bit patterns to keep track of queen placements +# for the columns, left diagonals and right diagonals. + +def totalNQueens(n): + #Helps identify valid solutions + all_ones = 2 ** n - 1 + + #Keeps track of the # of valid solutions + count = 0 + + #Checks all possible board configurations + def helper(ld, column, rd): + nonlocal count + #All columns are occupied,so the solution must be complete + if column == all_ones: + count += 1 + return + + #Gets a bit sequence with "1"s whereever there is an open "slot" + possible_slots = ~(ld | column | rd) & all_ones + + #Loops as long as there is a valid place to put another queen. + while possible_slots: + current_bit = possible_slots & -possible_slots + possible_slots -= current_bit + helper( (ld | current_bit) >> 1, column | current_bit, (rd | current_bit) << 1) + + helper(0, 0, 0) + return count + +if __name__ == '__main__': + n = int(input()) + d = (1 << n) - 1 + cnt = totalNQueens(n) + print(cnt) + +''' +Sample Input: +4 +Sample Output: +2 +Sample Input: +5 +Sample Output: +10 +''' \ No newline at end of file diff --git a/Bead_Sort/Bead_Sort.rb b/Bead_Sort/Bead_Sort.rb new file mode 100644 index 000000000..1cee3941c --- /dev/null +++ b/Bead_Sort/Bead_Sort.rb @@ -0,0 +1,41 @@ +# Bead Sort is a Natural Sorting Algorithm Also known as Gravity sort, +# this algorithm was inspired from natural phenomenons and was designed keeping in mind objects(or beads) falling under the influence of gravity. +# The Idea: Positive numbers are represented by a set of beads like those on an abacus. +# Implementation of Bead sort in Ruby + +class Array + # BeadSort algorithm function + def beadsort + # this will take the matrix and make transpose of it to sort. + map { |e| [1] * e }.columns.columns.map(&:length) + end + + # Columns for the matrix + def columns + y = length + x = map(&:length).max + Array.new(x) do |row| + Array.new(y) { |column| self[column][row] }.compact # it remove null value + end + end +end + +# function for taking dynamic array input. +def myarray(a, n) + for i in 0..n + a[i] = gets.chomp.to_i + end + return a +end + +# Driver code: +a = Array.new +n = gets.chomp.to_i +new_arr = myarray(a, n) +print(new_arr.beadsort.reverse()) + +# Output +# Before sorting +# 23 2 12 54 90 102 32 +# After sorting +# 2 12 23 32 54 90 102 diff --git a/Bellmanford_Algorithm/Bellmanford.dart b/Bellmanford_Algorithm/Bellmanford.dart new file mode 100644 index 000000000..1c44295ee --- /dev/null +++ b/Bellmanford_Algorithm/Bellmanford.dart @@ -0,0 +1,248 @@ +/** + * Bellman Ford Algorithm + * ---------------------------------------------- + * This algorithm is used to find shortest distances of all vertices from + * a source vertex in a graph. It is a DP algorithm unlike Dijkstra which is a greedy one. + * This algorithm has O(m*n) time complexity where Dijkstra has O(n*log(n)). + * Bellman ford is suitable for distributed systems and works well on negative edges unline + * Dijkstra. + * + */ + +// Importing required libraries +import 'dart:io'; + +// Class to define an edge +class Edge{ + int source; + int destination; + int weight; + // Constructor + Edge(int source, int destination, int weight){ + this.source = source; + this.destination = destination; + this.weight = weight; + } +} + +// Class to define a graph +class Graph{ + int numVertices; + int numEdges; + var edges; + + // Constructor + Graph(int n, int m){ + this.numVertices = n; + this.numEdges = m; + edges = List(); + } + + // Method to add an edge to the graph + void add_edge(int src, int dest, int wt){ + Edge edge = Edge(src, dest, wt); + this.edges.add(edge); + } + + /* Method to find shortest distances of all vertices from a source vertex + using Bellman Ford algorithm */ + void bellmanFordShortestDistances(int src){ + // Using maximum int value as infinity + const int int64MaxValue = 9223372036854775807; + var distances = List(this.numVertices); + + // Initializing the distances array + for(int i = 0; i < this.numVertices; i ++){ + distances[i] = int64MaxValue; + } + distances[src] = 0; + + // Finding shortest distances + for(int i = 0; i < this.numVertices - 1; i ++){ + for(int j = 0; j < this.numEdges; j ++){ + int srce = this.edges[j].source; + int desti = this.edges[j].destination; + int wt = this.edges[j].weight; + if(distances[srce] != int64MaxValue && distances[desti] > distances[srce] + wt){ + distances[desti] = distances[srce] + wt; + } + } + } + + // Checking for a negative cycle. + int flag = 0; + for(int j = 0; j < this.numEdges; j ++){ + int srce = this.edges[j].source; + int desti = this.edges[j].destination; + int wt = this.edges[j].weight; + if(distances[srce] != int64MaxValue && distances[desti] > distances[srce] + wt){ + print("Negative cycle found!!"); + flag = 1; + break; + } + } + + // Printing shortest distances if negative cycle is not found + if(flag == 0){ + print("The shortest distances of all vertices from src vertex are in the following order:"); + print(distances.join(" ")); + } + } +} + +// Driver method of the program +void main(){ + + // Input of number of vertices + print("Enter number of vertices:"); + var input = stdin.readLineSync(); + int n = int.parse(input); + + // Input of number of edges + print("Enter number of edges:"); + input = stdin.readLineSync(); + int m = int.parse(input); + + // Creating the graph + Graph g = Graph(n, m); + + // Input of edges + print("Enter edges:"); + for(int i = 0; i < m; i ++){ + print("Enter edge ${i + 1}"); + print("Enter source vertex:"); + int src = int.parse(stdin.readLineSync()); + print("Enter destination vertex:"); + int dest = int.parse(stdin.readLineSync()); + print("Enter weight of the edge:"); + int wt = int.parse(stdin.readLineSync()); + g.add_edge(src, dest, wt); + } + + // Input of source vertex for Bellman Ford + print("Enter the source vertex to find shortest distances:"); + int src = int.parse(stdin.readLineSync()); + + // Printing output of Bellman Ford + g.bellmanFordShortestDistances(src); + +} + +/** + * Sample Input and Output + * ----------------------------- + * Sample 1 + * ----------------------------- + * Enter number of vertices: + * 5 + * Enter number of edges: + * 8 + * Enter edges: + * Enter edge 1 + * Enter source vertex: + * 0 + * Enter destination vertex: + * 1 + * Enter weight of the edge: + * -1 + * Enter edge 2 + * Enter source vertex: + * 0 + * Enter destination vertex: + * 2 + * Enter weight of the edge: + * 4 + * Enter edge 3 + * Enter source vertex: + * 1 + * Enter destination vertex: + * 2 + * Enter weight of the edge: + * 3 + * Enter edge 4 + * Enter source vertex: + * 3 + * Enter destination vertex: + * 1 + * Enter weight of the edge: + * 1 + * Enter edge 5 + * Enter source vertex: + * 1 + * Enter destination vertex: + * 3 + * Enter weight of the edge: + * 2 + * Enter edge 6 + * Enter source vertex: + * 3 + * Enter destination vertex: + * 2 + * Enter weight of the edge: + * 5 + * Enter edge 7 + * Enter source vertex: + * 1 + * Enter destination vertex: + * 4 + * Enter weight of the edge: + * 2 + * Enter edge 8 + * Enter source vertex: + * 4 + * Enter destination vertex: + * 3 + * Enter weight of the edge: + * -3 + * Enter the source vertex to find shortest distances: + * 0 + * The shortest distances of all vertices from src vertex are in the following order: + * 0 -1 2 -2 1 + * ------------------------ + * Sample 2 + * ------------------------ + * Enter number of vertices: + * 4 + * Enter number of edges: + * 5 + * Enter edges: + * Enter edge 1 + * Enter source vertex: + * 0 + * Enter destination vertex: + * 1 + * Enter weight of the edge: + * 5 + * Enter edge 2 + * Enter source vertex: + * 0 + * Enter destination vertex: + * 2 + * Enter weight of the edge: + * 4 + * Enter edge 3 + * Enter source vertex: + * 2 + * Enter destination vertex: + * 1 + * Enter weight of the edge: + * -6 + * Enter edge 4 + * Enter source vertex: + * 1 + * Enter destination vertex: + * 3 + * Enter weight of the edge: + * 3 + * Enter edge 5 + * Enter source vertex: + * 3 + * Enter destination vertex: + * 2 + * Enter weight of the edge: + * 2 + * Enter the source vertex to find shortest distances: + * 0 + * Negative cycle found!! + * + */ diff --git a/Binary_Insertion_Sort/Binary_Insertion_Sort.dart.txt b/Binary_Insertion_Sort/Binary_Insertion_Sort.dart.txt new file mode 100644 index 000000000..221d06d98 --- /dev/null +++ b/Binary_Insertion_Sort/Binary_Insertion_Sort.dart.txt @@ -0,0 +1,58 @@ +/* Binary Insertion sort is a special type up of Insertion sort which uses binary search algorithm to find out the correct position of the inserted element in the array. */ + + +void insertionSort(List ar){ + if (ar == null || ar.length == 0){ + return; + } + int n = ar.length; + int temp, i, j; + for (i = 1; i < n; i++){ + temp = ar[i]; + j = i - 1; + while (j >= 0 && temp < ar[j]){ + ar[j+1] = ar[j]; + --j; + } + ar[j+1] = temp; + } +} + +// Binary Search Performed +int binarySearch(List ar, int key, int start, int end){ + if (end-start <= 1){ + if (key < ar[start]){ + return start - 1; + } + else{ + return start; + } + } + int mid = (start + end) ~/ 2; + if (ar[mid] < key){ + return binarySearch(ar, key, mid, end); + } + else if (ar[mid] > key){ + return binarySearch(ar, key, start, mid); + } + else{ + return mid; + } +} + +main(){ + List ar = [1, 5, 3, 4, 8, 6]; + int n = ar.length; + insertionSort(ar); + print("Sorted Array: "); + for (int i = 0;i < n; i++){ + print(ar[i]); + } +} + +/* +OUTPUT: +Sorted Array is: [1, 3, 4, 5, 6, 8] +*/ + + diff --git a/Binary_Search/Binary search.ts b/Binary_Search/Binary search.ts new file mode 100644 index 000000000..7ff9a3d90 --- /dev/null +++ b/Binary_Search/Binary search.ts @@ -0,0 +1,59 @@ +/* Implenetation of Binary Search algorithm to find value 6 in a given array of numbers */ + +function BinarySearch( arr:number[] , n:number , val:number ) :number +{ + var start = 0 //starting index of the array + var end = n-1 //ending index + var mid = 0 + var ind = -1 + + while (start <= end) + { + mid = Math.floor((start + end) / 2) + + //checking if value to be found is at the middle + if ( val == arr[mid] ) + { + ind = mid + break + } + + /* if value to be found is greater than the middle then the algorithm + searches to the right of the middle element in the array */ + else if ( val > arr[mid] ) + { + start = mid + 1 + } + /* if value to be found is less than the middle then the algorithm + searches to the left of the middle element in the array */ + else + { + end = mid - 1 + } + } + return ind //returning the index of the value if found, else returns -1 +} +var result = 0 +var n = 0 +var val = 6 //input value +console.log(" value to be found: ", val); +var n: number = 6 //no. of elements in the array +var arr = [1, 2, 3, 4, 5, 6]; //input array +console.log(" Array of numbers is: ", arr); +result = BinarySearch(arr, n, val) +if (result != -1) { + console.log(" value ", val," found at index no. ", result," in the array "); +} +else { + console.log(" value ", val," not found "); +} + + +/* OUTPUT: + + value to be found: 6 + Array of numbers is: [ 1, 2, 3, 4, 5, 6 ] + value 6 found at index no. 5 in the array +*/ + + diff --git a/Binary_Search/Binary_Search.dart b/Binary_Search/Binary_Search.dart new file mode 100644 index 000000000..a6b7e1fe8 --- /dev/null +++ b/Binary_Search/Binary_Search.dart @@ -0,0 +1,149 @@ +//Binary Search is an efficient algorithm for finding an item from a sorted list of items. +//This is the implementation of Binary Search in dart language to insert and search the elements. +import 'dart:io'; + +void binarySearch(List list, int x){ + int size = list.length; + int low = 0; + int high = size - 1; + while(low <= high){ + int mid = ((low + high) / 2).floor(); + if(list[mid] == x){ + print('Found $x in the List at Index $mid!'); + return; + } + if(list[mid] > x){ + high = mid - 1; + continue; + } + low = mid + 1; + } + print('Did not $x in the List!'); + return; +} + +main(){ + List list = new List(); + int task = 0; + print('Binary Search Program'); + while(task != 4){ + print('0 - Display List\n1 - Insert element in List \n2 - Search element in List\n3 - Quit\nSelect task:-'); + try{ + task = int.parse(stdin.readLineSync()); + } on Exception{ + print('Please enter valid Integer value!'); + continue; + } + switch(task){ + case 0: + if(list.length == 0){ + print('Empty List!'); + } + else{ + print('List:-'); + list.forEach((val){ + print(val); + }); + } + break; + case 1: + int val = null; + print('Enter value that needs to be inserted in List:- '); + try{ + val = int.parse(stdin.readLineSync()); + } on Exception{ + print('Please enter valid Integer value!'); + continue; + } + if(val == null){ + print('Failed to insert element in List!'); + continue; + } + list.add(val); + list.sort(); + print('Successfully inserted $val in List!'); + break; + + case 2: + int val = null; + print('Enter value that needs to be searched in List:- '); + try{ + val = int.parse(stdin.readLineSync()); + } on Exception{ + print('Please enter valid Integer value!'); + continue; + } + if(val == null){ + print('Failed to search element in List!'); + continue; + } + binarySearch(list, val); + break; + + case 3: + print('Binary Search Program Complete'); + break; + default: + continue; + } + } +} + + +/* +Sample Input/Output: +Binary Search Program +0 - Display List +1 - Insert element in List +2 - Search element in List +3 - Quit +Select task:- //to add element +1 +Enter value that needs to be inserted in List:- +1 +Successfully inserted 1 in List! +0 - Display List +1 - Insert element in List +2 - Search element in List +3 - Quit +Select task:- +1 +Enter value that needs to be inserted in List:- +2 +Successfully inserted 2 in List! +0 - Display List +1 - Insert element in List +2 - Search element in List +3 - Quit +Select task:- +1 +Enter value that needs to be inserted in List:- +3 +Successfully inserted 3 in List! +0 - Display List +1 - Insert element in List +2 - Search element in List +3 - Quit +Select task:- //to display the list +0 +List:- +1 +2 +3 +0 - Display List +1 - Insert element in List +2 - Search element in List +3 - Quit +Select task:- //to search the element +2 +Enter value that needs to be searched in List:- +2 +Found 2 in the List at Index 1! +0 - Display List +1 - Insert element in List +2 - Search element in List +3 - Quit +Select task:- //quiting the program +3 +Binary Search Program Complete +*/ diff --git a/Binary_Search/Binary_Search.rs b/Binary_Search/Binary_Search.rs new file mode 100644 index 000000000..08d24b231 --- /dev/null +++ b/Binary_Search/Binary_Search.rs @@ -0,0 +1,88 @@ +// Rust program for Binary Search +use std::io; + +fn main() { + println!(" Enter number of elements to be entered in the array "); + let mut size = String::new(); + + io::stdin().read_line(&mut size).expect("failed to read input."); + let size: usize = size.trim_end().parse().expect("invalid input"); + let mut vector: Vec = Vec::with_capacity(size as usize); + + println!("Enter element to be searched " ); + let mut element = usize::new(); + + println!("Enter elements of array in a sorted array "); + let mut index = 0; + + // Enter values into vector + while index < size { + index += 1; + // Note: Rust takes spaces as non-intergral value + let mut temp_arr = String::new(); + io::stdin().read_line(&mut temp_arr).expect("failed to read input."); + let temp_arr: usize = temp_arr.trim_end().parse().expect("invalid input"); + vector.push(temp_arr); + } + + // Binary Search process + let mut leftpart = 0; + let mut rightpart = size - 1; + let mut midindex = 0; + let mut checkpoint = 0; + while leftpart <= rightpart { + midindex = leftpart + (rightpart - leftpart) / 2; + + // Element found + if vector[midindex] == element{ + checkpoint = 1; + println!("Element is found at index "); + println!("{:?}" , midindex + 1); + break; + } + + else if vector[midindex] < element{ + leftpart = midindex + 1; + } + + else { + rightpart = midindex - 1; + } + + } + + if checkpoint == 0 { + println!("Element is not found in the array "); + } +} +/* +TEST CASE + +INPUT + Enter number of elements to be entered in the array +3 +Enter element to be searched +2 +Enter elements of array in a sorted array +1 +2 +3 + +OUTPUT +Element is found at index +2 + +INPUT + Enter number of elements to be entered in the array +3 +Enter element to be searched +5 +Enter elements of array in a sorted array +1 +2 +3 + +OUTPUT +Element is not found in the array +*/ + diff --git a/Binary_Search_Trees/BinarySearchTree.dart b/Binary_Search_Trees/BinarySearchTree.dart new file mode 100644 index 000000000..ed9f7f25e --- /dev/null +++ b/Binary_Search_Trees/BinarySearchTree.dart @@ -0,0 +1,291 @@ +import 'dart:io'; + +class Node{ + int value; + Node leftNode; + Node rightNode; + + Node(int val){ + this.value = val; + this.leftNode = null; + this.rightNode = null; + } + + Node get left{ + return this.leftNode; + } + + Node get right{ + return this.rightNode; + } + + int get val{ + return this. value; + } + + void set val(int x){ + this.value = x; + } + + void set left(Node x){ + this.leftNode = x; + } + + void set right(Node x){ + this.rightNode = x; + } +} + +Node root; + +preOrderTraversal(Node x){ + if(x == null) return; + print(x.val); + preOrderTraversal(x.left); + preOrderTraversal(x.right); +} + +inOrderTraversal(Node x){ + if(x == null) return; + inOrderTraversal(x.left); + print(x.val); + inOrderTraversal(x.right); +} + +postOrderTraversal(Node x){ + if(x == null) return; + postOrderTraversal(x.left); + print(x.val); + postOrderTraversal(x.right); +} + +insertElement(Node x, int val){ + if(root == null){ + root == new Node(val); + print(root.val); + return; + } + if(x.val == val) return; + if(x.val > val){ + if(x.left == null){ + Node newNode = new Node(val); + x.left = newNode; + return; + } + insertElement(x.left, val); + return; + } + if(x.right == null){ + Node newNode = new Node(val); + x.right = newNode; + return; + } + insertElement(x.right, val); + return; +} + +searchTree(Node x, int val){ + if(x == null){ + print('Did not find $val in Tree!'); + return; + } + if(x.val == val){ + print('Found $val in Tree!'); + return; + } + if(x.val > val){ + searchTree(x.left, val); + return; + } + if(x.val < val){ + searchTree(x.right, val); + return; + } +} + +main() { + int task = 0; + print('Binary Search Tree Program'); + while(task != 3){ + print('0 - Display Tree\n1 - Insert Element in Tree \n2 - Search element in Tree\n3 - Quit\nSelect task:-'); + try{ + task = int.parse(stdin.readLineSync()); + } on Exception{ + print('Please enter valid Integer value!'); + continue; + } + switch(task){ + case 0: + if(root == null){ + print('Empty Tree!'); + } + else{ + print('Traversal Order:-\n1 - Preorder \n2 - Inorder \n3 - Postorder'); + int val; + try{ + val = int.parse(stdin.readLineSync()); + } on Exception{ + print('Please enter valid Integer value!'); + continue; + } + switch(val){ + case 1: + print('PreOrder Traversal'); + preOrderTraversal(root); + break; + case 2: + print('InOrder Traversal'); + inOrderTraversal(root); + break; + case 3: + print('PostOrder Traversal'); + postOrderTraversal(root); + break; + default: + print('Please enter valid Integer value!'); + } + } + break; + + case 1: + int val = null; + print('Enter value that needs to be inserted in Tree:-'); + try{ + val = int.parse(stdin.readLineSync()); + } on Exception{ + print('Please enter valid Integer value!'); + continue; + } + if(val == null){ + print('Failed to insert element in Tree!'); + continue; + } + insertElement(root, val); + print('Successfully inserted $val in Tree!'); + break; + + case 2: + int val = null; + print('Enter value that needs to be searched in Tree:-'); + try{ + val = int.parse(stdin.readLineSync()); + } on Exception{ + print('Failed to search element in Tree!'); + continue; + } + if(val == null){ + print('Failed to search element in Tree!'); + continue; + } + searchTree(root, val); + break; + + case 3: + print('Binary Search Tree Program Complete'); + break; + + default: + continue; + } + } +} + +/* +Sample Input/Output: +Binary Search Tree Program +0 - Display Tree +1 - Insert element in Tree +2 - Search element in Tree +3 - Quit +Select task:- +1 +Enter value that needs to be inserted in Tree:- +1 +1 +Successfully inserted 1 in Tree! +0 - Display Tree +1 - Insert element in Tree +2 - Search element in Tree +3 - Quit +Select task:- +1 +Enter value that needs to be inserted in Tree:- +2 +Successfully inserted 2 in Tree! +0 - Display Tree +1 - Insert element in Tree +2 - Search element in Tree +3 - Quit +Select task:- +1 +Enter value that needs to be inserted in Tree:- +3 +Successfully inserted 3 in Tree! +0 - Display Tree +1 - Insert element in Tree +2 - Search element in Tree +3 - Quit +Select task:- +0 +Traversal Order:- +1 - Preorder +2 - Inorder +3 - Postorder +1 +PreOrder Traversal +1 +2 +3 +0 - Display Tree +1 - Insert element in Tree +2 - Search element in Tree +3 - Quit +Select task:- +0 +0 - Display Tree +1 - Insert element in Tree +2 - Search element in Tree +3 - Quit +Select task:- +0 +Traversal Order:- +1 - Preorder +2 - Inorder +3 - Postorder +2 +InOrder Traversal +1 +2 +3 +0 - Display Tree +1 - Insert element in Tree +2 - Search element in Tree +3 - Quit +Select task:- +0 +Traversal Order:- +1 - Preorder +2 - Inorder +3 - Postorder +3 +PostOrder Traversal +3 +2 +1 +0 - Display Tree +1 - Insert element in Tree +2 - Search element in Tree +3 - Quit +Select task:- +2 +Enter value that needs to be searched in Tree:- +2 +Found 2 in Tree! +0 - Display Tree +1 - Insert element in Tree +2 - Search element in Tree +3 - Quit +Select task:- +3 +Binary Search Tree Program Complete +*/ diff --git a/Binary_Tree_Bottom_View/Binary_Tree_Bottom_View.c b/Binary_Tree_Bottom_View/Binary_Tree_Bottom_View.c new file mode 100644 index 000000000..18e63540e --- /dev/null +++ b/Binary_Tree_Bottom_View/Binary_Tree_Bottom_View.c @@ -0,0 +1,124 @@ +/* C program to print bottom view of the binary tree*/ + +#include +#include +#include + +// A binary tree node has data, pointer to left child and a pointer to right child +struct Node +{ + int data; + struct Node* left; + struct Node* right; +}; + +/* Inserting elements into Binary Tree*/ +struct Node *create() +{ + Node *ptr; + int x; + printf("Enter data(-1 for no node):"); + scanf("%d", &x); + + if(x == -1) + return NULL; + + ptr = (struct Node*)malloc(sizeof(struct Node)); + ptr -> data = x; + + printf("Enter left child of %d:\n", x); + ptr -> left = create(); + + printf("Enter right child of %d:\n", x); + ptr -> right = create(); + + return ptr; +} + +// Calculating the level and the vertical distance of the node and finding the nodes that appear as the top view +void findBottomView(struct Node *root, int *a, int *b, int level, int dist) +{ + if(root == NULL) + return; + + if(level > a[50 + dist]) + { + a[50 + dist] = level; + b[50 + dist] = root -> data; + } + + # Recursively calling the right and the left child to get the bottom view + + findBottomView(root -> right, a, b, level + 1, dist + 1); + findBottomView(root -> left, a, b, level + 1, dist - 1); +} + +int *bottomView(struct Node* root, int *len) { + + int i, o = 0; + + // a stores level of the node + // b stores vertical distance of the node from root + + int *a = (int *)calloc(100, sizeof(int)); + int *b = (int *)calloc(100, sizeof(int)); + int *c = (int *)calloc(100, sizeof(int)); + + // Initialising a and b as INT_MIN as we need to print bottom most elements + for(i = 0; i < 100; i++) + { + a[i] = INT_MIN; + b[i] = INT_MIN; + } + + findBottomView(root, a, b, 0, 0); + + for(i = 0; i < 100; i++) + { + if(b[i] != INT_MIN) + c[o++] = b[i]; + } + + *len = o; + return c; +} + +int main() +{ + struct Node *root = create(); + int len = 0; + int *res = bottomView(root, &len); + + for(int i = 0; i < len; i++) + printf("%d ", res[i]); +} + + +/* Sample Input +Enter data(-1 for no node: 1 +Enter left child of 1: +Enter data(-1 for no node: 2 +Enter left child of 2: +Enter data(-1 for no node: 6 +Enter left child of 6: +Enter data(-1 for no node: -1 +Enter right child of 6: +Enter data(-1 for no node: -1 +Enter right child of 2: +Enter data(-1 for no node: -1 +Enter right child of 1: +Enter data(-1 for no node: 3 +Enter left child of 3: +Enter data(-1 for no node: -1 +Enter right child of 3: +Enter data(-1 for no node: -1 + + 1 + / \ + 2 3 + / + 6 + +Output :- 6 2 1 3 +*/ + diff --git a/Binary_Tree_Right_View/Binary_Tree_Right_View.c b/Binary_Tree_Right_View/Binary_Tree_Right_View.c new file mode 100644 index 000000000..5f58ab287 --- /dev/null +++ b/Binary_Tree_Right_View/Binary_Tree_Right_View.c @@ -0,0 +1,105 @@ +/* C program to print right view of the binary tree*/ + +#include +#include + +/* A binary tree node has data, pointer to left child and a pointer to right child */ +struct Node +{ + int data; + struct Node* left; + struct Node* right; +}; + +/* Inserting elements into Binary Tree*/ +struct Node *create() +{ + Node *ptr; + int x; + + printf("Enter data(-1 for no node):"); + scanf("%d", &x); + + if(x == -1) + return NULL; + + ptr = (struct Node*)malloc(sizeof(struct Node)); + ptr -> data = x; + + printf("Enter left child of %d:\n",x); + ptr -> left = create(); + + printf("Enter right child of %d:\n",x); + ptr -> right = create(); + + return ptr; +} + +/*Recursive solution for priniting right view of Binary Tree*/ +void findRightView(struct Node *root, int *ans, int *size, int index) +{ + if(root == NULL) + return; + + index++; + + // Increasing the level of the tree every time a node with the same level appears + if(index > *size) + ans[(*size)++] = root -> data; + + // Recursively calling the nodes down the tree + findRightView(root -> right, ans, size, index); + + findRightView(root -> left, and, size, index); +} + +// Function for intializing the level of the root node and size of the array +int *rightView(struct Node *root, int *size) +{ + int *ans = malloc(sizeof(int) * 100); + *size = 0; + + findRightView(root, ans, size, 0); + + return ans; +} + +int main() +{ + struct Node *root = create(); + + int size = 0; + int *res = rightView(root, &size); + + for(int i = 0; i < size; i++) + printf("%d", res[i]); +} + +/* Sample Input +Enter data(-1 for no node: 1 +Enter left child of 1: +Enter data(-1 for no node: 2 +Enter left child of 2: +Enter data(-1 for no node: 6 +Enter left child of 6: +Enter data(-1 for no node: -1 +Enter right child of 6: +Enter data(-1 for no node: -1 +Enter right child of 2: +Enter data(-1 for no node: -1 +Enter right child of 1: +Enter data(-1 for no node: 3 +Enter left child of 3: +Enter data(-1 for no node: -1 +Enter right child of 3: +Enter data(-1 for no node: -1 + + 1 + / \ + 2 3 + / + 6 + +Output :- 1 3 6 +*/ + diff --git a/Binary_Tree_Top_View/Binary_Tree_Top_View.c b/Binary_Tree_Top_View/Binary_Tree_Top_View.c new file mode 100644 index 000000000..be8940cbd --- /dev/null +++ b/Binary_Tree_Top_View/Binary_Tree_Top_View.c @@ -0,0 +1,124 @@ + +/* C program to print top view of Binary tree*/ + +#include +#include +#include + +/* A binary tree node has data, pointer to left child and a pointer to right child */ +struct Node +{ + int data; + struct Node* left; + struct Node* right; +}; + +// Inserting elements into Binary Tree +struct Node *create() +{ + Node *ptr; + int x; + + printf("Enter data(-1 for no node):"); + scanf("%d",&x); + + if(x == -1) + return NULL; + + ptr = (struct Node*)malloc(sizeof(struct Node)); + ptr -> data = x; + + printf("Enter left child of %d:\n",x); + ptr -> left = create(); + + printf("Enter right child of %d:\n",x); + ptr -> right = create(); + + return ptr; +} + +// Calculating the level and the vertical distance of the node and finding the nodes that appear as the top view +void findTopView(struct Node *root, int *a, int *b, int level, int dist) +{ + if(root == NULL) + return; + + if(level < a[50 + dist]) + { + a[50 + dist] = level; + b[50 + dist] = root->data; + } + + # Recursively calling the left and the right child to get the bottom view + findTopView(root->left, a, b, level+1, dist-1); + + findTopView(root->right, a, b, level+1, dist+1); +} + +int *topView(struct Node* root, int *len) { + + int i,o = 0; + + // a stores the level of the node + // b stores the Vertical distance of the node from root + int *a = (int *)calloc(100, sizeof(int)); + int *b = (int *)calloc(100, sizeof(int)); + int *c = (int *)calloc(100, sizeof(int)); + + // Initialising a and b as INT_MAX as we need to print top most elements + for(i = 0; i < 100; i++) + { + a[i] = INT_MAX; + b[i] = INT_MAX; + } + + findTopView(root, a, b, 0, 0); + + for(i = 0; i < 100; i++) + { + if(b[i] != INT_MAX) + c[o++] = b[i]; + } + + *len = o; + return c; +} + +int main() +{ + struct Node *root = create(); + int len = 0; + int *res = topView(root, &len); + + for(int i = 0; i < len; i++) + printf("%d ", res[i]); +} + +/* Sample Input +Enter data(-1 for no node: 1 +Enter left child of 1: +Enter data(-1 for no node: 2 +Enter left child of 2: +Enter data(-1 for no node: 6 +Enter left child of 6: +Enter data(-1 for no node: -1 +Enter right child of 6: +Enter data(-1 for no node: -1 +Enter right child of 2: +Enter data(-1 for no node: -1 +Enter right child of 1: +Enter data(-1 for no node: 3 +Enter left child of 3: +Enter data(-1 for no node: -1 +Enter right child of 3: +Enter data(-1 for no node: -1 + + 1 + / \ + 2 3 + / + 6 + +Output :- 6 2 1 3 +*/ + diff --git a/Bisection_Method/Bisection_Method.cpp b/Bisection_Method/Bisection_Method.cpp new file mode 100644 index 000000000..92541251d --- /dev/null +++ b/Bisection_Method/Bisection_Method.cpp @@ -0,0 +1,122 @@ +#include +#include +using namespace std; +// approximation limit +#define error 0.0001 + +//function of the polynomial is inputted here say f(x) = x*x - 2*x + 1 +float polynomial(float x) +{ + return x * x - 4 * x + 3; +} + +float mid(float q, float w) +{ + return (q + w) / 2; +} + +int main() +{ + int i; + float lower_bound, upper_bound, a, b; + + cout << "For the interval (a, b) where the root may lie : " << endl; + cout << "Enter the value of a :- " << endl; + cin >> lower_bound; + + a = lower_bound; + + cout << "Enter the value of b :- " << endl; + cin >> upper_bound; + + b = upper_bound; + + if(polynomial(lower_bound) * polynomial(upper_bound) > 0) + { + cout << "Invalid interval" << endl; + } + else + { + // repeat until the required accuracy is obtained + while(abs(polynomial(mid(lower_bound, upper_bound))) > error) + { + cout << "\nIteration_no = " << i << " , First_no = " << lower_bound + << " , Second_no = " << upper_bound << " middle = " + << mid(lower_bound, upper_bound) ; + cout << " , f(middle) = " << polynomial(mid(lower_bound, upper_bound)) + << " , f(first_no)*f(middle) = " + << polynomial(lower_bound)*polynomial(mid(lower_bound, upper_bound)) << endl; + // sign changes in the first interval => root lies in the 1st interval + if(polynomial(lower_bound) * polynomial(mid(lower_bound, upper_bound)) < 0) + { + upper_bound = mid(lower_bound, upper_bound); + } + else + { + lower_bound = mid(lower_bound, upper_bound); + } + i++; + } + cout << "\nIteration_no = " << i << " , First_no = " << lower_bound + << " , Second_no = " << upper_bound << " middle = " << mid(lower_bound, upper_bound) ; + cout << " , f(middle) = " << polynomial(mid(lower_bound, upper_bound)) + << " , f(first_no)*f(middle) = " + << polynomial(lower_bound)*polynomial(mid(lower_bound, upper_bound)) << endl; + cout << "\nThe approximated root of the given polynomial within the specified interval (" + << a << " , " << b << ") = " ; + cout << mid(upper_bound, lower_bound) << endl; + } + return 0; +} + +/* OUTPUT +For the interval (a, b) where the root may lie : +Enter the value of a :- +2.1 +Enter the value of b :- +4.1 + +Iteration_no = 0 , First_no = 2.1 , Second_no = 4.1 middle = 3.1 , f(middle) = 0.21 , +f(first_no)*f(middle) = -0.2079 + +Iteration_no = 1 , First_no = 2.1 , Second_no = 3.1 middle = 2.6 , f(middle) = -0.64 , +f(first_no)*f(middle) = 0.6336 + +Iteration_no = 2 , First_no = 2.6 , Second_no = 3.1 middle = 2.85 , f(middle) = -0.2775 , +f(first_no)*f(middle) = 0.1776 + +Iteration_no = 3 , First_no = 2.85 , Second_no = 3.1 middle = 2.975 , f(middle) = -0.0493755 , +f(first_no)*f(middle) = 0.0137017 + +Iteration_no = 4 , First_no = 2.975 , Second_no = 3.1 middle = 3.0375 , f(middle) = 0.0764065 , +f(first_no)*f(middle) = -0.00377261 + +Iteration_no = 5 , First_no = 2.975 , Second_no = 3.0375 middle = 3.00625 , f(middle) = 0.0125389 , +f(first_no)*f(middle) = -0.000619115 + +Iteration_no = 6 , First_no = 2.975 , Second_no = 3.00625 middle = 2.99062 , f(middle) = -0.0186625 , +f(first_no)*f(middle) = 0.000921469 + +Iteration_no = 7 , First_no = 2.99062 , Second_no = 3.00625 middle = 2.99844 , f(middle) = -0.00312233 , +f(first_no)*f(middle) = 5.82703e-005 + +Iteration_no = 8 , First_no = 2.99844 , Second_no = 3.00625 middle = 3.00234 , f(middle) = 0.00469303 , +f(first_no)*f(middle) = -1.46532e-005 + +Iteration_no = 9 , First_no = 2.99844 , Second_no = 3.00234 middle = 3.00039 , f(middle) = 0.000781059 , +f(first_no)*f(middle) = -2.43872e-006 + +Iteration_no = 10 , First_no = 2.99844 , Second_no = 3.00039 middle = 2.99941 , f(middle) = -0.00117207 , +f(first_no)*f(middle) = 3.65958e-006 + +Iteration_no = 11 , First_no = 2.99941 , Second_no = 3.00039 middle = 2.9999 , f(middle) = -0.000195503 , +f(first_no)*f(middle) = 2.29143e-007 + +Iteration_no = 12 , First_no = 2.9999 , Second_no = 3.00039 middle = 3.00015 , f(middle) = 0.000292778 , +f(first_no)*f(middle) = -5.7239e-008 + +Iteration_no = 13 , First_no = 2.9999 , Second_no = 3.00015 middle = 3.00002 , f(middle) = 4.86374e-005 , +f(first_no)*f(middle) = -9.50877e-009 + +The approximated root of the given polynomial within the specified interval (2.1, 4.1) = 3.00002 +*/ \ No newline at end of file diff --git a/Boyer_Moore_Algorithm/Boyer_Moore.c b/Boyer_Moore_Algorithm/Boyer_Moore.c new file mode 100644 index 000000000..ec88ef89d --- /dev/null +++ b/Boyer_Moore_Algorithm/Boyer_Moore.c @@ -0,0 +1,63 @@ +#include +#define MAX 256 + +int findmax(int a, int b) +{ + return (a > b) ? a : b; +} + +void searchwrongchar(char *str, int size, int extra[MAX]) +{ + for (int i = 0; i < MAX; ++i) + extra[i] = -1; + + for (int i = 0; i < size; ++i) + extra[(int)str[i]] = i; +} + +void search(char *text, char *pattern) +{ + int patLen = strlen(pattern); + int txtLen = strlen(text); + + int extra[MAX]; + + searchwrongchar(pattern, patLen, extra); + + int s = 0; + while (s <= (txtLen - patLen)) + { + int j = patLen - 1; + + while (j >= 0 && pattern[j] == text[s + j]) + j--; + + if (j < 0) + { + printf("\n\nPattern Matches at shift of = %d.", s); + s += (s + patLen < txtLen) ? patLen - extra[text[s + patLen]] : 1; + } + else + s += findmax(1, j - extra[text[s + j]]); + } +} + +int main() +{ + char text[MAX], pattern[MAX]; + printf("Enter the Text: "); + scanf("%s", &text); + printf("\nEnter the Pattern to Match: "); + scanf("%s", &pattern); + search(text, pattern); + return 0; +} + +/* +INPUT: +Enter the Text: ABAAABCD +Enter the Pattern to Match: ABC + +OUTPUT: +Pattern match at shift = 4 +*/ diff --git a/Boyer_Moore_Algorithm/Boyer_Moore.cs b/Boyer_Moore_Algorithm/Boyer_Moore.cs new file mode 100644 index 000000000..391afe81a --- /dev/null +++ b/Boyer_Moore_Algorithm/Boyer_Moore.cs @@ -0,0 +1,110 @@ +// C# Program for Boyer Moore String Matching Algorithm + +using System; + +public class Algorithm +{ + static int CHARACTERS = 256; + + // Getting maximum of two integers + static int max (int a, int b) { return (a > b)? a: b; } + + // Bad Character Pre-Processing Function + static void badChar( char []str, int size,int []badCharacter) + { + int i; + + // Initializing all occurences to -1 + for (i = 0; i < CHARACTERS; i++) + badCharacter[i] = -1; + + // Filling the Actual Value + for (i = 0; i < size; i++) + badCharacter[(int) str[i]] = i; + } + + // Pattern Searching Function + static void search( char []txt, char []pat) + { + int m = pat.Length; + int n = txt.Length; + + int []Character = new int[CHARACTERS]; + badChar(pat, m, Character); + + /* + s is used to keep track of + pattern shifting with respect to text + */ + + int s = 0; + + while(s <= (n - m)) + { + int j = m - 1; + + while(j >= 0 && pat[j] == txt[s+j]) + j--; + + /* + If the pattern is present at current + shift, then index j will become -1 after + the above loop + */ + + if (j < 0) + { + Console.WriteLine("Pattern occurs at index: " + s); + s += (s+m < n)? m-Character[txt[s+m]] : 1; + } + + else + s += max(1, j - Character[txt[s+j]]); + + } + } + + public static void Main() + { + Console.WriteLine("Enter The String Value: "); + String valueEntered = Console.ReadLine(); + Console.WriteLine("Enter The Pattern To Search: "); + String pattern = Console.ReadLine(); + Console.WriteLine(); + + char []txt = valueEntered.ToCharArray(); + char []pat = pattern.ToCharArray(); + search(txt, pat); + } +} + +/** + +Enter The String Value: +ABAAABCD +Enter The Pattern To Search: +ABC + +Pattern occurs at index: 4 + +-------------------------------------------------- + +Enter The String Value: +AABAACAADAABAABA +Enter The Pattern To Search: +AABA + +Pattern occurs at index: 0 +Pattern occurs at index: 9 +Pattern occurs at index: 12 + +-------------------------------------------------- + +Enter The String Value: +THIS IS A TEST TEXT +Enter The Pattern To Search: +TEST + +Pattern occurs at index: 10 + +*/ diff --git a/Boyer_Moore_Algorithm/Boyer_Moore.go b/Boyer_Moore_Algorithm/Boyer_Moore.go new file mode 100644 index 000000000..092766194 --- /dev/null +++ b/Boyer_Moore_Algorithm/Boyer_Moore.go @@ -0,0 +1,78 @@ +/*Boyer Moore Algorithm for Pattern Search*/ +package main + +import "fmt" + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +//Using Bad Character Heuristic method +func preprocess(str string, length int, chars []int) { + + for i,_:=range(chars) {chars[i] = 1} + + //The last occurrence of the char + for k := 0; k < length; k++ { + chars[int(str[k])] = k; + } +} + +func boyreMoore(text string, pattern string) { + var lenStr int = len(text) + var lenPattern int = len(pattern) + + chars := make([]int, 128) + + preprocess(pattern, lenPattern, chars) + + //shift of the pattern with respect to text + var shift int = 0 + + for shift <= lenStr - lenPattern { + match := lenPattern - 1 + + for (match >= 0 && pattern[match] == text[shift + match]) { + match = match - 1 + } + + // If pattern found, match = -1 + if match < 0 { + fmt.Printf("Pattern found at : %d\n", shift) + + // Shift the pattern so that the next character in text + //aligns with the last occurrence of it in pattern. + if shift + lenPattern < lenStr { + shift = shift + lenPattern - chars[text[shift + lenPattern]] + } else { + shift = 1 + } + } else { + shift = shift + max(1, match - chars[text[shift + match]]); + } + } +} + +func main() { + var text string + var pattern string + fmt.Println("Enter the text : ") + fmt.Scan(&text) + fmt.Println("Enter the pattern to search : ") + fmt.Scan(&pattern) + + boyreMoore(text, pattern) + +} + +/*Input : +* Enter the text : +* therethenthat +* Enter the pattern : +* the +* Pattern found at : 0 +* Pattern found at : 8 +*/ diff --git a/Boyer_Moore_Algorithm/Boyer_Moore.kt b/Boyer_Moore_Algorithm/Boyer_Moore.kt new file mode 100644 index 000000000..5bc69cb02 --- /dev/null +++ b/Boyer_Moore_Algorithm/Boyer_Moore.kt @@ -0,0 +1,78 @@ +/* +Boyer Moore String Matching Algorithm in Kotlin +Author: Arkadip Bhattacharya (@darkmatter18) + */ +import java.util.* + +internal object Main { + private var NO_OF_CHARACTERS = 256 + private fun maxOfAAndB(a: Int, b: Int): Int { + return a.coerceAtLeast(b) + } + + private fun badCharacterHeuristic(str: CharArray, size: Int, badcharacter: IntArray) { + + // Initialize all elements of bad character as -1 + var i = 0 + while (i < NO_OF_CHARACTERS) { + badcharacter[i] = -1 + i++ + } + // Fill the actual value of last occurrence of a character + i = 0 + while (i < size) { + badcharacter[str[i].toInt()] = i + i++ + } + } + + // A pattern searching function + private fun search(text: CharArray, pattern: CharArray) { + val m = pattern.size + val n = text.size + val badCharacterHeuristic = IntArray(NO_OF_CHARACTERS) + + // Fill the bad character array by calling the preprocessing function + badCharacterHeuristic(pattern, m, badCharacterHeuristic) + + // s is shift of the pattern with respect to text + var s = 0 + while (s <= n - m) { + var j = m - 1 + + // Keep reducing index j of pattern while characters of pattern and text are matching at this shift s + while (j >= 0 && pattern[j] == text[s + j]) j-- + + // If the pattern is present at current shift, then index j will become -1 after the above loop + s += if (j < 0) { + println("Patterns occur at shift = $s") + + // Shift the pattern so that the next character in text aligns with the last occurrence of it in pattern. + // The condition s+m < n is necessary for the case when pattern occurs at the end of text + if (s + m < n) m - badCharacterHeuristic[text[s + m].toInt()] else 1 + } else maxOfAAndB(1, j - badCharacterHeuristic[text[s + j].toInt()]) + } + } + + /* Driver program*/ + @JvmStatic + fun main(args: Array) { + val sc = Scanner(System.`in`) + var s = sc.nextLine() + val text = s.toCharArray() + s = sc.nextLine() + val pattern = s.toCharArray() + search(text, pattern) + } +} + +/* +Sample Input: +AABAACAADAABAABA +AABA + +Sample Output: +Patterns occur at shift = 0 +Patterns occur at shift = 9 +Patterns occur at shift = 12 + */ diff --git a/Boyer_Moore_Algorithm/Boyer_Moore.php b/Boyer_Moore_Algorithm/Boyer_Moore.php new file mode 100644 index 000000000..83aba52ab --- /dev/null +++ b/Boyer_Moore_Algorithm/Boyer_Moore.php @@ -0,0 +1,81 @@ += 0 && $pattern[$j] == $text[$s + $j]) + $j--; + + // If the pattern is present at current shift, then index j will become -1, so + // Shift the pattern so that the next character in text aligns + // with the last occurrence of it in pattern. + // Else, Shift the pattern so that the bad character in text aligns with + // the last occurrence of it in pattern. + if ($j < 0){ + $arr[$i++] = $s; + $s += ($s + $patternLength < $textLength) ? + $patternLength - $badChar[ord($text[$s + $patternLength])] : 1; + } + else + $s += max(1, $j - $badChar[ord($text[$s + $j])]); + } + + for ($j = 0; $j < $i; $j++) + $result[$j] = $arr[$j]; + return $result; +} + +// Sample Input +$text = "I scream, you scream, we all scream for ice cream"; +$pattern = "scream"; + +$occ = search($text, $pattern); +echo "Occurrences of pattern in text are as follows:\n"; +foreach ($occ as $res){ + echo "$res \n"; +} + +/* +Sample Input as mentioned in the code- +$text = "I scream, you scream, we all scream for ice cream" +$pattern = "scream" + +Sample Output- +Occurrences of pattern in text are as follows: +2 +14 +29 +8 +*/ +?> + + diff --git a/Boyer_Moore_Algorithm/Readme.md b/Boyer_Moore_Algorithm/Readme.md new file mode 100644 index 000000000..f86721f1e --- /dev/null +++ b/Boyer_Moore_Algorithm/Readme.md @@ -0,0 +1,137 @@ +# Boyer Moore Algorithm +The Boyer Moore Algorithm was established by Robert Boyer and J Strother Moore in 1977. The Boyer Moore (B-M) String search algorithm is a particularly efficient algorithm and has served as a standard benchmark for string search algorithm ever since.The algorithm takes a 'backward' approach: the pattern string (P) is aligned with the start of the text string (T), and then compares the characters of a pattern from right to left, beginning with rightmost character.If a character is compared that is not within the pattern, no match can be found by analyzing any further aspects at this position so the pattern can be changed entirely past the mismatching character. +## **Explanation** +The B-M algorithm ,for deciding the possible shifts, uses two preprocessing strategies simultaneously. Whenever a mismatch occurs, the algorithm calculates a variation using both approaches and selects the more significant shift thus, if make use of the most effective strategy for each case. +The two strategies are called heuristics of B - M as they are used to reduce the search. They are: +1) Bad Character Heuristics +2) Good Suffix Heuristics + + ***Bad Character Heuristic*** +The idea of bad character heuristic is simple. The character of the text which doesn’t match with the current character of the pattern is called the Bad Character. Upon mismatch, we shift the pattern until – +1) The mismatch becomes a match +2) Pattern P move past the mismatched character. ++ Case 1 – Mismatch become match +We will lookup the position of last occurrence of mismatching character in pattern and if mismatching character exist in pattern then we’ll shift the pattern such that it get aligned to the mismatching character in text T. +![Pic01](https://media.geeksforgeeks.org/wp-content/uploads/bad_match_heuristic_case_1.jpg) ++ Case 2 – Pattern move past the mismatch character +We’ll lookup the position of last occurrence of mismatching character in pattern and if character does not exist we will shift pattern past the mismatching character. +![Pic02](https://media.geeksforgeeks.org/wp-content/uploads/bad_match_heuristic_case_2.jpg) + + ***Good Suffix Heuristic*** + Let t be substring of text T which is matched with substring of pattern P. Now we shift pattern until : + 1) Another occurrence of t in P matched with t in T. + 2) A prefix of P, which matches with suffix of t + 3) P moves past t ++ Case 1: Another occurrence of t in P matched with t in T +Pattern P might contain few more occurrences of t. In such case, we will try to shift the pattern to align that occurrence with t in text T. For example- +![Pic03](https://media.geeksforgeeks.org/wp-content/uploads/1-36.jpg) ++ Case 2: A prefix of P, which matches with suffix of t in T +It is not always likely that we will find the occurrence of t in P. Sometimes there is no occurrence at all, in such cases sometimes we can search for some suffix of t matching with some prefix of P and try to align them by shifting P. For example – +![Pic04](https://media.geeksforgeeks.org/wp-content/uploads/2-32.jpg) ++ Case 3: P moves past t +If the above two cases are not satisfied, we will shift the pattern past the t. For example – +![Pic05](https://media.geeksforgeeks.org/wp-content/uploads/3-19.jpg) +## Algorithm +``` +fullSuffixMatch(shiftArray, borderArray, pattern) + +Input: Array to store shift locations, the border array and the pattern to search + +Output: Fill the shift array and the border array + +Begin + n := pattern length + j := n + j := n + 1 + borderArray[i] := j + + while i > 0, do + while j <= n AND pattern[i - 1] ≠ pattern[j - 1], do + if shiftArray[j] = 0, then + shiftArray[j] := j - i; + j := borderArray[j]; + done + + decrease i and j by 1 + borderArray[i] := j + done +End + +partialSuffixMatch(shiftArray, borderArray, pattern) + +Input: Array to store shift locations, the border array and the pattern to search + +Output: Fill the shift array and the border array + +Begin + n := pattern length + j := borderArray[0] + + for index of all characters ‘i’ of pattern, do + if shiftArray[i] = 0, then + shiftArray[i] := j + if i = j then + j := borderArray[j] + done +End + +searchPattern(text, pattern) + +Input: The main text and the pattern, that will be searched + +Output: The indexes where the pattern is found + +Begin + patLen := pattern length + strLen := text size + + for all entries of shiftArray, do + set all entries to 0 + done + + call fullSuffixMatch(shiftArray, borderArray, pattern) + call partialSuffixMatch(shiftArray, borderArray, pattern) + shift := 0 + + while shift <= (strLen - patLen), do + j := patLen -1 + while j >= 0 and pattern[j] = text[shift + j], do + decrease j by 1 + done + + if j < 0, then + print the shift as, there is a match + shift := shift + shiftArray[0] + else + shift := shift + shiftArray[j + 1] + done +End +``` +## Examples + Input: txt[] = "THIS IS A TEST TEXT" + pat[] = "TEST" + Output: Pattern found at index 10 + Input: txt[] = "AABAACAADAABAABA" + pat[] = "AABA" + Output: Pattern found at index 0 + Pattern found at index 9 + Pattern found at index 12 + + ![Pic06](https://media.geeksforgeeks.org/wp-content/cdn-uploads/Pattern-Searching-2.png) +## Time Complexity + Preprocessing Time Complexity: O(|∑|) + Matching Time Complexity: (O ((n - m + 1) + |∑|)) +## Implementation +- [C Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/da4a40a70f/Boyer_Moore_Algorithm/Boyer_Moore.c) +- [C++ Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/da4a40a70f/Boyer_Moore_Algorithm/Boyer_Moore.cpp ) +- [C# Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/da4a40a70f/Boyer_Moore_Algorithm/Boyer_Moore.cs) +- [Go Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/da4a40a70f/Boyer_Moore_Algorithm/Boyer_Moore.go) +- [Java Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/da4a40a70f/Boyer_Moore_Algorithm/Boyer_Moore.java) +- [Kotlin Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/da4a40a70f/Boyer_Moore_Algorithm/Boyer_Moore.kt) +- [Python Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/da4a40a70f/Boyer_Moore_Algorithm/Boyer_Moore.py) +## References ++ Image source: [https://www.geeksforgeeks.org/boyer-moore-algorithm-for-pattern-searching/](https://www.geeksforgeeks.org/boyer-moore-algorithm-for-pattern-searching/) +#### Websites: +1. [https://www.javatpoint.com/daa-boyer-moore-algorithm](https://www.javatpoint.com/daa-boyer-moore-algorithm) +2. [https://www.cs.auckland.ac.nz/courses/compsci369s1c/lectures/GG-notes/CS369-StringAlgs.pdf](https://www.cs.auckland.ac.nz/courses/compsci369s1c/lectures/GG-notes/CS369-StringAlgs.pdf) +3. [geeksforgeeks.org/boyer-moore-algorithm-good-suffix-heuristic/?ref=rp](geeksforgeeks.org/boyer-moore-algorithm-good-suffix-heuristic/?ref=rp) diff --git a/Breadth_First_Search/BFS_in_Csharp.cs b/Breadth_First_Search/BFS_in_Csharp.cs new file mode 100644 index 000000000..aa25d7319 --- /dev/null +++ b/Breadth_First_Search/BFS_in_Csharp.cs @@ -0,0 +1,133 @@ +//Breadth First Search ALgorithm implemented using queue in C# + +using System; +// for generic data structures +using System.Collections.Generic; + +namespace GraphBfs +{ + class graph + { //no of vertices in a graph + private int vertices; + //declaraing list + private List[] adj; + public graph(int v) + { + //initialising Adjacency List with number of vertices + vertices = v; + adj = new List[v]; + for(int i = 0; i < v; i++) + { + adj[i] = new List(); + } + } + + public void addedge(int c,int v) + { + adj[c].Add(v); + adj[v].Add(c); + } + + // function for Breadth First Search ,starting node as parameter + public void BFS(int v) + { + bool[] visited = new bool[vertices]; + Queue queue = new Queue(); + visited[v] = true; + // enqueuing first node in queue + queue.Enqueue(v); + while(queue.Count != 0) + { + // dequeue node from beginning of queue + v = queue.Dequeue(); + Console.Write(v + " "); + foreach(int i in adj[v]) + { + //only unvisited node pushed into queue + if( !visited[i]) + { + visited[i] = true; + queue.Enqueue(i); + } + } + } + } + } + + class program + { + static void Main(string[] args) + { //Taking input number of vertices + Console.WriteLine("Enter number of vertices in a graph"); + int v = Convert.ToInt32(Console.ReadLine()); + + graph g = new graph(v); + + //Taking input number of edges + Console.WriteLine("Enter number of edge in a graph"); + int e = Convert.ToInt32(Console.ReadLine()); + + for(int i = 0; i < e; i++) + { + Console.WriteLine("Enter nodes of " + (i+1) +" edge"); + string s = Console.ReadLine(); + + int e1 = Convert.ToInt32(s.Split(" ")[0]); + int e2 = Convert.ToInt32(s.Split(" ")[1]); + + g.addedge(e1, e2); + } + Console.WriteLine("Breadth First Search of Graph :-"); + //calling BFS function with starting node provided + g.BFS(0); + } + } +} + +/*Sample Input and Output + +Enter number of vertices in a graph +10 +Enter number of edge in a graph +12 +Enter nodes of 1 edge +0 1 +Enter nodes of 2 edge +0 2 +Enter nodes of 3 edge +1 3 +Enter nodes of 4 edge +2 4 +Enter nodes of 5 edge +2 5 +Enter nodes of 6 edge +3 6 +Enter nodes of 7 edge +6 4 +Enter nodes of 8 edge +4 5 +Enter nodes of 9 edge +4 7 +Enter nodes of 10 edge +7 8 +Enter nodes of 11 edge +7 9 +Enter nodes of 12 edge +8 9 +Breadth First Search of Graph :- +0 1 2 3 4 5 6 7 8 9 + +Adjacency List of Sample Input + +0 -> 1,2 +1 -> 0,3 +2 -> 0,4,5 +3 -> 1,6 +4 -> 2,6,5,7, +5 -> 2,4 +6 -> 3,4 +7 -> 4,8,9 +8 -> 7,9 +9 -> 7,8 + +*/ diff --git a/Breadth_First_Search/Breadth_First_Search.dart b/Breadth_First_Search/Breadth_First_Search.dart new file mode 100644 index 000000000..895b1f5f3 --- /dev/null +++ b/Breadth_First_Search/Breadth_First_Search.dart @@ -0,0 +1,99 @@ +// Required library to use inbuilt queues in Dart +import 'dart:collection'; +// Required library to use standard output facility of dart +import 'dart:io'; + +// Function to find the breadth first search of a graph +void Breadth_First_Search( var graph, int source, int no_vertices ) { + // Queue to order nodes levelwise or breadthwise + var queue = Queue(); + // A list to keep track of visited nodes + var visited = new List(no_vertices); + // Initializing the list + for(int i = 0; i < no_vertices; i++){ + visited[i] = 0; + } + // Adding the source node to queue + queue.add(source); + // Marking the node visited + visited[source] = 1; + int val; + + while(queue.isNotEmpty){ + val = queue.removeFirst(); + stdout.write("$val "); + + //Visiting neighbours of the dequed node + for(int i = 0; i < no_vertices; i++){ + if(graph[val][i] == 1 && visited[i] == 0){ + queue.add(i); + visited[i] = 1; + } + } + } +} + +// Driver method of the program +void main() { + + // Reading from the standard input + print("Which graph do you want to enter ( directed/ undirected ):"); + String mode = stdin.readLineSync().toString(); + + print("Enter number of vertices:"); + var input = stdin.readLineSync(); + int no_vertices = int.parse(input); + + // Graph is implemented as adjacency matrix. + var graph = new List.generate(no_vertices, (_) => new List(no_vertices)); + for(int i = 0; i < no_vertices; i++){ + for(int j = 0; j < no_vertices; j++){ + graph[i][j] = 0; + } + } + + print("Enter number of edges:"); + var input1 = stdin.readLineSync(); + int no_edges = int.parse(input); + print("Enter source and destination vertices of edges:\n"); + print("Note: Enter source and destination vertices as 0,1,2,..."); + + for(int i = 1; i <= no_edges; i++){ + + print("Edge #$i:"); + + print("Enter source vertex:"); + int source = int.parse(stdin.readLineSync()); + + print("Enter destination vertex:"); + int destination = int.parse(stdin.readLineSync()); + + if(mode == "undirected"){ + graph[source][destination] = 1; + graph[destination][source] = 1; + } + else { + graph[source][destination] = 1; + } + + } + + print("Enter the source vertex from which BFS should begin:"); + int source1 = int.parse(stdin.readLineSync()); + + // Sample input graph + // 0 - 1 - 2 + // | / + // 3 - 4 + + print("Vertices in Breadth First Search of the graph in sample input is: "); + + // Breadth First Search of the above graph + Breadth_First_Search(graph,source1,no_vertices); + + // Sample Output + // 0 1 3 2 4 + +} + + diff --git a/Breadth_First_Search/Breadth_First_Search.rb b/Breadth_First_Search/Breadth_First_Search.rb new file mode 100644 index 000000000..e2548423c --- /dev/null +++ b/Breadth_First_Search/Breadth_First_Search.rb @@ -0,0 +1,92 @@ +## Breadth First Search algorithm in Ruby. + +def breadth_first_search(adj_matrix, source, destination) + node_array = [source] + path = [] + ## puts "\nThe initial NODE ARRAY is #{node_array}." + + loop do + curr_node = node_array.pop + path << curr_node + ## puts "The next node to be checked is #{curr_node}." + + if curr_node.nil? + puts 'Destination Node Not Found!' + return false + + elsif curr_node == destination + puts "\nDestination Node #{curr_node} Found!" + puts "\nThe path between Source Node #{source} and Destination Node #{destination} is:\n #{path}." + return true + + end + + ## puts "\nIterating through the following array:\n #{adj_matrix[curr_node]}" + children = (0..adj_matrix.length - 1).to_a.select do |i| + ## puts "Checking index #{i} whose value is #{adj_matrix[curr_node][i]}" + adj_matrix[curr_node][i] == 1 + + end + + ## puts "\nCHILD ARRAY returned: #{children}" + node_array = children + node_array + ## puts "\nAfter appending CHILD ARRAY, NODE ARRAY is: #{node_array}" + + end + +end + +## Defining Adjacency Matrix by taking user input + +puts "Enter Size of Adjacency Matrix: " +size = gets.to_i + +adj_matrix = Array.new(size) { [] } + +i = 0 +counter = 0 + +while(counter != size) + i = 0 + puts "\nEnter the values of row #{counter + 1}: " + while(i != size) + adj_matrix[counter][i] = gets.to_i + i += 1 + end + counter += 1 +end + +## User input for Source Node and Destination Node + +puts "\nEnter Source Node: " +source = gets.to_i + +puts "\nEnter Destination Node: " +destination = gets.to_i + +## Passing the adjacent matrix, source and destination as arguments to the algorithm. + +breadth_first_search(adj_matrix, source, destination) + +=begin + +Enter Size of Adjacency Matrix: 4 + +Enter the values of row 1: 0 1 1 0 + +Enter the values of row 2: 1 0 0 0 + +Enter the values of row 3: 1 0 1 0 + +Enter the values of row 4: 0 1 0 0 + +Enter Source Node: 0 + +Enter Destination Node: 2 + +Destination Node 2 Found! + +The path between Source Node 0 and Destination Node 2 is: + [0, 2]. + +=end diff --git a/Bubble_Sort/Bubble_Sort.cpp b/Bubble_Sort/Bubble_Sort.cpp index 7c0f90d72..2ad496eae 100644 --- a/Bubble_Sort/Bubble_Sort.cpp +++ b/Bubble_Sort/Bubble_Sort.cpp @@ -44,7 +44,7 @@ int main() cout<<"Enter number of elements in your array: "; cin>>num; int array[num]; - cou<<"Enter your array: "; + cout<<"Enter your array: "; for (int i = 0; i < num; i++) { cin>>array[i]; diff --git a/Bubble_Sort/Bubble_Sort.rs b/Bubble_Sort/Bubble_Sort.rs new file mode 100644 index 000000000..c6ecd9053 --- /dev/null +++ b/Bubble_Sort/Bubble_Sort.rs @@ -0,0 +1,48 @@ +use std::io; +use std::str::FromStr; + +fn main() { + println!("Enter the numbers to be sorted (separated by space) : "); + let i = read_values::().unwrap(); + let a = bubble_sort(i); + println!("Sorted array: {:?}", a) + } + +fn bubble_sort(mut a: Vec) -> Vec { + for _ in 0..a.len() { + let mut flag = false; + for j in 0..a.len() - 1 { + if a[j] > a[j + 1] { + let temp = a[j]; + a[j] = a[j + 1]; + a[j + 1] = temp; + flag = true + } + } + if !flag { + break; + } + } + a +} + +fn read_values() -> Result, T::Err> { + let mut s = String::new(); + io::stdin() + .read_line(&mut s) + .expect("could not read from stdin"); + s.trim() + .split_whitespace() + .map(|word| word.parse()) + .collect() +} + +/* + + Output : + Enter the numbers to be sorted (separated by space) : + 5 2 8 6 89 + Sorted array: [2, 5, 6, 8, 89] + +*/ + diff --git a/Bucket_Sort/Bucket_Sort.go b/Bucket_Sort/Bucket_Sort.go new file mode 100644 index 000000000..7a7d11022 --- /dev/null +++ b/Bucket_Sort/Bucket_Sort.go @@ -0,0 +1,104 @@ +/* + Bucket Sort Implementation in GO + --------------------------------------------------- + Bucket Sort + --------------------------------------------------- +Bucket Sort is a sorting technique that sorts the elements by first dividing the elements into several groups called buckets. +The elements inside each bucket are sorted using any of the suitable sorting algorithms or recursively calling the same algorithm. +Several buckets are created. Each bucket is filled with a specific range of elements. +The elements inside the bucket are sorted using any other algorithm. Finally, the elements of the bucket are gathered to get the sorted array. +The process of bucket sort can be understood as a scatter-gather approach. The elements are first scattered into buckets then +the elements of buckets are sorted. + +Bucket sort is used when: +-> input is uniformly distributed over a range. +-> there are floating point values +*/ + + +package main + +import ( + "fmt" + "os" + "strconv" +) + +func insertionSort(array []float64) { + for i := 0; i < len(array); i++ { + temp := array[i] + j := i - 1 + for ; j >= 0 && array[j] > temp; j-- { + array[j + 1] = array[j] + } + array[j + 1] = temp + } +} + +func bucketSort(array []float64, bucketSize int) []float64 { + var max, min float64 + for _, n := range array { + if n < min { + min = n + } + if n > max { + max = n + } + } + + nBuckets := int(max-min) / bucketSize + 1 + buckets := make([][]float64, nBuckets) + for i := 0; i < nBuckets; i++ { + buckets[i] = make([]float64, 0) + } + + for _, n := range array { + idx := int(n-min) / bucketSize + buckets[idx] = append(buckets[idx], n) + } + + sorted := make([]float64, 0) + for _, bucket := range buckets { + if len(bucket) > 0 { + insertionSort(bucket) + sorted = append(sorted, bucket...) + } + } + return sorted +} + +func main() { + var x int + fmt.Printf("Enter the size of the array : ") + fmt.Scan(&x) + fmt.Printf("Enter the elements of the array : ") + a := make([]float64, x) + for i := 0; i < x; i++ { + fmt.Scan(&a[i]) + } + + array := a // A copy of the array 'a' is assigned to 'array' + for _, arg := range os.Args[1:] { + if n, err := strconv.ParseFloat(arg, 64); err == nil { + array = append(array, n) + } + } + + fmt.Printf("The array before sorting is %v\n", array) + array = bucketSort(array, 5) + fmt.Printf("The array after sorting is %v\n", array) +} + + +/* + + Sample Input : + Enter the size of the array : 3 + Enter the elements of the array : 2 8 5 + + Sample Output : + The array before sorting is [2 8 5] + The array after sorting is [2 5 8] + +*/ + diff --git a/Bucket_Sort/Bucket_Sort.js b/Bucket_Sort/Bucket_Sort.js new file mode 100644 index 000000000..ee9a8c90e --- /dev/null +++ b/Bucket_Sort/Bucket_Sort.js @@ -0,0 +1,64 @@ +/* + Bucket sort is a comparison sort algorithm that operates on elements by dividing + them into different buckets and then sorting these buckets individually. +*/ + +const insertionSort = arr => { + let i, j; + for (i = 1; i < arr.length; i++) { + let currentVal = arr[i]; + for (j = i - 1; j >= 0; j--) { + if (currentVal > arr[j]) { + break; + } + else { + arr[j + 1] = arr[j]; + } + } + arr[j + 1] = currentVal; + } + return arr; +} + +const bucketSort = arr => { + + if (arr.length === 0) { + return arr; + } + + // finding minimum and maximum value and setting bucket size + let minValue = Math.min(...arr); + let maxValue = Math.max(...arr); + let bucketSize = 10; + + let bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1; + + let buckets = Array.from({ length: bucketCount }, () => []); + + // Pushing values to buckets + for (let i = 0; i < arr.length; i++) { + let index = Math.floor((arr[i] - minValue) / bucketSize); + buckets[index].push(arr[i]); + } + + // reset the input array to store sorted result + arr.length = 0; + + // sort individual buckets and put the elements onto the array + buckets.forEach(function (bucket) { + insertionSort(bucket); + bucket.forEach(function (value) { + arr.push(value) + }); + }); + + return arr; +} + +// I/P and O/P examples + +// [ -11, -10, -1, 2, 4 ] +console.log(bucketSort([-1, 2, 4, -10, -11])); + +// [ -11, -10, 4, 100, 200 ] +console.log(bucketSort([100, 200, 4, -10, -11])); \ No newline at end of file diff --git a/Bucket_Sort/Bucket_Sort.rb b/Bucket_Sort/Bucket_Sort.rb new file mode 100644 index 000000000..92c906c86 --- /dev/null +++ b/Bucket_Sort/Bucket_Sort.rb @@ -0,0 +1,36 @@ +DEFAULT_BUCKET_SIZE = 5 + +def bucket_sort(input, bucket_size = DEFAULT_BUCKET_SIZE) + print 'Array is empty' if input.empty? + + array = input.split(' ').map(&:to_i) + + bucket_count = ((array.max - array.min) / bucket_size).floor + 1 + + # create buckets + buckets = [] + bucket_count.times { buckets.push [] } + + # fill buckets + array.each do |item| + buckets[((item - array.min) / bucket_size).floor].push(item) + end + + # sort buckets + buckets.each(&:sort!) + + buckets.flatten.join(' ') +end + +puts 'Enter a list of numbers (separated by space) : ' +list = gets +puts 'The sorted list is : ' +print bucket_sort(list) + + +# Output : +# Enter a list of numbers (separated by space) : +# 7 9 5 4 1 +# The sorted list is : +# 1 4 5 7 9 + diff --git a/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.dart b/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.dart new file mode 100644 index 000000000..ec990892c --- /dev/null +++ b/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.dart @@ -0,0 +1,119 @@ +/* + Dart program to implement Chinese Remainder Theorem (CRT) + --------------------------------------------------------------------- + + Chinese Remainder Theorem + --------------------------------------------------------------------- + + The Chinese Remainder Theorem ( based on Extended Euclid's algorithm ) states that a set of 'k' congruency equations with a single variable + as follows + + x % num[0] = rem[0] + x % num[1] = rem[1] + . + . + . + x % num[k] = rem[k] + + can be solved by using the formula, x = ( sum(rem[i]*pd[i]*inv[i]) for all i ) % product where + + product is the product of all numbers in num array + rem[i] is the i'th remainder in the given input, + pd[i] is the value of product divided by num[i], + inv[i] is the modulo inverse of pd[i] and num[i], + sum() is a function that sums up the values. + + Here, the obtained solution is minimum possible x. + +*/ + +// Importing required libraries. +import 'dart:io'; + +// Function to calculate modulo inverse. +int modular_inverse(int a, int m){ + + // Temporary variable to store m to use later. + int temp = m; + + if (m == 1){ + return 0; + } + + int y = 0, x = 1, temp2, quotient, remainder; + + // Calculating x and y based on Euclid's algorithm + while (a > 1){ + quotient = (a / m).floor(); + remainder = a % m; + a = m; + m = remainder; + temp2 = y; + y = x - quotient * y; + x = temp2; + } + + // Making x positive if found negative + if (x < 0){ + x += temp; + } + + return x; +} + +// Driver function of the program +void main(){ + + // Taking input of the number array (num[i]). + print("Enter array of pairwise co-prime numbers:"); + + var input = stdin.readLineSync(); + var lis = input.split(' '); + List numbers = lis.map(int.parse).toList(); + + // Taking input of remainder array (rem[i]). + print("Enter remainders:"); + + input = stdin.readLineSync(); + lis = input.split(' '); + List remainders = lis.map(int.parse).toList(); + + int product = 1; + + // Length of the 'numbers' list. + int length = numbers.length; + + // Finding product of all the numbers. + for (int i = 0; i < length; i ++){ + product *= numbers[i]; + } + + int temp, result = 0; + + // Summing the required values for all i according to the formula. + for (int i = 0; i < length; i ++){ + temp = (product / numbers[i]).floor(); + result += temp * (remainders[i]) * modular_inverse(temp,numbers[i]); + } + + result = result % product; + + // Printing result + print("The value of 'x' by Chinese Remainder Theorem is $result."); + +} + +/* + Sample Input + + Enter array of pairwise co-prime numbers: + 9 8 5 7 1 + Enter remainders: + 1 2 3 4 5 + + Sample Output + + The value of 'x' by Chinese Remainder Theorem is 298. + +*/ + diff --git a/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.go b/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.go new file mode 100644 index 000000000..389734a93 --- /dev/null +++ b/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.go @@ -0,0 +1,93 @@ +/* Chinese Remainder Theorem : +* Given two arrays number[0..n-1] and remainder[0..n-1] +* Find the minimum possible value of x +* that produces given remainders, i.e +* x % number[0] = remainder[0] +* x % number[1] = remainder[1] and so on. +*/ + +package main + +import "fmt" + +//Extended Euclid Algorithm +func inverse(a int, m int) (x1 int) { + var m0 int = m + x0 := 0 + x1 = 1 + var quotient int + var next int + + if m == 1 { + return 0 + } + + // while the number is greater than 1 + // keep on making (a,m) = (m,a%m) + // Go on reverse to find out x0 and x1 from there. + // where x1 will be the inverse modulo + for a > 1 { + quotient = a / m; next = m + m = a % m + a = next; next = x0 + x0 = x1 - quotient * x0 + x1 = next + } + + if x1 < 0 { + x1 = x1 + m0 + } + + return x1 +} + +func CRT(number []int, rem []int, k int) int { + var prod int = 1 + var prod_exp int + + for i := 0; i < k; i++ { + prod = prod * number[i] + } + + var result int = 0 + + // Optimized CRT formula + for i := 0; i < k; i++ { + prod_exp = prod / number[i] + result = result + rem[i] * inverse(prod_exp, number[i]) * prod_exp + } + + return result % prod +} + +func main() { + var n int + fmt.Println("Enter the size of the array : ") + fmt.Scan(&n) + fmt.Println("Enter the number array : ") + num := make([]int, n) + + for i := 0; i < n; i++ { + fmt.Scan(&num[i]) + } + + fmt.Println("Enter the remainder array : ") + rem := make([]int, n) + + for i := 0; i < n; i++ { + fmt.Scan(&rem[i]) + } + + fmt.Printf("Minimum positive number x is : %d\n", CRT(num, rem, n)) +} + +/* Input : +Enter the size of the array : +3 +Enter the number array : +4 11 9 +Enter the remainder array : +1 2 4 +Output : +Minimum positive number x is : 13 +*/ diff --git a/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.php b/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.php new file mode 100644 index 000000000..0275718e9 --- /dev/null +++ b/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.php @@ -0,0 +1,57 @@ + + diff --git a/Chinese_Remainder_Theorem/Chinese_remainder_theorem.c b/Chinese_Remainder_Theorem/Chinese_remainder_theorem.c new file mode 100644 index 000000000..0ace268c5 --- /dev/null +++ b/Chinese_Remainder_Theorem/Chinese_remainder_theorem.c @@ -0,0 +1,64 @@ +#include + +//function to find minimum number such that num%divisor[i] gives corresponding remainder[i] +int minresult( int divisor[], int rem[], int size) +{ + int m = 1, M[size], inv[size], i, k, count, x = 0; + for (i = 0; i < size; i++) + { + m = m * divisor[i]; + } + for (i = 0; i < size; i++) + { + M[i] = m / divisor[i]; + } + for (i = 0; i < size; i++) + { + count = 0; + k = 1; + do + { + if(((M[i] % divisor[i]) * k) % divisor[i] == 1) + { + inv[i] = k; + count++; + } + k++; + }while(count == 0); + } + for (i = 0; i < size; i++) + { + x = x + (rem[i] * M[i] * inv[i]); //according to CRT + } + x = x % m; + return x; +} + +int main() +{ + int size, i, divisor[100], rem[100]; + //input size of array in variable size + printf("Enter size of array:"); + scanf("%d", &size); + //input divisor values and then remainder values + printf("Enter value of coprime divisors:"); + for (i = 0; i < size; i++ ) + { + scanf("%d", &divisor[i]); + } + printf("Enter value of remainders:"); + for (i = 0; i < size; i++ ) + { + scanf("%d", &rem[i]); + } + //function call to find result. + printf("Answer is: %d ", minresult( divisor, rem, size)); + return 0; +} + +/* Sample input-output: +Enter size of array:3 +Enter value of coprime divisors:2 3 5 +Enter value of remainders:1 2 4 +Answer is: 29 +*/ diff --git a/Chinese_Remainder_Theorem/Readme.md b/Chinese_Remainder_Theorem/Readme.md new file mode 100644 index 000000000..136c5d072 --- /dev/null +++ b/Chinese_Remainder_Theorem/Readme.md @@ -0,0 +1,116 @@ +# Chinese Remainder Theorem + +If m1, m2, .., mk are pairwise relatively prime positive integers, and if a1, a2, .., ak are any integers, then the simultaneous congruences x ≡ a1 (mod m1), x ≡ a2 (mod m2), ..., x ≡ ak (mod mk) have a solution, and the solution is unique modulo m, where m = m1m2⋅⋅⋅mk . + +**Problem Statement :** + +We are given two arrays num[0..n-1] and rem[0..n-1]. In num[0..n-1], every pair is coprime (gcd for every pair is 1). We need to find minimum positive number x such that: + + x % num[0] = rem[0], + x % num[1] = rem[1], + x % num[2] = rem[2], + ....................... + x % num[n-1] = rem[n-1] + +## Algorithm + +The solution is based on the below given formula : + + x = sum of { (rem[i]* pp[i]* inv[i]) % prod } where 0 <= i <= n-1 + + where, + + rem[i] is given array of remainders + + prod is product of all given numbers + prod = num[0] * num[1] * ... * num[k-1] + + pp[i] is product of all divided by num[i] + pp[i] = prod / num[i] + + inv[i] = Modular Multiplicative Inverse of pp[i] with respect to num[i] + + +## Example + +![Pic01](https://i.pinimg.com/474x/f4/62/23/f46223a470eb8f967b3be60f8a255c6e--chinese-remainder-theorem-the-chinese.jpg) + +Consider the above given example for understanding **Chinese Remainder Theorem**. + + Input : num[] = {3, 5, 7}, rem[] = {1, 2, 3} + output : x = 52 + + Explanation: 52 is the smallest number such that: + (1) When we divide it by 3, we get remainder 1. + (2) When we divide it by 5, we get remainder 2 + (3) When we divide it by 7, we get remainder 3. + + +Let us consider an example for a better understanding of **above given formula**. + + Input: num[] = {3, 5, 7}, rem[] = {1, 2, 3} + Output: x = 52 + + Explanation: num[] = {3, 5, 7}, rem[] = {1, 2, 3} + prod = 3*5*7 = 105 + pp[] = {35, 21, 15} + inv[] = {2, 1, 1} // (35*2)%3 = 1, (21*1)%5 = 1, // (15*1)%7 = 1 + + x = (rem[0]* pp[0]* inv[0] + rem[1]* pp[1]* inv[1] + rem[2]* pp[2]* inv[2]) % prod + = (1*35*2 + 2*21*1 + 3*15*1) % 105 + = (70 + 42 + 45) % 105 + = 52 + +## Pseudo Code + +The code is a simple 4-step process followed to find the solution : + + STEP 1 : Find the Product of all the numbers given in num[]. + STEP 2 : Find the number which is equal to Product divided by num[i] and store it in pp[i]. + STEP 3 : Find the Modular Multiplicative Inverse of pp[i] with respect to num[i] and store it + in inv[i]. + STEP 4 : Multiply rem[i] with the product of pp[i] and inv[i] for all 0 <= i <= n-1 and + add them. This is our required Output. + + +## Complexity + + Time complexity : __O(n*log(max(a,b))__ , where + +* __n__ is the total number of elements in the array. +* __a__ is the maximum value in __num[ ]__ +* __b__ is the minimum value in __rem[ ]__ + + +## Implementation + +- [C Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Chinese_Remainder_Theorem/Chinese_remainder_theorem.c) + +- [CoffeeScript code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.coffee) + +- [C++ Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.cpp) + +- [C# Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.cs) + +- [Dart Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.dart) + +- [Go Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.go) + +- [Java Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.java) + +- [JavaScript Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.js) + +- [PHP Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.php) + +- [Python Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Chinese_Remainder_Theorem/Chinese_Remainder_Theorem.py) + +### Refer this [link](https://www.youtube.com/watch?v=ru7mWZJlRQg) to know more! + +## References + +Image source: [https://www.storyofmathematics.com/chinese.html](https://www.storyofmathematics.com/chinese.html) + +#### Websites: +1. [http://homepages.math.uic.edu/~leon/mcs425-s08/handouts/chinese_remainder.pdf](http://homepages.math.uic.edu/~leon/mcs425-s08/handouts/chinese_remainder.pdf) +2. [https://www.geeksforgeeks.org/chinese-remainder-theorem-set-2-implementation/](https://www.geeksforgeeks.org/chinese-remainder-theorem-set-2-implementation/) +3. [https://medium.com/free-code-camp/how-to-implement-the-chinese-remainder-theorem-in-java-db88a3f1ffe0](https://medium.com/free-code-camp/how-to-implement-the-chinese-remainder-theorem-in-java-db88a3f1ffe0) diff --git a/Circle_Sort/Circle_Sort.kts b/Circle_Sort/Circle_Sort.kts new file mode 100644 index 000000000..382c01749 --- /dev/null +++ b/Circle_Sort/Circle_Sort.kts @@ -0,0 +1,55 @@ +fun> circleSort(array: Array, lo: Int, hi: Int, nSwaps: Int): Int { + if (lo == hi) return nSwaps + + fun swap(array: Array, i: Int, j: Int) { + val temp = array[i] + array[i] = array[j] + array[j] = temp + } + + var high = hi + var low = lo + val mid = (hi - lo) / 2 + var swaps = nSwaps + + while (low < high) { + if (array[low] > array[high]) { + swap(array, low, high) + swaps++ + } + low++ + high-- + } + if (low == high) + if (array[low] > array[high + 1]) { + swap(array, low, high + 1) + swaps++ + } + + swaps = circleSort(array, lo, lo + mid, swaps) + swaps = circleSort(array, lo + mid + 1, hi, swaps) + return swaps +} + +fun main(args: Array) { + // -- ExampleArray1 -- + val array = arrayOf(6, 7, 8, 9, 2, 5, 3, 4, 1) + println("Unsorted Array: ${array.asList()}") + while (circleSort(array, 0, array.size - 1, 0) != 0) ; + println("Sorted Array : ${array.asList()}") //Sorted Array + println() + + // -- ExampleArray2 -- + val array2 = arrayOf("the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog") + println("Unsorted Array : ${array2.asList()}") + while (circleSort(array2, 0, array2.size - 1, 0) != 0) ; + println("Sorted Array : ${array2.asList()}") //Sorted Array +} + + +//output +Unsorted Array: [6, 7, 8, 9, 2, 5, 3, 4, 1] +Sorted Array : [1, 2, 3, 4, 5, 6, 7, 8, 9] + +Unsorted Array : [the, quick, brown, fox, jumps, over, the, lazy, dog] +Sorted Array : [brown, dog, fox, jumps, lazy, over, quick, the, the] diff --git a/Circle_Sort/Circle_Sort.php b/Circle_Sort/Circle_Sort.php new file mode 100644 index 000000000..8545d9470 --- /dev/null +++ b/Circle_Sort/Circle_Sort.php @@ -0,0 +1,85 @@ + $a[$hi]) + { + $temp = $a[$lo]; + $a[$lo] = $a[$hi]; + $a[$hi] = $temp; + $swapped = true; + } + $lo++; + $hi--; + } + + if($lo == $hi) + if($a[$lo] > $a[$hi + 1]) + { + $t = $a[$low]; + $a[$low] = $a[$hi + 1]; + $a[$hi + 1] = $t; + $swapped = true; + } + + $mid = ($high - $low) / 2; + $firstHalf = circleSortRec($a , $low , $low + $mid); + $secondHalf = circleSortRec($a , $low + $mid + 1 , $high); + return $swapped || $firstHalf || $secondHalf; +} + +function circleSort($a , $n) +{ + + while(circleSortRec($a,0,$n - 1)) + { + ; + } +} + +$a = explode(' ',readline()); +$n = sizeof($a) / sizeof($a[0]); + +echo "Unsorted: "; + +for($i = 0; $i < $n; $i++) +{ + echo "$a[$i] "; +} + +circleSort($a , $n); + +echo "\n Sorted: "; + +for($i = 0; $i < $n; $i++) +{ + echo "$a[$i] "; +} + +return 0; + +/* +Input: +7 5 3 1 2 4 6 8 + +Output: +Unsorted: [6, 5, 3, 1, 8, 7, 2, 4] +Sorted: [1, 2, 3, 4, 5, 6, 7, 8] +*/ + +?> diff --git a/Circle_Sort/Circle_Sort.rb b/Circle_Sort/Circle_Sort.rb new file mode 100644 index 000000000..2a27d7fb3 --- /dev/null +++ b/Circle_Sort/Circle_Sort.rb @@ -0,0 +1,76 @@ +# Circle Sort In Ruby + +class Array + def circle_sort! + while _circle_sort!(0, size - 1) > 0 + end + self + end + + private + def _circle_sort!(lower, higher, swapping = 0) + return swapping if lower == higher + low, high = lower, higher + middle = (lower + higher) / 2 + + while lower < higher + if self[lower] > self[higher] + self[lower], self[higher] = self[higher], self[lower] + swapping += 1 + end + lower += 1 + higher -= 1 + end + + if lower == higher && self[lower] > self[higher+1] + self[lower], self[higher + 1] = self[higher + 1], self[lower] + swapping += 1 + end + + swapping + _circle_sort!(low, middle) + _circle_sort!(middle + 1, high) + end +end + +puts "Enter the size of array: " +size = gets.to_i +puts +input_array = Array.new(size) + +counter = 0 + +while(counter != size) + puts "Enter the value at index #{counter}: " + input_array[counter] = gets.to_i + counter += 1 +end + +puts + +puts "Input Array: #{input_array}" +puts "Circle Sort: #{input_array.circle_sort!}" + += begin + +Enter the size of array: 3 + +Enter the value at index 0: 999 +Enter the value at index 1: 21 +Enter the value at index 2: 58 + +Input Array: [999, 21, 58] +Circle Sort: [21, 58, 999] + +-------------------------------------------------- + +Enter the size of array: 5 + +Enter the value at index 0: 121 +Enter the value at index 1: 71 +Enter the value at index 2: 1 +Enter the value at index 3: 88 +Enter the value at index 4: 9 + +Input Array: [121, 71, 1, 88, 9] +Circle Sort: [1, 9, 71, 88, 121] + += end diff --git a/Circular_Doubly_Linked_List/Circular_Doubly_Linked_List.cpp b/Circular_Doubly_Linked_List/Circular_Doubly_Linked_List.cpp index 8b6d71ce0..3551c1e33 100644 --- a/Circular_Doubly_Linked_List/Circular_Doubly_Linked_List.cpp +++ b/Circular_Doubly_Linked_List/Circular_Doubly_Linked_List.cpp @@ -1,131 +1,407 @@ +/** + Code contributed by Hardev Khandhar for GirlScript Summer of Code 2020 + link: https://github.com/HardevKhandhar +*/ + #include using namespace std; -class node{ -private: + +// Declaring the structure of node +struct node +{ int data; - node *next; - node *prev; -public: - node(int d) - { - data=d; - next=NULL; - prev=NULL; - } - friend class Linked_List; + struct node *lptr; + struct node *rptr; }; -class Linked_List + +struct node *HEAD = NULL; + +// Creating a node +node *createNode(int value) { -private: - node *head; -public: - Linked_List() + struct node *ptr; + ptr = new(struct node); + if(ptr == NULL) + { + cout << "Memory Not Allocated!" << endl; + return 0; + } + else { - head=NULL; - } -void insertatbeg(int d) - { - node *n=new node(d); - node*ptr=head; - if(head==NULL) - { - head=n; - n->next=head; - n->prev=n; - } - else - { - head->prev->next=n; - n->prev=head->prev; - n->next=head; - head->prev=n; - head=n; - - } - - - } - void insertatend(int d) + ptr -> data = value; + ptr -> lptr = NULL; + ptr -> rptr = NULL; + return ptr; + } +} + +// Insert node at the beginning of circular-doubly-linked-list +void insertAtFront() { - node *n=new node(d); - head->prev->next=n; - n->prev=head->prev; - n->next=head; + struct node *newNode; + struct node *trav = HEAD; + int value; + cout << "Enter the value to be inserted: "; + cin >> value; + newNode = createNode(value); + if(HEAD == NULL) + { + HEAD = newNode; + newNode -> rptr = HEAD; + } + else + { + newNode -> lptr = NULL; + newNode -> rptr = HEAD; + while(trav -> rptr != HEAD) + { + trav = trav -> rptr; + } + trav -> rptr = newNode; + HEAD = newNode; + } +} + +// Insert node at the end of circular-doubly-linked-list +void insertAtLast() +{ + struct node *newNode; + struct node *trav; + trav = HEAD; + int value; + cout << "Enter the value to be inserted: "; + cin >> value; + newNode = createNode(value); + if(HEAD == NULL) + { + newNode -> lptr = NULL; + HEAD = newNode; + newNode -> rptr = HEAD; + return; + } + else { + while(trav -> rptr != HEAD) + { + trav = trav -> rptr; + } + trav -> rptr = newNode; + newNode -> lptr = trav; + newNode -> rptr = HEAD; + } } - void print() + +// Insert node after a particular node in the circular-doubly-linked-list +void insertAtPosition(int x) +{ + struct node *trav; + struct node *next; + struct node *newNode; + trav = HEAD; + int value; + cout << "Enter the value to be inserted: "; + cin >> value; + newNode = createNode(value); + while(trav -> data != x && trav -> rptr != NULL) { - node *t=head; - do - { - cout<data<<" ->"; - t=t->next; + trav = trav -> rptr; + } + if(trav == NULL) + { + cout << "Desired element not found!" << endl; + } + else + { + next = trav -> rptr; + trav -> rptr = newNode; + newNode -> rptr = next; + newNode -> lptr = trav; + next -> lptr = newNode; + } +} - }while(t!=head); - cout< data << " "; + ptr = ptr -> rptr; } - void insertatK(int d,int k) + while(ptr != HEAD); + cout << endl; +} + +// Delete front node from the list +void deleteAtFront() { - node *n=new node(d); - node *t=head; - node *temp=NULL; - int cnt=1; - while(head==NULL || k==1) + struct node *trav = HEAD; + if(HEAD == NULL) { - insertatbeg(d); + cout << "List is Empty!"; + return; + } + if(HEAD -> rptr == HEAD){ + cout << "Element " << HEAD -> data << " is removed." << endl; + HEAD = NULL; + } + else { + cout << "Element " << HEAD -> data << " is removed." << endl; + while(trav -> rptr != HEAD){ + trav = trav -> rptr; + } + HEAD = HEAD -> rptr; + HEAD -> lptr = NULL; + trav -> rptr = HEAD; + } +} + +// Delete last node from the list +void deleteAtLast() +{ + struct node *trav; + struct node *previous; + trav = HEAD; + if(HEAD == NULL){ + cout << "List is Empty!"; return; } - while(t->next!=NULL && cnt rptr == HEAD) { - temp=t; - t=t->next; - cnt++; - } - n->prev=temp; - n->next=temp->next; - temp->next=n; - t->prev=n; + HEAD = NULL; + } + else { + while(trav -> rptr != HEAD) + { + previous = trav; + trav = trav -> rptr; + } + cout << "Element " << trav -> data << " is removed." << endl; + previous = trav -> lptr; + previous -> rptr = HEAD; + } } -void delatbeg() + +// Delete node from a particular position in the list +void deleteAtPosition(int x) { - node *t=head; - head->prev->next=head->next; - head->next->prev=head->prev; - head=head->next; - t->next=NULL; - delete t; + struct node *trav; + struct node *previous; + struct node *next; + trav = HEAD; + while(trav -> data != x && trav -> rptr != NULL) + { + previous = trav; + trav = trav -> rptr; + } + if(trav == NULL) + { + cout << "Desired element not found!" << endl; + } + else + { + next = trav -> rptr; + previous -> rptr = trav -> rptr; + next -> lptr = previous; + } } -void delatend() + +// Menu driven program +int main() { - node *t; - t=head->prev; - t->prev->next=head; - head->prev=t->prev; - t->next=NULL; - delete t; + int choice, nodes, position, element, i; + cout << "**************************************" << endl; + cout << "* Circular Doubly Linked List *" << endl; + cout << "**************************************\n" << endl; + while(1) + { + cout << "1. Insert node at the beginning" << endl; + cout << "2. Insert node at the end" << endl; + cout << "3. Insert node at given position" << endl; + cout << "4. Delete node at front" << endl; + cout << "5. Delete node at last" << endl; + cout << "6. Delete node at given position" << endl; + cout << "7. Display elements of linked list" << endl; + cout << "8. Exit" << endl; + cout << "\nEnter your choice: "; + cin >> choice; + switch(choice) + { + case 1: + insertAtFront(); + cout << endl; + break; + case 2: + insertAtLast(); + cout << endl; + break; + case 3: + int x; + cout << "Enter the node information: "; + cin >> x; + insertAtPosition(x); + cout << endl; + break; + case 4: + deleteAtFront(); + cout << endl; + break; + + case 5: + deleteAtLast(); + cout << endl; + break; + + case 6: + int y; + cout << "Enter the node information: "; + cin >> y; + deleteAtPosition(y); + cout << endl; + break; + + case 7: + display(); + cout << endl; + break; + + case 8: + cout << "Exit" << endl; + return 0; + break; + + default: + cout << "Invalid Choice!" << endl; + break; + } + } + return 0; } -}; -int main() -{ - Linked_List ll; - int d,c; - char choice; - ll.insertatbeg(1); - ll.insertatbeg(2); - ll.insertatbeg(3); - ll.print(); - ll.insertatend(4); - ll.print(); - // ll.insertatK(10,3); - //ll.print(); - ll.delatend(); - ll.print(); - ll.delatend(); - ll.print(); - // ll.delatend(); - //ll.print(); -} + +/** + +************************************** +* Circular Doubly Linked List * +************************************** + +1. Insert node at the beginning +2. Insert node at the end +3. Insert node at given position +4. Delete node at front +5. Delete node at last +6. Delete node at given position +7. Display elements of linked list +8. Exit + +Enter your choice: 1 +Enter the value to be inserted: 21 + +1. Insert node at the beginning +2. Insert node at the end +3. Insert node at given position +4. Delete node at front +5. Delete node at last +6. Delete node at given position +7. Display elements of linked list +8. Exit + +Enter your choice: 1 +Enter the value to be inserted: 52 + +1. Insert node at the beginning +2. Insert node at the end +3. Insert node at given position +4. Delete node at front +5. Delete node at last +6. Delete node at given position +7. Display elements of linked list +8. Exit + +Enter your choice: 7 +Elements of Doubly Linked List are: 52 21 + +1. Insert node at the beginning +2. Insert node at the end +3. Insert node at given position +4. Delete node at front +5. Delete node at last +6. Delete node at given position +7. Display elements of linked list +8. Exit + +Enter your choice: 2 +Enter the value to be inserted: 99 + +1. Insert node at the beginning +2. Insert node at the end +3. Insert node at given position +4. Delete node at front +5. Delete node at last +6. Delete node at given position +7. Display elements of linked list +8. Exit + +Enter your choice: 3 +Enter the node information: 21 +Enter the value to be inserted: 45 + +1. Insert node at the beginning +2. Insert node at the end +3. Insert node at given position +4. Delete node at front +5. Delete node at last +6. Delete node at given position +7. Display elements of linked list +8. Exit + +Enter your choice: 7 +Elements of Doubly Linked List are: 52 21 45 99 + +1. Insert node at the beginning +2. Insert node at the end +3. Insert node at given position +4. Delete node at front +5. Delete node at last +6. Delete node at given position +7. Display elements of linked list +8. Exit + +Enter your choice: 4 +Element 52 is removed. + +1. Insert node at the beginning +2. Insert node at the end +3. Insert node at given position +4. Delete node at front +5. Delete node at last +6. Delete node at given position +7. Display elements of linked list +8. Exit + +Enter your choice: 5 +Element 99 is removed. + +1. Insert node at the beginning +2. Insert node at the end +3. Insert node at given position +4. Delete node at front +5. Delete node at last +6. Delete node at given position +7. Display elements of linked list +8. Exit + +Enter your choice: 7 +Elements of Doubly Linked List are: 21 45 + +*/ diff --git a/Circular_Queue/Circular_Queue.java b/Circular_Queue/Circular_Queue.java new file mode 100644 index 000000000..10c736364 --- /dev/null +++ b/Circular_Queue/Circular_Queue.java @@ -0,0 +1,248 @@ +/* Circular Queue works by the process of circular increment +i.e. when we try to increment any variable and we reach the end of queue, +we start from the beginning of queue by modulo division with the queue size.*/ + +import java.util.Scanner; + +public class Circular_Queue { + int front, rear, size; + int[] arr; + + public Circular_Queue(int s) { + size = s; + arr = new int[s]; + front = rear = -1; + } + + public static void main(String[] args) { + int choice, value, s; + Scanner in = new Scanner(System.in); + + System.out.println("Enter the size of queue:"); + s = in.nextInt(); + Circular_Queue q = new Circular_Queue(s); + do { + System.out.println("\n1. Insert"); + System.out.println("2. Delete"); + System.out.println("3. Display"); + System.out.println("4. Exit"); + System.out.println("Enter choice: "); + choice = in.nextInt(); + switch (choice) { + case 1: + System.out.println("\nEnter the value: "); + value = in.nextInt(); + q.enQueue(value); + break; + case 2: + value = q.deQueue(); + if(value == -1) { + System.out.println("\nUNDERFLOW! Queue is Empty."); + break; + } + System.out.println("\n" + value + " Deleted from queue."); + break; + case 3: + q.display(); + break; + case 4: + System.exit(0); + default: + System.out.println("Invalid choice."); + + } + } while (choice != 4); + + } + + /* +Insertion: +1) Check whether queue is Full by (front == 0 && rear == size - 1) || (rear == (front - 1) % (size - 1)). +2) If it is full then display Queue is full. If queue is not full then, check + if (front == -1) then set front = rear = 0 and insert the first element. +3) If (rear == SIZE – 1 && front != 0) if it is true then set rear = 0 and insert element. +4) Otherwise increment rear by 1 and insert an element. +*/ +// Inserting the value in the queue + public void enQueue(int value) { + if ((front == 0 && rear == size - 1) || + (rear == (front - 1) % (size - 1))) { + System.out.println("\nOVERFLOW! Queue is Full."); + return; + } else if (front == -1) /* Insert First Element */ { + front = rear = 0; + arr[rear] = value; + } else if (rear == size - 1 && front != 0) { + rear = 0; + arr[rear] = value; + } else { + rear++; + arr[rear] = value; + } + } + + /* +Deletion: +1) Check whether queue is Empty with (front==-1). +2) If it is empty then display Queue is empty. +3) If queue is not empty then remove the element and Check if (front==rear) + if it is true then set front = rear= -1 else set front = (front + 1) % size and return the element. +*/ +// Deleting from queue + public int deQueue() { + if (front == -1) { + return -1; + + } + int element = arr[front]; + arr[front] = -1; + if (front == rear) { + front = -1; + rear = -1; + } + else { + if (front == size - 1) + front = 0; + else + front = front + 1; + } + return element; + } + + // Displaying the queue + public void display() { + if (front == -1) { + System.out.println("UNDERFLOW! Queue is Empty."); + return; + } + System.out.println("\nElements in Circular Queue are: "); + if (rear >= front) { + for (int i = front; i <= rear; i++) + System.out.print(arr[i] + "\t"); + } else { + for (int i = front; i < size; i++) + System.out.println(arr[i] + "\t"); + + for (int i = 0; i <= rear; i++) + System.out.println(arr[i] + "\t"); + } + } + +} +/* +Enter the size of queue: +4 + +1. Insert +2. Delete +3. Display +4. Exit +Enter choice: +1 + +Enter the value: +10 + +1. Insert +2. Delete +3. Display +4. Exit +Enter choice: +1 + +Enter the value: +20 + +1. Insert +2. Delete +3. Display +4. Exit +Enter choice: +1 + +Enter the value: +30 + +1. Insert +2. Delete +3. Display +4. Exit +Enter choice: +1 + +Enter the value: +40 + +1. Insert +2. Delete +3. Display +4. Exit +Enter choice: +1 + +Enter the value: +50 + +OVERFLOW! Queue is Full. + +1. Insert +2. Delete +3. Display +4. Exit +Enter choice: +3 + +Elements in Circular Queue are: +10 20 30 40 +1. Insert +2. Delete +3. Display +4. Exit +Enter choice: +2 + +10 Deleted from queue. + +1. Insert +2. Delete +3. Display +4. Exit +Enter choice: +2 + +20 Deleted from queue. + +1. Insert +2. Delete +3. Display +4. Exit +Enter choice: +2 + +30 Deleted from queue. + +1. Insert +2. Delete +3. Display +4. Exit +Enter choice: +2 + +40 Deleted from queue. + +1. Insert +2. Delete +3. Display +4. Exit +Enter choice: +2 + +UNDERFLOW! Queue is Empty. + +1. Insert +2. Delete +3. Display +4. Exit +Enter choice: +4 + */ diff --git a/Cocktail_Sort/Cocktail_Sort.dart b/Cocktail_Sort/Cocktail_Sort.dart new file mode 100644 index 000000000..a6693449d --- /dev/null +++ b/Cocktail_Sort/Cocktail_Sort.dart @@ -0,0 +1,64 @@ +// Importing required libraries +import 'dart:io'; + +// Function to sort the input list using cocktail sort +void cocktail_sort(List array, int n){ + bool swapped = true; + int start = 0; + int end = n; + while (swapped == true){ + swapped = false; + // Forward swapping + for (int i = start; i < end - 1; i ++){ + if (array[i] > array[i + 1]){ + int temp = array[i]; + array[i] = array[i + 1]; + array[i + 1] = temp; + swapped = true; + } + } + if (swapped == false){ + break; + } + swapped = false; + end = end - 1; + // Reverse swapping + for (int i = end - 1; i >= start; i --){ + if (array[i] > array[i + 1]){ + int temp = array[i]; + array[i] = array[i + 1]; + array[i + 1] = temp; + swapped = true; + } + } + start = start + 1; + } + +} + +// Driver method of the program +void main(){ + // Input of size of the array + print("Enter number of elements in the array:"); + var input = stdin.readLineSync(); + int n = int.parse(input); + // Input of the array elements + print("Enter array elements:"); + input = stdin.readLineSync(); + var lis = input.split(" "); + List array = lis.map(int.parse).toList(); + // Cocktail sorting + cocktail_sort(array, n); + // Printing the output to stdout + print(array.join(" ")); +} + +/** + * Sample Input and Output + * ------------------------------------ + * Enter number of elements in the array: + * 10 + * Enter array elements: + * 10 9 8 7 6 5 4 3 2 1 + * 1 2 3 4 5 6 7 8 9 10 + */ diff --git a/Cocktail_Sort/Cocktail_Sort.rb b/Cocktail_Sort/Cocktail_Sort.rb new file mode 100644 index 000000000..8434b6aa3 --- /dev/null +++ b/Cocktail_Sort/Cocktail_Sort.rb @@ -0,0 +1,70 @@ +# Cocktail Sort In Ruby + +class Array + def cocktailSort! + begin + swap = false + 0.upto(length - 2) do |i| + if self[i] > self[i + 1] + self[i], self[i + 1] = self[i + 1], self[i] + swap = true + end + end + break unless swap + + swap = false + (length - 2).downto(0) do |i| + if self[i] > self[i + 1] + self[i], self[i + 1] = self[i + 1], self[i] + swap = true + end + end + end while swap + self + end +end + +# Taking User Input + +puts "Enter the size of array: " +size = gets.to_i +puts +input_array = Array.new(size) + +counter = 0 + +# Input array values using while loop + +while(counter != size) + puts "Enter the value at index #{counter}: " + input_array[counter] = gets.to_i + counter += 1 +end + +puts + +puts "Input Array: #{input_array}" +print "Cocktail Sort: ", input_array.cocktailSort! + +# Sample Input and Output + += begin + +Enter the size of array: 11 + +Enter the value at index 0: 10 +Enter the value at index 1: 8 +Enter the value at index 2: 4 +Enter the value at index 3: 3 +Enter the value at index 4: 1 +Enter the value at index 5: 9 +Enter the value at index 6: 0 +Enter the value at index 7: 2 +Enter the value at index 8: 7 +Enter the value at index 9: 5 +Enter the value at index 10: 6 + +Input Array: [10, 8, 4, 3, 1, 9, 0, 2, 7, 5, 6] +Cocktail Sort: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + += end diff --git a/Collections/arrayList.java b/Collections/arrayList.java new file mode 100644 index 000000000..868a686a4 --- /dev/null +++ b/Collections/arrayList.java @@ -0,0 +1,228 @@ +import java.util.*; +public class arrayList { + public static void main(String[] args) { + + // Creating a Scanner Object + Scanner scan = new Scanner(System.in); + + // Creating the ArrayList + List li = new ArrayList(); + + char choice='y'; + int value, index; + System.out.println("Enter 1 to add Objects to the list"); + System.out.println("Enter 2 to add Object at a particular index to a list"); + System.out.println("Enter 3 to check size of the list"); + System.out.println("Enter 4 to remove an element from particular index"); + System.out.println("Enter 5 to get an element at a particular index"); + System.out.println("Enter 6 to replace an element at a particular index"); + System.out.println("Enter 7 to find the index of an element"); + System.out.println("Enter 8 to search for the last occurence index of element in the list"); + System.out.println("Enter 9 to check whether an element exists in the list"); + System.out.println("Enter 10 to clear the list"); + System.out.println("Enter 11 to check whether the list is empty or not"); + System.out.println("Enter 12 to create a sublist from the list"); + System.out.println("Enter 13 to print the list"); + while(choice=='y') + { + System.out.println("Enter your choice"); + int input = scan.nextInt(); + switch(input) + { + case 1: System.out.println("Enter value to be added"); + value=scan.nextInt(); + li.add(value); + break; + case 2: System.out.println("Enter the index and value of element to be added"); + index=scan.nextInt(); + value=scan.nextInt(); + li.add(index,value); + break; + case 3: System.out.println("Size of list: "+li.size()); + break; + case 4: System.out.println("Enter index of element to be removed"); + index=scan.nextInt(); + li.remove(index); + System.out.println("Element removed successfully!"); + System.out.println("After Deletion: "+li); + break; + case 5: System.out.println("Enter index of element"); + index=scan.nextInt(); + System.out.println("Element is: "+li.get(index)); + break; + case 6: System.out.println("Enter index and value of element to be replaced"); + index=scan.nextInt(); + value=scan.nextInt(); + li.set(index,value); + System.out.println("After replacing: "+li); + break; + case 7: System.out.println("Enter value of element whose index to be found"); + value=scan.nextInt(); + System.out.println("Value is: "+li.indexOf(value)); + + break; + case 8: System.out.println("Enter the value of element whose last occurence index is to be found"); + value=scan.nextInt(); + System.out.println("Value is:"+li.lastIndexOf(value)); + break; + case 9: // Check if an element exists in the Array List + System.out.println("Enter value of element"); + value=scan.nextInt(); + boolean find = li.contains(value); + if(find) { + System.out.println("Element is in the list"); + } + else + { + System.out.println("Element is not in the list"); + } + break; + case 10: // To clear all elements in array + li.clear(); + break; + case 11: // To check whether the list is empty or not. + System.out.println("Is the list empty? "+li.isEmpty()); + break; + case 12: // To print sublist + int start,end; + System.out.println("Enter starting and ending index"); + start=scan.nextInt(); + end=scan.nextInt(); + List sublist = new ArrayList(); + sublist = li.subList(start,end); + System.out.println(sublist); + break; + case 13: // Creating an Iterator to traverse the arraylist. + Iterator itr = li.iterator(); + while(itr.hasNext()) + { + System.out.println(itr.next()); + } + break; + default: System.out.println("Invalid option entered"); + break; + + } + System.out.println("Do you want to continue? Enter 'y' for more inputs or 'n' to stop"); + choice=scan.next().charAt(0); + } + } +} + +/* +Sample Input +Enter 1 to add Objects to the list +Enter 2 to add Object at a particular index to a list +Enter 3 to check size of the list +Enter 4 to remove an element from particular index +Enter 5 to get an element at a particular index +Enter 6 to replace an element at a particular index +Enter 7 to find the index of an element +Enter 8 to search for the last occurence index of element in the list +Enter 9 to check whether an element exists in the list +Enter 10 to clear the list +Enter 11 to check whether the list is empty or not +Enter 12 to create a sublist from the list +Enter 13 to print the list +Enter your choice +1 +Enter value to be added +100 +Do you want to continue? Enter 'y' for more inputs or 'n' to stop +y +Enter your choice +1 +Enter value to be added +200 +Do you want to continue? Enter 'y' for more inputs or 'n' to stop +y +Enter your choice +1 +Enter value to be added +300 +Do you want to continue? Enter 'y' for more inputs or 'n' to stop +y +Enter your choice +2 +Enter the index and value of element to be added +2 +1000 +Do you want to continue? Enter 'y' for more inputs or 'n' to stop +y +Enter your choice +3 +Size of list: 4 +Do you want to continue? Enter 'y' for more inputs or 'n' to stop +y +Enter your choice +4 +Enter index of element to be removed +2 +Element removed successfully! +After Deletion: [100, 200, 300] +Do you want to continue? Enter 'y' for more inputs or 'n' to stop +y +Enter your choice +5 +Enter index of element +2 +Element is: 300 +Do you want to continue? Enter 'y' for more inputs or 'n' to stop +y +Enter your choice +6 +Enter index and value of element to be replaced +1 +200 +After replacing: [100, 200, 300] +Do you want to continue? Enter 'y' for more inputs or 'n' to stop +y +Enter your choice +7 +Enter value of element whose index to be found +100 +Value is: 0 +Do you want to continue? Enter 'y' for more inputs or 'n' to stop +y +Enter your choice +8 +Enter the value of element whose last occurence index is to be found +200 +Value is:1 +Do you want to continue? Enter 'y' for more inputs or 'n' to stop +y +Enter your choice +9 +Enter value of element +100 +Element is in the list +Do you want to continue? Enter 'y' for more inputs or 'n' to stop +y +Enter your choice +11 +Is the list empty? false +Do you want to continue? Enter 'y' for more inputs or 'n' to stop +y +Enter your choice +12 +Enter starting and ending index +1 +2 +[200] +Do you want to continue? Enter 'y' for more inputs or 'n' to stop +y +Enter your choice +13 +100 +200 +300 +Do you want to continue? Enter 'y' for more inputs or 'n' to stop +y +Enter your choice +9 +Enter value of element +12 +Element is not in the list +Do you want to continue? Enter 'y' for more inputs or 'n' to stop +n +*/ \ No newline at end of file diff --git a/Comb_Sort/Comb_Sort.kt b/Comb_Sort/Comb_Sort.kt new file mode 100644 index 000000000..517e9b77a --- /dev/null +++ b/Comb_Sort/Comb_Sort.kt @@ -0,0 +1,67 @@ +// Kotlin Code for Comb Sort + +import java.lang.Math; +class CombSort +{ + // Function to swap elements at index a and b + fun swap(int:arr[], int:a, int:b):void + { + int temp = arr[a]; + arr[a] = arr[b]; + arr[b] = temp; + } + + // Function to sort arr[] using Comb Sort + fun combSort(int:arr[], int:n):void + { + // initialize gap value to array length + int gap = n; + int flag = 1; + while (gap > 1 || flag == 1 ) + { + // Update gap value by using shrink factor 1.3 + gap = (gap * 10) / 13; + gap = Math.max(1, gap); + flag = 0; + // Compare all elements with the obtained gap value + for (i in 0 until (n-gap)) + { + if (arr[i] > arr[i+gap]) + { + swap(arr, i, i + gap); + flag = 1; + } + } + } + } + + // Main function + fun main() + { + CombSort obj = new CombSort(); + var read = Scanner(System.`in`) + println("Enter the size of Array:") + val arrSize = read.nextLine().toInt() + var arr = IntArray(arrSize) + println("Enter elements") + for(i in 0 until arrSize) + { + arr[i] = read.nextLine().toInt() + } + int n = arrSize; + obj.combSort(arr, n); + + println("Array after sorting:"); + for (i in 0 until arrSize) + { + println(arr[i] + " "); + } + } +} + +/* +Input +-10, 50, 20, 0, 15, -25, 30 +Output +-25 -10 0 15 20 30 50 +*/ diff --git a/Count_Inversion/Count_Inversion.cpp b/Count_Inversion/Count_Inversion.cpp new file mode 100644 index 000000000..3f4c1601e --- /dev/null +++ b/Count_Inversion/Count_Inversion.cpp @@ -0,0 +1,85 @@ +// Count inversion using merge sort + +#include +using namespace std; + +//merge two sorted arrays such that resultant array is also sorted +int merge(int array[], int aux[], int low, int mid, int high) +{ + int x = low, y = mid, z = low, count = 0; + + // checking till left and right half of merge sort + while ((x <= mid-1) && (y <= high)) + { + if (array[x] <= array[y]) + { + aux[z++] = array[x++]; + } + else + { + aux[z++] = array[y++]; + count += mid-x; + } + } + + // Copy remaining elements + while (x <= mid-1) + { + aux[z++] = array[x++]; + } + + while (y <= high) + { + aux[z++] = array[y++]; + } + + // Sorting the original array with the help of aux array + for (int i = low; i <= high; i++) + { + array[i] = aux[i]; + } + return count; +} + +//merge sort to find inversion count +int mergeSort(int array[], int aux[], int low, int high) +{ + int count = 0; + if (high > low) + { + int mid = (low + high) / 2; + + // merge sort on Left half of the array + count = mergeSort(array, aux, low, mid); + // merge sort on Right half of the array + count += mergeSort(array, aux, mid + 1, high); + // Merge the two half + count += merge(array, aux, low, mid + 1, high); + } + return count; +} + +//wrapper function that returns number of inversions +int inversions_count(int array[], int n) +{ + int aux[n]; + return mergeSort(array, aux, 0, n-1); +} + +int main () +{ + int n; + cin >> n; + int arr[n]; + for(int i = 0; i < n; i++) + cin >> arr[i]; + cout << (inversions_count(arr, n)) << endl; + return 0; +} + +/* Sample input +5 +1 20 6 4 5 + +Sample Output +5 */ diff --git a/Count_Rotations/Count_Rotations.java b/Count_Rotations/Count_Rotations.java new file mode 100644 index 000000000..6b1accc83 --- /dev/null +++ b/Count_Rotations/Count_Rotations.java @@ -0,0 +1,70 @@ +/** + * A sorted array has been rotated in clockwise direction. + * Find how many times it was rotated. + */ + +import java.util.Scanner; + +class CountRotations +{ + static int findRotations(int[] arr) + { + /** + * returns no. of times a sorted array was rotated. + */ + int size = arr.length; + int left = 0, right = size - 1; + + while(left <= right) + { + int middle = (right + left) / 2; + int previous = (middle + size - 1) % size, next = (middle + 1) % size; + + // next is index of element after middle + // previous is index of element before middle + + if(arr[left] <= arr[right]) + return left; + + if(arr[middle] <= arr[next] && arr[middle] <= arr[previous]) + return middle; + + if(arr[middle] <= arr[right]) + right = middle - 1; + + else if(arr[middle] >= arr[left]) + left = middle + 1; + } + return 0; + } + + public static void main(String[] args) + { + Scanner scan = new Scanner(System.in); + + System.out.println("Enter size of the array: "); + int size = scan.nextInt(); + + int[] arr = new int[size]; + + System.out.println("Enter " + size + " elements: "); + for(int i = 0; i < size; i++) + arr[i] = scan.nextInt(); + + int count = findRotations(arr); + // count variable stores no. of rotations in the array. + + System.out.println("The array is rotated " + count + " times."); + } +} + +/** + * Sample Input + * size = 6 + * arr = 5, 6, 1, 2, 3, 4 + */ + +/** + * Sample Output + * The array is rotated 2 times. + */ diff --git a/Counting_Sort/Counting_Sort.go b/Counting_Sort/Counting_Sort.go new file mode 100644 index 000000000..4db7949a4 --- /dev/null +++ b/Counting_Sort/Counting_Sort.go @@ -0,0 +1,65 @@ +/* + Counting Sort + ------------------------------------ + Counting sort is a sorting technique based on keys between a specific range. + It works by counting the number of objects having distinct key values (kind of hashing). + Then doing some arithmetic to calculate the position of each object in the output sequence. +*/ + +package main +import "fmt" + +const MaxUint = ^uint(0) +const MaxInt = int(MaxUint >> 1) +const MinInt = - MaxInt - 1 + +func countingSort(list []int) { + maxNumber := MinInt + minNumber := MaxInt + for _, v := range list { + if v > maxNumber { + maxNumber = v + } + if v < minNumber { + minNumber = v + } + } + + count := make([]int, maxNumber - minNumber + 1) + + for _, x := range list { + count[x - minNumber]++ + } + index := 0 + for i, c := range count { + for ; c > 0; c-- { + list[index] = i + minNumber + index++ + } + } +} + +func main() { + var x int + fmt.Printf("Enter the size of the array : ") + fmt.Scan(&x) + fmt.Printf("Enter the elements of the array : ") + a := make([]int, x) + for i := 0; i < x; i++ { + fmt.Scan(&a[i]) + } + list := a // A copy of the array 'a' is assigned to 'list' + fmt.Println("before sorting", list) + countingSort(list) + fmt.Println("after sorting", list) +} + +/* +Sample Input : + Enter the size of the array : 4 + Enter the elements of the array : 12 29 10 78 + +Sample Output : + After sorting [10 12 29 78] +*/ + diff --git a/Counting_Sort/Counting_Sort.kt b/Counting_Sort/Counting_Sort.kt new file mode 100644 index 000000000..a009de4bc --- /dev/null +++ b/Counting_Sort/Counting_Sort.kt @@ -0,0 +1,78 @@ +// Kotlin Code for Counting Sort + +public class Counting_Sort { + // Function that sort the given input + fun sort(int:input[]):void + { + int n = input.length; + int output[] = new int[n]; + int max = input[0]; + int min = input[0]; + + for(i in 1 until n) + { + if(input[i] > max) + { + max = input[i]; + } + + else if(input[i] < min) + { + min = input[i]; + } + } + + // Size of count array + int k = max - min + 1; + int count_array[] = new int[k]; + + for(i in 0 until n) + { + count_array[input[i] - min]++; + } + + for(i in 1 until k) + { + count_array[i] += count_array[i - 1]; + } + + + for(i in 0 until n) + { + output[count_array[input[i] - min] - 1] = input[i]; + count_array[input[i] - min]--; + } + // Copy the output array to input, so that input now contains sorted values + for(i in 0 until n) + { + input[i] = output[i]; + } + } + + // Main Function + fun main() + { + var read = Scanner(System.`in`) + println("Enter the size of Array:") + val arrSize = read.nextLine().toInt() + var input = IntArray(arrSize) + println("Enter elements") + for(i in 0 until arrSize) + { + input[i] = read.nextLine().toInt() + } + + sort(input); + for(i in 0 until arrSize) + { + println(input[i]); + } + } +} + +/* +Input +2 1 4 1 3 5 7 5 4 +Output +1 1 2 3 4 4 5 5 7 +*/ diff --git a/Cycle_Sort.c b/Cycle_Sort.c new file mode 100644 index 000000000..a88653ea1 --- /dev/null +++ b/Cycle_Sort.c @@ -0,0 +1,78 @@ +// Cycle sort is an in-place and unstable sorting algorithm, a comparison sort that is based on the idea that array to be sorted can be divided into cycles. + +# include + +// Cycle Sort begins +void cyclesort(int a[], int n) +{ + int write = 0, start, element, pos, temp, i; + + // Finding the position where we put the element. + for (start = 0 ; start <= n - 2 ; start++) + { + element = a[start]; + pos = start; + + for (i = start + 1 ; i < n ; i++) + if (a[i] < element) + pos++; + + // Checking if element is already in correct position + if (pos == start) + continue; + + while (element == a[pos]) + pos += 1; + + // Putting the element to their right position + if (pos != start) + { + temp = element; + element = a[pos]; + a[pos] = temp; + write++; + } + + // Rotating rest of the cycle + while (pos != start) { + pos = start; + for (i = start + 1 ; i < n ; i++) + if (a[i] < element) + pos += 1; + + while (element == a[pos]) + pos += 1; + + // Putting the element to their right position + if (element != a[pos]) + { + temp = element; + element = a[pos]; + a[pos] = temp; + write++; + } + } + } + } + +int main() +{ int n,i; + int a[20]; + printf("Enter the no. of elements : "); + scanf("%d",&n); + printf("Enter the elements : "); + for(i = 0 ; i < n ; i++) + scanf("%d ",a[i]); + cyclesort(a, n); + printf("After sorting : "); + for (i = 0 ; i < n ; i++) + printf("%d ",a[i]); + return 0; +} + +/* Sample Output: + +Enter the no. of elements : 4 +Enter the elements : 5 8 2 3 +After sorting : 2 3 5 8 +*/ diff --git a/Cycle_Sort/Cycle_Sort.dart b/Cycle_Sort/Cycle_Sort.dart new file mode 100644 index 000000000..526ff3d3d --- /dev/null +++ b/Cycle_Sort/Cycle_Sort.dart @@ -0,0 +1,72 @@ +// Importing required libraries +import 'dart:io'; + +// Function to sort the list using cycle sort +void cycle_sort(List array, int n){ + for(int cycle_start = 0; cycle_start <= n - 2; cycle_start ++){ + // Selecting an element + int value = array[cycle_start]; + int position = cycle_start; + // Finding its position where it should be when the list is sorted + for(int i = cycle_start; i < n; i ++){ + if(array[i] < value){ + position ++; + } + } + // If its in the right position already, ignore + if(position == cycle_start){ + continue; + } + // If not, and there are repititive values, insert after them + while(value == array[position]){ + position += 1; + } + if(position != cycle_start){ + int temp = value; + value = array[position]; + array[position] = temp; + } + // Continue the same process till the cycle ends. + while(position != cycle_start){ + position = cycle_start; + for(int i = cycle_start; i < n; i ++){ + if(array[i] < value){ + position += 1; + } + } + while(value == array[position]){ + position += 1; + } + if(value != array[position]){ + int temp = value; + value = array[position]; + array[position] = temp; + } + } + } +} +// Driver method of the program +void main(){ + // Input of size of the array + print("Enter number of elements in the array:"); + var input = stdin.readLineSync(); + int n = int.parse(input); + // Input of the array elements + print("Enter array elements:"); + input = stdin.readLineSync(); + var lis = input.split(" "); + List array = lis.map(int.parse).toList(); + // Cycle sorting + cycle_sort(array, n); + // Printing the output to stdout + print(array.join(" ")); +} +/** + * Sample Input and Output + * ------------------------------- + * Enter number of elements in the array: + * 7 + * Enter array elements: + * 78 7 8 89 8 8 8 + * 7 8 8 8 8 78 89 + */ diff --git a/Cycle_Sort/Cycle_Sort.go b/Cycle_Sort/Cycle_Sort.go new file mode 100644 index 000000000..b4087920d --- /dev/null +++ b/Cycle_Sort/Cycle_Sort.go @@ -0,0 +1,67 @@ +package main +import ( + "fmt" +) + +func main() { + var x int + fmt.Printf("Enter the size of the array : ") + fmt.Scan(&x) + fmt.Printf("Enter the elements of the array : ") + a := make([]int, x) + for i := 0; i < x; i++ { + fmt.Scan(&a[i]) + } + arr := a // A copy of the array 'a' is assigned to 'randomSlice' + CycleSort(&arr) + fmt.Printf("After sort: %v\n", arr) +} + +func CycleSort(arr *[]int) int { + writes := 0 + for cycleStart, item := range *arr { // Loop through the array to find cycles to rotate. + pos := cycleStart // Find where to put the item. + for i := cycleStart + 1; i < len(*arr); i++ { + if (*arr)[i] < item { + pos++ + } + } + + if pos != cycleStart { // If the item is already there, this is not a cycle. + for item == (*arr)[pos] { // Put the item there or right after any duplicates. + pos++ + } + + (*arr)[pos], item = item, (*arr)[pos] + writes++ + for pos != cycleStart { // Rotate the rest of the cycle + pos = cycleStart // Find where to put the item + for i := cycleStart + 1; i < len(*arr); i++ { + if (*arr)[i] < item { + pos++ + } + } + + for item == (*arr)[pos] { // Put the item there or right after any duplicates. + pos++ + } + (*arr)[pos], item = item, (*arr)[pos] + writes++ + } + } + } + return writes +} + + +/* + +Sample Input : + Enter the size of the array : 4 + Enter the elements of the array : 23 78 56 9 + +Sample Output : + After sort: [9 23 56 78] + +*/ + diff --git a/Cycle_Sort/Cycle_Sort.rb b/Cycle_Sort/Cycle_Sort.rb new file mode 100644 index 000000000..0203c852d --- /dev/null +++ b/Cycle_Sort/Cycle_Sort.rb @@ -0,0 +1,93 @@ +# Cycle Sort In Ruby + +# Function definition +def cycleSort!(input) + change = 0 + + # Looping through the input to find cycles to rotate + for cycleStart in 0 .. input.size - 2 + item = input[cycleStart] + + # Finding where to put the item + position = cycleStart + for i in cycleStart + 1 ... input.size + position += 1 if input[i] < item + end + + # If the item is already present, there is no cycle + next if position == cycleStart + + # Otherwise, put the item there or right after any duplicates + position += 1 while item == input[position] + input[position], item = item, input[position] + change += 1 + + # Rotate the rest of the cycle + while position != cycleStart + + # Finding where to put the item + position = cycleStart + for i in cycleStart + 1 ... input.size + position += 1 if input[i] < item + end + + # Putting the item there or right after any duplicates + position += 1 while item == input[position] + input[position], item = item, input[position] + change += 1 + end + end + change +end + +# Taking User Input +puts "Enter the size of array: " +size = gets.to_i +puts +input_array = Array.new(size) + +counter = 0 + +# Input array values using while loop +while(counter != size) + puts "Enter the value at index #{counter}: " + input_array[counter] = gets.to_i + counter += 1 +end + +puts + +puts "Input Array: #{input_array}" +puts "Cycle Sort: " + +cycleSort!(input_array) +puts "#{input_array}" + +=begin + +Sample Input + +Enter the size of array: 15 + +Enter the value at index 0: 0 +Enter the value at index 1: 1 +Enter the value at index 2: 2 +Enter the value at index 3: 2 +Enter the value at index 4: 2 +Enter the value at index 5: 2 +Enter the value at index 6: 1 +Enter the value at index 7: 9 +Enter the value at index 8: 3.5 +Enter the value at index 9: 5 +Enter the value at index 10: 8 +Enter the value at index 11: 4 +Enter the value at index 12: 7 +Enter the value at index 13: 0 +Enter the value at index 14: 6 + +Sample Output + +Input Array: [0, 1, 2, 2, 2, 2, 1, 9, 3, 5, 8, 4, 7, 0, 6] +Cycle Sort: [0, 0, 1, 1, 2, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9] + +=end diff --git a/Cycle_Sort/cyclesort.c b/Cycle_Sort/cyclesort.c new file mode 100644 index 000000000..5103c68c4 --- /dev/null +++ b/Cycle_Sort/cyclesort.c @@ -0,0 +1,97 @@ +#include + +void main() +{ + int arr[100], i, j, k, p, n, value, index, l, temp; + //input for array size + printf("enter the number of elements required \n"); + scanf("%d", &n); + printf("enter the elements of the array"); + + for (i = 0; i < n; i++) + { + scanf("%d", &arr[i]); + } + + //this sorting follows comparing process,with it's right elements hence loop goes to n-2 to avoid garbage values in the output + for (k = 0; k < n - 2; k++) + { + value = arr[k]; + index = k; + + //loop to find number of elements less than the element in consideration + for (j = k + 1; j < n; j++) + { + if (arr[j] < value) + { + index++; + } + } + + //if the element is at right position + if (index == k) + { + continue; + } + + //skipping duplicate elements + while (arr[index] == value) + { + index++; + } + + //providing the correct position to the element + if (index != k) + { + temp = value; + value = arr[index]; + arr[index] = temp; + } + + //rotate rest of the cycle + while (index != k) + { + index = k; + + for (p = k + 1; p < n; p++) + { + if (arr[p] < value) + { + index++; + } + } + + while (arr[index] == value) + { + index++; + } + + if (index != k) + { + temp = value; + value = arr[index]; + arr[index] = temp; + } + } + arr[k] = value; + } + printf("the sorted array is"); + + for (l = 0; l < n; l++) + { + printf("%d\t", arr[l]); + } + +} + +//sample input-output +/*enter the number of elements required +6 +enter the elements of the array +4 +9 +3 +2 +4 +6 +the sorted array is 2 3 4 4 6 9*/ diff --git a/Depth_First_Search/Depth_First_Search.cs b/Depth_First_Search/Depth_First_Search.cs new file mode 100644 index 000000000..f1e65a25d --- /dev/null +++ b/Depth_First_Search/Depth_First_Search.cs @@ -0,0 +1,69 @@ +/// C# program for Depth First Search Traversal + +using System; +using System.Collections.Generic; //used for including List + +class DirectedGraph +{ + List[] adjacencylist; + int vertix; + + DirectedGraph(int newv) //Constructor with same name as that of class + { + vertix = newv; + adjacencylist = new List[newv]; + for (int i = 0; i < newv; ++i) + adjacencylist[i] = new List(); + } + + void DFSFunction(int newv, bool[] traversed) + { + traversed[newv] = true; + Console.Write(newv + " "); + List vList = adjacencylist[newv]; + foreach (var n in vList) + { + if (!traversed[n]) + DFSFunction(n, traversed); + } + } + + void Addition_of_Edge(int newv, int var) + { + adjacencylist[newv].Add(var); + } + + void Depth_First_Search(int newv) + { + bool[] traversed = new bool[vertix]; + + DFSFunction(newv, traversed); + } + + public static void Main(String[] args) + { + DirectedGraph newgraph = new DirectedGraph(4); // Number of vertices is 4 + Console.WriteLine("Number of edges between the vertices to enter"); + int n = Convert.ToInt32(Console.ReadLine()); + for (int i=0;i new List(no_vertices)); + for(int i = 0; i < no_vertices; i++){ + for(int j = 0; j < no_vertices; j++){ + graph[i][j] = 0; + } + } + + print("Enter number of edges:"); + var input1 = stdin.readLineSync(); + int no_edges = int.parse(input); + print("Enter source and destination vertices of edges:\n"); + print("Note: Enter source and destination vertices as 0,1,2,..."); + + for(int i = 1; i <= no_edges; i++){ + + print("Edge #$i:"); + + print("Enter source vertex:"); + int source = int.parse(stdin.readLineSync()); + + print("Enter destination vertex:"); + int destination = int.parse(stdin.readLineSync()); + + if(mode == "undirected"){ + graph[source][destination] = 1; + graph[destination][source] = 1; + } + else{ + graph[source][destination] = 1; + } + + } + + print("Enter the source vertex from which DFS should begin:"); + int source1 = int.parse(stdin.readLineSync()); + + // Sample input graph + // 0 - 1 - 2 + // | / + // 3 - 4 + + print("Vertices in Depth First Search of the graph in sample input is: "); + + // Depth First Search of the above graph + Depth_First_Search(graph,source1,no_vertices); + + // Sample Output + // Vertices in Depth First Search of the graph in sample input is: + // 0 3 4 2 1 + +} + + diff --git a/Depth_First_Search/Depth_First_Search.go b/Depth_First_Search/Depth_First_Search.go new file mode 100644 index 000000000..9b3f9e47b --- /dev/null +++ b/Depth_First_Search/Depth_First_Search.go @@ -0,0 +1,114 @@ +package main +import "fmt" +type set map[int]bool + +// Define Graph structure +type Graph struct { + adjList map[int]set +} + +// Create a graph and initialize its adjacency list, and return a pointer to it. +func createGraph() *Graph { + var g = Graph{} + g.adjList = make(map[int]set) + return &g +} + +// Add an edge between the two given nodes.If a node does not exist in the graph yet, add it. +func (g *Graph) addEdge(node1 int, node2 int) { + // Check if node1 is already in the graph + if g.adjList[node1] == nil { + g.adjList[node1] = make(set) + } + + g.adjList[node1][node2] = true + // Check if node2 is already in the graph + if g.adjList[node2] == nil { + g.adjList[node2] = make(set) + } + + g.adjList[node2][node1] = true +} + +// Perform a depth first search from the given node and apply the given function to each node. +func dfs(g *Graph, current int, visited set, visitFunction func(int)) { + if _, seen := visited[current]; seen { + return + } + + visited[current] = true + visitFunction(current) + for neighbour := range g.adjList[current] { + dfs(g, neighbour, visited, visitFunction) + } +} + +func main() { + graph := createGraph() + var n int + fmt.Println("Enter the number of vertices : ") + fmt.Scan(&n) + for i := 0; i < n; i++ { + var a int + var b int + fmt.Println("Enter the source vertex : ") + fmt.Scan(&a) + fmt.Println("Enter the destination vertex : ") + fmt.Scan(&b) + graph.addEdge(a, b) + } + fmt.Println("\nThe DFS Traversal of the graph is : ") + visited := make(set) + dfs(graph, 1, visited, func(node int) { + fmt.Print(node, " ") + }) +} + + +/* + + The sample input is given in the form of the following graph : + 1 + / \ + / \ + 2 5 + / \ / \ + 3 - 4 6 7 + + Sample Input : + Enter the number of vertices : + 7 + Enter the source vertex : + 1 + Enter the destination vertex : + 2 + Enter the source vertex : + 2 + Enter the destination vertex : + 3 + Enter the source vertex : + 2 + Enter the destination vertex : + 4 + Enter the source vertex : + 3 + Enter the destination vertex : + 4 + Enter the source vertex : + 1 + Enter the destination vertex : + 5 + Enter the source vertex : + 5 + Enter the destination vertex : + 6 + Enter the source vertex : + 5 + Enter the destination vertex : + 7 + + The DFS Traversal of the graph is : + 1 2 3 4 5 6 7 + +*/ + diff --git a/Depth_First_Search/Depth_First_Search.kt b/Depth_First_Search/Depth_First_Search.kt new file mode 100644 index 000000000..4e4817db3 --- /dev/null +++ b/Depth_First_Search/Depth_First_Search.kt @@ -0,0 +1,77 @@ +import java.util.LinkedList + +class Dfs(private val vertices: Int) { + private val adj: List> = (0 until vertices).map { LinkedList() } + fun addEdge(vertex: Int, weight: Int) { + adj[vertex].add(weight) // Add weight to vertex's list. + } + + private fun dfsUtil(vertex: Int, visited: BooleanArray) { + visited[vertex] = true // Mark the current node as visited and print it + print("$vertex ") + adj[vertex].filter { !visited[it] }.forEach { dfsUtil(it, visited) } + } + + fun traverse(startVertex: Int) { + dfsUtil(startVertex, BooleanArray(vertices)) // Call the recursive helper function to print DFS traversal + } +} + +fun main(args: Array) { + var read = Scanner(System.`in`) + println("Enter the number of vertices :") + val arrSize = read.nextLine().toInt() + val graph = Dfs(arrSize) + for(i in 0 until arrSize) + { + println("Enter the source vertex :") + val a = read.nextLine().toInt() + println("Enter the destination vertex :") + val b = read.nextLine().toInt() + graph.addEdge(a,b) + } + println("\nFollowing is Depth First Traversal :") + graph.traverse(0) + println() +} + + +/* + + Sample Input : + Enter the number of vertices : + 7 + Enter the source vertex : + 1 + Enter the destination vertex : + 2 + Enter the source vertex : + 2 + Enter the destination vertex : + 3 + Enter the source vertex : + 2 + Enter the destination vertex : + 4 + Enter the source vertex : + 3 + Enter the destination vertex : + 4 + Enter the source vertex : + 1 + Enter the destination vertex : + 5 + Enter the source vertex : + 5 + Enter the destination vertex : + 6 + Enter the source vertex : + 5 + Enter the destination vertex : + 7 + + Following is Depth First Traversal : + 1 2 3 4 5 6 7 + +*/ + diff --git a/Depth_First_Search/Depth_First_Search.php b/Depth_First_Search/Depth_First_Search.php new file mode 100644 index 000000000..85c0197be --- /dev/null +++ b/Depth_First_Search/Depth_First_Search.php @@ -0,0 +1,81 @@ +// Depth First Search implementation in PHP + + name = $name; + } + + public function link_to(Node $node, $also = true) + { + if (!$this -> linked($node)) + $this -> linked[] = $node; + if ($also) + $node -> link_to($this, false); + return $this; + } + + private function linked(Node $node) + { + foreach ($this->linked as $l) + { + if ($l -> name === $node -> name) + return true; + } + return false; + } + + public function not_visited_nodes($visited_names) + { + $ret = array(); + foreach ($this -> linked as $l) + { + if (!in_array($l -> name, $visited_names)) $ret[] = $l; + } + return $ret; + } +} + +/* Building Graph */ +$root = new Node('root'); +foreach (range(1, 6) as $v) +{ + $name = "node{$v}"; + $$name = new Node($name); +} + +$root -> link_to($node1) -> link_to($node2); +$node1 -> link_to($node3) -> link_to($node4); +$node2 -> link_to($node5) -> link_to($node6); +$node4 -> link_to($node5); + + +/* Searching Path */ +function dfs(Node $node, $path = '', $visited = array()) +{ + $visited[] = $node -> name; + $not_visited = $node -> not_visited_nodes($visited); + if (empty($not_visited)) + { + echo 'path : ' . $path . ' -> ' . $node -> name . PHP_EOL; + return; + } + foreach ($not_visited as $n) + dfs($n, $path . ' -> ' . $node -> name, $visited); +} + +dfs($root); + +/* +OUTPUT: +path : -> root -> node1 -> node3 +path : -> root -> node1 -> node4 -> node5 -> node2 -> node6 +path : -> root -> node2 -> node5 -> node4 -> node1 -> node3 +path : -> root -> node2 -> node6 +*/ diff --git a/Dijkstra_Algorithm/Dijkstra_Algorithm.dart b/Dijkstra_Algorithm/Dijkstra_Algorithm.dart new file mode 100644 index 000000000..283a735be --- /dev/null +++ b/Dijkstra_Algorithm/Dijkstra_Algorithm.dart @@ -0,0 +1,152 @@ +/* + Djikstra's algorithm (named after its discover, E.W. Dijkstra) solves the + problem of finding the shortest path from a point in a graph (the source) + to a destination. + It turns out that one can find the shortest paths from a given source to all + points in a graph in the same time, hence this problem is sometimes called + the single-source shortest paths problem. +*/ +import 'dart:io'; + +var INT_MAX = 9223372036854775807; + +int minDistance(dist, visited, n) +{ + int min = INT_MAX, min_index; + + for (var v = 0; v < n + 1; v++) + { + if (( visited[v] == false ) && ( dist[v] <= min )) + { + min = dist[v]; + min_index = v; + } + } + + return min_index; +} + +void printsol(dist, n) +{ + print('Vertex \t\t Distance from Source\n'); + + for (var i = 0; i < n + 1; i++) + { + print('${i} \t\t ${dist[i]}\n'); + } +} + +void dijkstra(graph, src, n) +{ + var dist = new List(n + 1); + + var visited = new List(n + 1); + + for (var i = 0; i < n + 1; i++) + { + dist[i] = INT_MAX; + visited[i] = false; + } + + dist[src] = 0; + + for (var count = 0; count < n; count++) + { + var u = minDistance(dist, visited, n); + + visited[u] = true; + + for (var v = 0; v < n + 1; v++) + { + if ( !visited[v] && graph[u][v] > 0 && dist[u] != INT_MAX + && dist[u] + graph[u][v] < dist[v] ) + { + dist[v] = dist[u] + graph[u][v]; + } + } + } + + printsol(dist, n); +} + +void main() +{ + print('Enter number of nodes 0 to ?'); + + int n = int.parse(stdin.readLineSync()); + + var max_edges = (n + 1) * (n); + + var adjmat = new List.generate(n + 1, (_) => new List(n + 1)); + + for(var i = 0; i <= n; i++) + { + for(var j = 0; j <= n; j++) + { + adjmat[i][j] = 0; + } + } + + print('Enter in the following format\nsrc\ndest\nweight\n'); + for(var i = 0; i < max_edges; i++) + { + var src = int.parse(stdin.readLineSync()); + var dest = int.parse(stdin.readLineSync()); + var weight = int.parse(stdin.readLineSync()); + + print('*' * 20); + + if( (src == -1) && (dest == -1) ) + { + break; + } + + if( src > n || dest > n || src < 0 || dest < 0 ) + { + print('Invalid edge!\n'); + i--; + } + else + { + adjmat[src][dest] = weight; + } + } + + dijkstra(adjmat, 0, n); +} + +/* +Input: +Enter number of nodes 0 to ? +9 +Enter in the following format +Source +Destination +Weight +******************************************************* +The adjacency matrix will look like this +admat=[[0, 14, 0, 7, 0, 0, 0, 8, 0, 10], + [14, 0, 8, 0, 0, 0, 0, 11, 0, 0], + [0, 8, 0, 7, 0, 4, 0, 0, 2, 0], + [7, 0, 7, 0, 9, 12, 0, 0, 0, 5], + [0, 0, 0, 9, 0, 0, 0, 0, 0, 0], + [0, 0, 4, 0, 0, 0, 2, 0, 0, 11], + [0, 0, 0, 12, 0, 2, 0, 1, 6, 15], + [8, 11, 0, 0, 0, 0, 1, 0, 7, 0], + [0, 0, 2, 0, 0, 0, 6, 7, 0, 0], + [10, 0, 0, 5, 0, 11, 15, 0, 0, 0]]; +******************************************************* +Output: +Distance from Source: +Vertex Distance +0 0 +1 14 +2 14 +3 7 +4 16 +5 11 +6 9 +7 8 +8 15 +9 10 +*/ diff --git a/Dijkstra_Algorithm/Dijkstra_Algorithm.php b/Dijkstra_Algorithm/Dijkstra_Algorithm.php new file mode 100644 index 000000000..c16e38c63 --- /dev/null +++ b/Dijkstra_Algorithm/Dijkstra_Algorithm.php @@ -0,0 +1,82 @@ + $dist[$i])) ){ + $minVertex = $i; + } + } + return $minVertex; +} + +function dijkstra($graph, $vertices){ + + $visited = array(); + $dist = array(); + + for($i = 0; $i < $vertices; ++$i){ + $visited[$i] = false; + $dist[$i] = PHP_INT_MAX; + } + + // 0 is the source/starting vertex + $dist[0] = 0; + + for($i = 0; $i < $vertices-1; ++$i){ + $minVertex = getMinVertex($dist, $visited, $vertices); + // Mark the minVertex as visited + $visited[$minVertex] = true; + + // Explore all unvisited neighbours of minVertex + // and update the dist array if required + for($j = 0; $j < $vertices; ++$j){ + if($graph[$minVertex][$j] != 0 && !$visited[$j]){ + $currD = $dist[$minVertex] + $graph[$minVertex][$j]; + if($dist[$j] > $currD){ + $dist[$j] = $currD; + } + } + } + } + + // Print the vertices and their corresponding distances from the source vertex + echo "Vertex\tDistance from source\n"; + for($k = 0; $k < $vertices; ++$k){ + echo $k."\t".$dist[$k]."\n"; + } +} + +// Sample Graph (Sample Input) - Adjacency Matrix representation +$graph = array( + array(0, 3, 0, 5), + array(3, 0, 1, 0), + array(0, 1, 0, 8), + array(5, 0, 8, 0) + ); + +// Function for Dijkstra'a algorithm +dijkstra($graph, 4); + +/* +Sample Input: +$graph = array( + array(0, 3, 0, 5), + array(3, 0, 1, 0), + array(0, 1, 0, 8), + array(5, 0, 8, 0) + ); + +Sample Output: +Vertex Distance from source +0 0 +1 3 +2 4 +3 5 +*/ + +?> diff --git a/Dijkstra_Algorithm/Dijkstra_Algorithm.ts b/Dijkstra_Algorithm/Dijkstra_Algorithm.ts new file mode 100644 index 000000000..61b630b60 --- /dev/null +++ b/Dijkstra_Algorithm/Dijkstra_Algorithm.ts @@ -0,0 +1,173 @@ +// Description: Function to perform the Dijkstra algorithm on a weighted graph +// Expected Output: returns the shorted path + +// class for new node +class NewNode { + val: string; + priority: number; + constructor(val: string, priority: number) { + this.val = val; + this.priority = priority; + } +} + +// class for graph +class WeightedGraph { + adjacencyList: {}; + constructor() { + this.adjacencyList = {}; + } + // function to add vertex on graph + addVertex = (vertex: string) => { + if (!this.adjacencyList[vertex]) this.adjacencyList[vertex] = []; + }; + + // function to add weight of the edge between two vertices + addEdge = (vertex1: string, vertex2: string, weight: number) => { + this.adjacencyList[vertex1].push({ node: vertex2, weight }); + this.adjacencyList[vertex2].push({ node: vertex1, weight }); + }; + + // main function to implement Dijkstra Algorithm from start to end node + DijkstraFunction = (start: string, finish: string) => { + const nodes: PriorityQueue = new PriorityQueue(); + const distances = {}; + const previous = {}; + // to return at end + let path = []; + let smallest; + + // build up initial state + for (let vertex in this.adjacencyList) { + if (vertex === start) { + distances[vertex] = 0; + nodes.enqueue(vertex, 0); + } else { + distances[vertex] = Infinity; + nodes.enqueue(vertex, Infinity); + } + previous[vertex] = null; + } + + // as long as there is something to visit, visit the node + while (nodes.values.length) { + smallest = nodes.dequeue().val; + if (smallest === finish) { + // reached the end , need to form the path now and return + while (previous[smallest]) { + path.push(smallest); + smallest = previous[smallest]; + } + break; + } + + if (smallest || distances[smallest] !== Infinity) { + for (let neighbor in this.adjacencyList[smallest]) { + // find neighboring node + let nextNode = this.adjacencyList[smallest][neighbor]; + // calculate new distance to neighboring node + let candidate = distances[smallest] + nextNode.weight; + let nextNeighbor = nextNode.node; + if (candidate < distances[nextNeighbor]) { + // updating new smallest distance to neighbor + distances[nextNeighbor] = candidate; + // updating previous - How we got to neighbor + previous[nextNeighbor] = smallest; + // enqueue in priority queue with new priority + nodes.enqueue(nextNeighbor, candidate); + } + } + } + } + return path.concat(smallest).reverse(); + }; +} + +// class defnition for Priority Queue +class PriorityQueue { + values: NewNode[]; + constructor() { + this.values = []; + } + enqueue = (val: string, priority: number) => { + let newNode = new NewNode(val, priority); + this.values.push(newNode); + this.bubbleUp(); + }; + bubbleUp = () => { + let idx: number = this.values.length - 1; + const element: NewNode = this.values[idx]; + while (idx > 0) { + let parentIdx: number = Math.floor((idx - 1) / 2); + let parent: NewNode = this.values[parentIdx]; + if (element.priority >= parent.priority) break; + this.values[parentIdx] = element; + this.values[idx] = parent; + idx = parentIdx; + } + }; + dequeue = () => { + const min: NewNode = this.values[0]; + const end: NewNode = this.values.pop(); + if (this.values.length > 0) { + this.values[0] = end; + this.sinkDown(); + } + return min; + }; + sinkDown = () => { + let idx: number = 0; + const length: number = this.values.length; + const element: NewNode = this.values[0]; + while (true) { + let leftChildIdx: number = 2 * idx + 1; + let rightChildIdx: number = 2 * idx + 2; + let leftChild: NewNode, rightChild: NewNode; + let swap: number = null; + if (leftChildIdx < length) { + leftChild = this.values[leftChildIdx]; + if (leftChild.priority < element.priority) swap = leftChildIdx; + } + if (rightChildIdx < length) { + rightChild = this.values[rightChildIdx]; + if ( + (swap === null && rightChild.priority < element.priority) || + (swap !== null && rightChild.priority < leftChild.priority) + ) + swap = rightChildIdx; + } + if (swap === null) break; + this.values[idx] = this.values[swap]; + this.values[swap] = element; + idx = swap; + } + }; +} + +function main() { + const wtdGraph = new WeightedGraph(); + // INPUT WEIGHTED GRAPH + // adding vertices of the graph + wtdGraph.addVertex("A"); + wtdGraph.addVertex("B"); + wtdGraph.addVertex("C"); + wtdGraph.addVertex("D"); + wtdGraph.addVertex("E"); + wtdGraph.addVertex("F"); + // addition weight of the edges + wtdGraph.addEdge("A", "B", 1); + wtdGraph.addEdge("A", "C", 3); + wtdGraph.addEdge("B", "E", 2); + wtdGraph.addEdge("C", "D", 4); + wtdGraph.addEdge("C", "F", 5); + wtdGraph.addEdge("D", "E", 3); + wtdGraph.addEdge("D", "F", 1); + wtdGraph.addEdge("E", "F", 2); + + // running the algorithm for the ghraph + const output = wtdGraph.DijkstraFunction("A", "F"); + // OUTPUT OF wtdGraph + console.log(output); //[ 'A', 'B', 'E', 'F'] +} + +main(); diff --git a/Dijkstra_Algorithm/readme.md b/Dijkstra_Algorithm/readme.md new file mode 100644 index 000000000..4ca1f206f --- /dev/null +++ b/Dijkstra_Algorithm/readme.md @@ -0,0 +1,85 @@ +# Dijkstra Algorithm + +Dijkstra's algorithm is used to find the shortest paths from the source vertex to all other vertices in the graph. + +## Example + +Let's find shortest distance of all the vertices from the vertex 0 in the graph given below. + +![Screenshot from 2020-05-27 01-01-28](https://user-images.githubusercontent.com/43384092/82946882-c0785100-9fbc-11ea-8726-688335180c17.png) + +- The set sptSet is initially empty and distances assigned to vertices are {0, INF, INF, INF} where INF indicates infinite. Now pick the vertex with minimum distance value. The vertex 0 is picked, include it in sptSet. So sptSet becomes {0}. After including 0 to sptSet, update distance values of its adjacent vertices. Adjacent vertices of 0 are 1 and 3. The distance values of 1 and 3 are updated as 1 and 2. + +- Pick the vertex with minimum distance value and not already included in sptSet. The vertex 1 is picked and added to sptSet. So sptSet now becomes {0, 1}. Update the distance values of adjacent vertices of 1. The distance value of vertex 2 becomes 4. + +- Pick the vertex with minimum distance value and not already included in sptSet. Vertex 3 is picked. So sptSet now becomes {0, 1, 3}. Update the distance values of adjacent vertices of 3. The adjacent vertices of 3 are 0 and 2 which already have a minimum value so they will not be updated. + +- Pick the vertex with minimum distance value and not already included in sptSet. Vertex 2 is picked. So sptSet now becomes {0, 1, 3, 2}. The adjacent vertices of 2 are 1 and 3 which already have a minimum value so they will not be updated. + +- Now we stop the process as sptSet does include all vertices of given graph. Finally, we get the shortest distances of all the vertices from the vertex 0. + +## Algorithm + +1) Create an array dist. The size of the array is equal to the number of vertices V in the graph. Initialise all the elements of the array with INFINITE. + +2) Create an empty set s of type pair(weight, vertex). + +3) Insert source vertex into the set and its distance as 0. + Update dist[src] = 0. + +4) Repeat the below steps while set is not empty
+ a) Extract the minimum distance vertex from the set s i.e. the top element from the set as the set is sorted in ascending order on the basis of distance from the source. Let it be u.
+ b) Loop through all the adjacent vertices of u. Let the adjacent vertex be labelled as v. For every v,
+           if dist[v] > dist[u] + weight(u, v)
+                      (i) dist[v] = dist[u] + weight(u, v)
+                      (ii) If v is in set, remove it.
+                      (iii) Insert v in the set with updated distance.
+ +5) Print distance array dist[ ] along with the vertex number. + +## Pseudocode +``` +minDistance(dist[], sptSet[]) + min = INT_MAX + for(v = 0; v < V; v++) + if (sptSet[v] == false and dist[v] <= min) + min = dist[v], min_index = v + return min_index + +dijkstra(int graph[V][V], int src) + for(i = 0; i < V; i++) + dist[i] = INT_MAX + sptSet[i] = false + dist[src] = 0 + for(count = 0; count < V - 1; count++) + u = minDistance(dist, sptSet) + sptSet[u] = true + for(v = 0; v < V; v++) + if(not(sptSet[v]) && graph[u][v] && dist[u] not equal to INT_MAX && dist[u] + graph[u][v] < dist[v]) + dist[v] = dist[u] + graph[u][v] + for(i = 0; i < V; i++) + display i, dist[i] +``` +## Complexity + + Time Complexity: O(V * V) + Space Complexity: O(V) + +where +>V = number of vertices
+ +## Implementation + * [C Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Dijkstra_Algorithm/Dijkstra_Algorithm.c) + * [C++ Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Dijkstra_Algorithm/Dijkstra_Algorithm.cpp) + * [Java Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Dijkstra_Algorithm/Dijkstra_Algorithm.java) + * [Python Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Dijkstra_Algorithm/Dijkstra_Algorithm.py) + * [JS Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Dijkstra_Algorithm/Dijkstra_Algorithm.js) + * [Ruby Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Dijkstra_Algorithm/Dijkstra_Algorithm.rb) + * [C++ STL Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Dijkstra_Algorithm/Dijkstra_Algorithm_STL.cpp) + * [C++ Efficient Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Dijkstra_Algorithm/Dijkstra_Efficient.cpp) + +## References + +* [Tutorial - GeeksforGeeks](https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-greedy-algo-7/) +* [Wikipedia](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) + diff --git a/Euclidean_Algorithm/Euclidean_Algorithm.c b/Euclidean_Algorithm/Euclidean_Algorithm.c new file mode 100644 index 000000000..977cf2ad9 --- /dev/null +++ b/Euclidean_Algorithm/Euclidean_Algorithm.c @@ -0,0 +1,31 @@ +// Program to demonstrate Basic Euclidean Algorithm +#include + +// Function to return gcd of x and y +int gcd_algorithm(int x,int y) +{ + // if the remainder is 0, return second number + if(x == 0) + { + return y; + } + return gcd_algorithm((y % x),x); // recursive call to the function +} + +// Driver program +int main() +{ + int num1, num2, gcd; + printf("\nEnter two numbers to find gcd using Euclidean algorithm: "); + scanf("%d %d", &num1, &num2); + gcd = gcd_algorithm(num1, num2); + printf("\nThe GCD of %d and %d is %d\n", num1, num2, gcd); + return 0; +} + +/* +Output- +Enter two numbers to fing gcd using Euclidean algorithm: +12 16 +The GCD of 12 and 16 is 4 +*/ diff --git a/Euclidean_Algorithm/Euclidean_Algorithm.js b/Euclidean_Algorithm/Euclidean_Algorithm.js new file mode 100644 index 000000000..d27b6661d --- /dev/null +++ b/Euclidean_Algorithm/Euclidean_Algorithm.js @@ -0,0 +1,28 @@ +// Euclidean Algorithm to find GCD of two numbers + +// Function to return gcd of a and b +function gcd(a, b) +{ + // base case + if(b == 0) + { + return a; + } + return gcd(b, a % b); +} + +// Used synchronous readline package to take console input +var readlineSync = require('readline-sync'); + +var a = readlineSync.question('Enter first Number'); +a = parseInt(a); +var b = readlineSync.question('Enter second number'); +b = parseInt(b); + +var result = gcd(a, b); +console.log("The GCD is" + " " + result) + +/* + Sample Input : 9 6 + Sample Output : The GCD is 3 +*/ diff --git a/Euclidean_Algorithm/Euclidean_Algorithm.rb b/Euclidean_Algorithm/Euclidean_Algorithm.rb new file mode 100644 index 000000000..f8a7d9e30 --- /dev/null +++ b/Euclidean_Algorithm/Euclidean_Algorithm.rb @@ -0,0 +1,30 @@ +# Given two numbers, we need to find the greatest common divisor of those two numbers + +def gcd(x, y) + # every number divides 0 + if (x == 0) + return y + else + return gcd(y % x, x) + end +end + +# Driver Code +puts "Enter first number:" +x = gets.to_i + +puts "Enter second number:" +y = gets.to_i + +puts "GCD of numbers #{x} and #{y} is #{gcd(x, y)}" + +=begin +Enter first number: +462 + +Enter second number: +780 + +Output: +GCD of numbers 462 and 780 is 6 +=end diff --git a/Euclidean_Algorithm/Euclidean_Algorithm.ts b/Euclidean_Algorithm/Euclidean_Algorithm.ts new file mode 100644 index 000000000..5d220d693 --- /dev/null +++ b/Euclidean_Algorithm/Euclidean_Algorithm.ts @@ -0,0 +1,23 @@ +// Euclidean Algorithm to find GCD of two numbers + +export {} + +// Recursive Function to return gcd of a and b +function gcd(a:number , b:number) : number +{ + return (b === 0) ? a : gcd(b, a % b); +} + +let x : number = 24; +let y : number = 60; +let ans : number = gcd(x,y); +console.log("The GCD of " + x + " and " + y + " is " + ans); + +/* +INPUT +x = 24 +y = 60 + +OUTPUT +The GCD of 24 and 60 is 12 +*/ \ No newline at end of file diff --git a/Exponential_Search/Exponential_Search.php b/Exponential_Search/Exponential_Search.php new file mode 100644 index 000000000..11a24146c --- /dev/null +++ b/Exponential_Search/Exponential_Search.php @@ -0,0 +1,50 @@ + $left) + { + $mid = $left + ($right - $left) / 2; + if ($input_arr[$mid] == $x) + return $mid; + if ($x < $input_arr[$mid] ) + return Binary_Search($input_arr, $left, $mid - 1, $x); + + return Binary_Search($input_arr, $mid + 1, $right, $x); + } + return -1; +} + +function Exponential_Search($input_arr,$size,$x) +{ + if ($input_arr[0] == $x) + return 0; + $i = 1; + while ($i < $size and $input_arr[$i] <= $x) + { + $i = $i * 2; + } + + return Binary_Search($input_arr, $i / 2, min($i, $size), $x); + +} + +//Driver Code + +$input_arr = array(1, 2, 3, 4, 5, 6); +$size = count($input_arr); +$x = 4; +$result = exponential_search($input_arr, $size, $x); +if ($result != -1) + echo "The index at which the element " , $x, " is present is " , $result; + +else + echo "The element is not present in array"; + +/* +OUTPUT: +The index at which the element 4 is present is 3 +*/ + +?> diff --git a/Exponential_Search/README.md b/Exponential_Search/README.md new file mode 100644 index 000000000..78e04d6b8 --- /dev/null +++ b/Exponential_Search/README.md @@ -0,0 +1,96 @@ +# Exponential Search + +Exponential search (also called doubling search or galloping search or Struzik search) is a searching technique for sorted, unbounded/infinite lists. +There are multiple ways to perform this method, but the most common and useful one is to find the range in which the element to be searched must be present. This is done by applying a Binary Search between the ranges. + +The name of this searching algorithm may be misleading but it works in O(Log n) time. The name comes from the way it searches an element. + +## Explanation + +Exponential search involves two steps: + +1. Find range where element is present +2. Do Binary Search in above found range. + +The idea is to start with subarray size 1, compare its last element with x, then try size 2, then 4 and so on until last element of a subarray is not greater. +Once we find an index i (after repeated doubling of i), we know that the element must be present between i/2 and i (Why i/2? because we could not find a greater value in previous iteration) + +## Algorithm + +The algorithm consists of two stages. The first stage determines a range in which the search key would reside if it were in the list. In the second stage, a binary search is performed on this range. In the first stage, assuming that the list is sorted in ascending order, the algorithm looks for the first exponent, j, where the value 2j is greater than the search key. This value, 2j becomes the upper bound for the binary search with the previous power of 2, 2j - 1, being the lower bound for the binary search.[3] + +```C++ +// Returns the position of key in the array arr of length size. +template +int exponential_search(T arr[], int size, T key) +{ + if (size == 0) + { + return NOT_FOUND; + } + + int bound = 1; + while (bound < size && arr[bound] < key) + { + bound*= 2; + } + + return binary_search(arr, key, bound/2, min(bound + 1, size)); +} +``` + +In each step, the algorithm compares the search key value with the key value at the current search index. If the element at the current index is smaller than the search key, the algorithm repeats, skipping to the next search index by doubling it, calculating the next power of 2.[3] If the element at the current index is larger than the search key, the algorithm now knows that the search key, if it is contained in the list at all, is located in the interval formed by the previous search index, 2j - 1, and the current search index, 2j. The binary search is then performed with the result of either a failure, if the search key is not in the list, or the position of the search key in the list. + +## Pseudocode + +Input: An sorted array, start and end location, and the search key. + +Output: location of the key (if found), otherwise wrong location. + + Begin + + if (end – start) <= 0 then + + return invalid location + + i := 1 + + while i < (end - start) do + + if array[i] < key then + + i := i * 2 //increase i as power of 2 + + else + + terminate the loop + + done + + call binarySearch(array, i/2, i, key) + + End + + +## Example + +Given a sorted array, and an element x to be searched, find position of x in the array. + +1. Input: arr[] = {10, 20, 40, 45, 55} + x = 45 +Output: Element found at index 3 + +2. Input: arr[] = {10, 15, 25, 45, 55} + x = 15 +Output: Element found at index 1 + +## The complexity of Exponential Search Technique + +1. Time Complexity: O(1) for the best case. O(log2 i) for average or worst case. Where i is the location where search key is present. + +2. Space Complexity: O(1) + +## See also + +* [Wikipedia : Exponential Search](https://en.wikipedia.org/wiki/Exponential_search) +* [geeksforgeeks : Exponential Search](https://www.geeksforgeeks.org/exponential-search/) diff --git a/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.dart b/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.dart new file mode 100644 index 000000000..ee2d2779b --- /dev/null +++ b/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.dart @@ -0,0 +1,42 @@ +/* Extended Euclidean Algorithm + ============================== + GCD of two numbers is the largest number that divides both of them. + A simple way to find GCD is to factorize both numbers and multiply + common factors. + + GCD(a,b) = ax + by + If we can find the value of x and y then we can easily find the + value of GCD(a,b) by replacing (x,y) with their respective values. +*/ + +import 'dart:io'; + +void main() { + int x = 0, y = 0; + var a = int.parse(stdin.readLineSync()); + var b = int.parse(stdin.readLineSync()); + // function called for 98 and 21 + print(gcdFunction(a, b, x, y)); +} + +int gcdFunction(a, b, x, y) { + if (a == 0) { + x = 0; + y = 0; + return b; + } + + int x1 = 0, y1 = 0; + int gcd = gcdFunction(b % a, a, x1, y1); + + x = y1 - (b / a).round() * x1; + y = x1; + + return gcd; +} + +// Sample input : +// 98 +// 21 +// Sample output : +// 7 diff --git a/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.java b/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.java new file mode 100644 index 000000000..eaa13be6b --- /dev/null +++ b/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.java @@ -0,0 +1,46 @@ +import java.util.*; + +public class Extended_Euclidean_Algorithm +{ + // extended Euclidean Algorithm + public static int getGCD(int a, int b, int x, int y) + { + // Base Case + if (a == 0) + { + x = 0; + y = 1; + return b; + } + + int x1 = 1, y1 = 1; // To store results of recursive call + int gcd = getGCD(b % a, a, x1, y1); + + // Update x and y after recursive call + x = y1 - (b / a) * x1; + y = x1; + + return gcd; + } + +// Main function + public static void main(String[] args) + { + int x = 1, y = 1; + Scanner s = new Scanner(System.in); + int a = s.nextInt(); + int b = s.nextInt(); + int g = getGCD(a, b, x, y); + System.out.print("GCD of " + a + " , " + b + " = " + g); + } +} + + + +/* + INPUT + a = 35, b = 15; + + Output: + GCD of 35 , 15 = 5 +*/ diff --git a/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.js b/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.js new file mode 100644 index 000000000..cf5d61394 --- /dev/null +++ b/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.js @@ -0,0 +1,39 @@ +// Extended Euclidean Algorithm to find GCD of two numbers + +// Function to return gcd of a and b +function gcdExtended(a, b, x, y) +{ + // Base Case + if (a == 0) + { + x = 0; + y = 1; + return b; + } + + var x1, y1; // To store results of recursive call + var gcd = gcdExtended(b % a, a, x1, y1); + + // Update x and y using results of + // recursive call + x = y1 - (b / a) * x1; + y = x1; + + return gcd; +} + +// Used synchronous readline package to take console input +var readlineSync = require('readline-sync'); + +var a = readlineSync.question('Enter first Number'); +a = parseInt(a); +var b = readlineSync.question('Enter second number'); +b = parseInt(b); + +var result = gcdExtended(a, b); +console.log("The GCD is" + " " + result) + +/* + Sample Input : 9 6 + Sample Output : The GCD is 3 +*/ diff --git a/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.php b/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.php new file mode 100644 index 000000000..20efb80f8 --- /dev/null +++ b/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.php @@ -0,0 +1,45 @@ + diff --git a/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.rb b/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.rb new file mode 100644 index 000000000..e4076814a --- /dev/null +++ b/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.rb @@ -0,0 +1,36 @@ +=begin +Extended Euclidean Algorithm +============================== +GCD of two numbers is the largest number that divides both of them. +A simple way to find GCD is to factorize both numbers and multiply common factors. + +GCD(a,b) = ax + by +If we can find the value of x and y then we can easily find the +value of GCD(a,b) by replacing (x,y) with their respective values. +=end + +def extended_gcd(a, b, x, y) #Function for extended Euclidean Algorithm + + #Base Case + return b if a == 0 + + x1, y1 = 1, 1 #To store results of recursive call + gcd = extended_gcd(b % a, a, x1, y1) + #Update x and y using results of recursive call + x = y1 - (b / a) * x1 + y = x1 + return gcd +end + +x , y = 1, 1 +a = gets.to_i +b = gets.to_i +puts "GCD of numbers #{a} and #{b} is #{extended_gcd(a, b, x, y)}" + +=begin +INPUT: +27 +81 +OUTPUT: +GCD of numbers 27 and 81 is 27 +=end diff --git a/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.ts b/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.ts new file mode 100644 index 000000000..5b82e9342 --- /dev/null +++ b/Extended_Euclidean_Algorithm/Extended_Euclidean_Algorithm.ts @@ -0,0 +1,35 @@ +export {} + +/* +Extended Euclidean Algorithm :- Find greatest common divisor of the two numbers + a*x + b*y = gcd(a,b) + and solves the above linear equation +*/ + +// find greatest common divisor +function gcdExtended(a:number , b:number) : number[] +{ + //base case + if (a==0) + { + return [b,0,1]; + } + //recursive call + let ans: number[] = gcdExtended(b%a , a); + return [ans[0], (ans[2] - (Math.floor(b/a) * ans[1])) , ans[1]]; +} + +let a : number = 12; +let b : number = 16; + +let ans : number[] = gcdExtended(a,b); +console.log(ans[0] , ans[1] , ans[2]); + +/* +INPUT +a = 12 +b = 16 + +OUTPUT +4 -1 1 +*/ diff --git a/Fenwick_Tree/Fenwick_Tree.c b/Fenwick_Tree/Fenwick_Tree.c new file mode 100644 index 000000000..3553fb4f4 --- /dev/null +++ b/Fenwick_Tree/Fenwick_Tree.c @@ -0,0 +1,122 @@ +/* + Fenwick Tree[also known as binary indexed tree] is used when there is a problem of range sum query wiht update i.e.RMQ. + Suppose you have an array and you have been asked to find sum in range.It can be done in linear time with static array + method.It will be difficult for on to do it in linear time when you have point updates.In this, update operation + incrementing an index by some value.Brute force approach will take O(n^2) time but Fenwick tree will take O(nlogn) time. +*/ + +#include +#include + +/* n --> No. of elements present in input array. + BITree[0..n] --> Array that represents Fenwick Tree(Binary Indexed Tree). + arr[0..n-1] --> Input array for which prefix sum is evaluated. +*/ +/* + Returns sum of arr[0..index]. This function assumes that the array is preprocessed and partial sums of + array elements are stored in BITree[]. +*/ + +int getSum(int BITree[], int index) +{ + int sum = 0; // Iniialize result + + // index in BITree[] is 1 more than the index in arr[] + index = index + 1; + + // Traverse ancestors of BITree[index] + while (index > 0) + { + // Add current element of BITree to sum + sum += BITree[index]; + + // Move index to parent node in getSum View + index -= index & (-index); + } + return sum; +} + +/* + Updates a node in Fenwick Tree at given index in BITree. The given value 'val' is added to BITree[i] and + all of its ancestors in tree. +*/ + +void updateBIT(int BITree[], int n, int index, int val) +{ + // index in BITree[] is 1 more than the index in arr[] + index = index + 1; + + // Traverse all ancestors and add 'val' + while (index <= n) + { + // Add 'val' to current node of BI Tree + BITree[index] += val; + + // Update index to that of parent in update View + index += index & (-index); + } +} + +/* + Constructs and returns a Fenwick Tree for given array of size n. +*/ + +int *constructBITree(int arr[], int n) +{ + // Create and initialize BITree[] as 0 + int *BITree = (int*) calloc(n+1, sizeof(int)); + + for (int i = 1; i <= n; ++i) + BITree[i] = 0; + + // Store the actual values in BITree[] using update() + for (int i = 0; i < n; ++i) + updateBIT(BITree, n, i, arr[i]); + + return BITree; +} + +int rangeSum(int l, int r, int BITree[]) +{ + return getSum(BITree, r) - getSum(BITree, l); +} + +int main() +{ + int n; + scanf("%d", &n); + + int freq[n]; + for (int i = 0; i < n; ++i) + { + scanf("%d", &freq[i]); + } + int *BITree = constructBITree(freq, n); + // Print sum of freq[0...5] + printf("%d\n", getSum(BITree, 5)); + + //Update operation + freq[4] += 16; + updateBIT(BITree, n, 4, 16); + + //Print sum of freq[2....7] after update + printf("%d\n", rangeSum(2, 7, BITree)); + + return 0; + +} + +/* +INPUT +----- +n=12 +freq :[2,1,1,3,2,3,4,5,6,7,8,9]; +Print sum of freq[0...5] +Update position 4 by adding 16 +Print sum of freq[2....7] after update + +OUTPUT +------ +12 +33 +*/ diff --git a/Fenwick_Tree/Fenwick_Tree.cs b/Fenwick_Tree/Fenwick_Tree.cs new file mode 100644 index 000000000..2ebb3d992 --- /dev/null +++ b/Fenwick_Tree/Fenwick_Tree.cs @@ -0,0 +1,78 @@ +using System; + +internal class BinaryIndexedTree +{ + // Max tree size + internal + const int MAX = 1000; + internal static int[] BITree = new int[MAX]; + + internal virtual int getSum(int index) + { + // Iniialize result + int sum = 0; + + // index in BITree[] is 1 more than + // the index in arr[] + index = index + 1; + + // Traverse ancestors of BITree[index] + while (index > 0) { + sum += BITree[index]; + index -= index & (-index); + } + return sum; + } + + // Updates a node in Binary Index Tree (BITree) at given index in BITree. + public static void updateBIT(int n, int index, int val) + { + // index in BITree[] is 1 more than + // the index in arr[] + index = index + 1; + + // Traverse all ancestors and add 'val' + while (index <= n) + { + BITree[index] += val; + index += index & (-index); + } + } + + /* Function to construct fenwick tree + from given array.*/ + internal virtual void constructBITree(int[] arr, int n) + { + // Initialize BITree[] as 0 + for (int i = 1; i <= n; i++) + { + BITree[i] = 0; + } + + // Store the actual values in BITree[] + // using update() + for (int i = 0; i < n; i++) + { + updateBIT(n, i, arr[i]); + } + } + + // Main function + public static void Main(string[] args) + { + int[] freq = new int[] {2, 1, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9}; + int n = freq.Length; + BinaryIndexedTree tree = new BinaryIndexedTree(); + // Build fenwick tree from given array + tree.constructBITree(freq, n); + Console.WriteLine("Sum of elements in arr[0..5]" + " is = " + tree.getSum(5)); + freq[3] += 6; + updateBIT(n, 3, 6); + // Find sum after the value is updated + Console.WriteLine("Sum of elements in arr[0..5]" + " after update is = " + tree.getSum(5)); + } +} + +/*Output:- +Sum of elements in arr[0..5] is = 12 +Sum of elements in arr[0..5] after update is = 18*/ diff --git a/Fenwick_Tree/Fenwick_Tree.dart b/Fenwick_Tree/Fenwick_Tree.dart new file mode 100644 index 000000000..ee51585b1 --- /dev/null +++ b/Fenwick_Tree/Fenwick_Tree.dart @@ -0,0 +1,159 @@ +/** + * Fenwick Tree + * ------------------------- + * Binary Indexed tree or Fenwick tree is used to solve + * range queries optimally. It has O(n) space complexity, + * O(logn) time complexity to update, O(nlog(n)) time complexity to build + * and O(logn) time complexity to find sum in a given range. + * + */ +// Importing required libraries +import 'dart:io'; + +// Updating the tree with respect to any updates or construction +void updateBITTree(List tree, int n, int index, int val){ + index = index + 1; + + while(index <= n){ + tree[index] += val; + index += index & ( - index); + } + +} + +// Method to find the sum till a given index +int getSum(List tree, int index){ + + int total = 0; + index = index + 1; + + while(index > 0){ + total += tree[index]; + index -= index & ( - index ); + } + + return total; +} + +// Method to find sum between a range using the above method. +int findSum(List tree, int left, int right){ + if(left > right){ + return -1; + } + else if(left == right){ + return getSum(tree, left) - getSum(tree, left - 1); + } + else{ + if(left > 0){ + return getSum(tree,right) - getSum(tree,left) + (getSum(tree, left) - getSum(tree, left - 1)); + } + else if(left == 0){ + return getSum(tree,right); + } + else{ + return -1; + } + } +} + +// Driver method of the program +void main(){ + + // Input of number of array elements + print("Enter number of elements in the array:"); + var input = stdin.readLineSync(); + int n = int.parse(input); + + // Input of array elements + print("Enter array elements:"); + input = stdin.readLineSync(); + var lis = input.split(" "); + List array = lis.map(int.parse).toList(); + + // Fenwick tree initialization + List tree_BIT = List(n + 1); + for(int i = 0; i < n + 1; i ++){ + tree_BIT[i] = 0; + } + + // Tree construction + for(int i = 0; i < n; i ++){ + updateBITTree(tree_BIT, n, i, array[i]); + } + + // Input of number of queries + print("Enter number of queries:"); + input = stdin.readLineSync(); + int q = int.parse(input); + + // Input of queries + print("Enter queries:"); + for(int i = 0 ; i < q ; i ++){ + + print("Enter 1 to update, 2 to find sum:"); + input = stdin.readLineSync(); + int choice = int.parse(input); + switch(choice){ + + case 1: + // Input for updates + print("Enter index and value to update"); + input = stdin.readLineSync(); + lis = input.split(" "); + List choices = lis.map(int.parse).toList(); + array[choices[0]] += choices[1]; + // Updating value + updateBITTree(tree_BIT, n, choices[0], choices[1]); + break; + case 2: + // Input for sum queries + print("Enter range to find the sum"); + input = stdin.readLineSync(); + lis = input.split(" "); + List choices = lis.map(int.parse).toList(); + // Finding sum + int result = findSum(tree_BIT,choices[0],choices[1]); + print(result); + break; + } + } +} + +/** + * + * Sample Input + * ------------------------------------ + * Enter number of elements in the array: + * 12 + * Enter array elements: + * 2 1 1 3 2 3 4 5 6 7 8 9 + * Enter number of queries: + * 5 + * Enter 1 to update, 2 to find sum: + * 2 + * Enter range to find the sum + * 0 5 + * Enter 1 to update, 2 to find sum: + * 1 + * Enter index and value to update + * 3 9 + * Enter 1 to update, 2 to find sum: + * 2 + * Enter range to find the sum + * 0 5 + * Enter 1 to update, 2 to find sum: + * 2 + * Enter range to find the sum + * 5 9 + * Enter 1 to update, 2 to find sum: + * 2 + * Enter range to find the sum + * 8 8 + * + * Sample Output + * ---------------------------------------- + * 12 + * 21 + * 25 + * 6 + */ diff --git a/Fenwick_Tree/Fenwick_Tree.kt b/Fenwick_Tree/Fenwick_Tree.kt new file mode 100644 index 000000000..8cf232208 --- /dev/null +++ b/Fenwick_Tree/Fenwick_Tree.kt @@ -0,0 +1,127 @@ +/*Fenwick Tree is used when there is a problem of range sum query with update +i.e. RMQ. Suppose you have an array and you have been asked to find sum in +range. It can be done in linear time with static array method. If will be +difficult for one to do it in linear time when you have point updates. In this +update operation is incrementing an index by some value. Brute force approach +will take O(n^2) time but Fenwick Tree will take O(nlogn) time +*/ + +//Sum function +fun sum(ft:Array, _index:Int):Int{ + /* + Argument + ft : Fenwick Tree + index : Index upto which you want to find prefix sum + Initialize the result "s" then increment the value of + index "index". + + Returns : sum of given arr[0..index]. This function assumes + that the array is preprocessed and partial sums of + array elements are stored in ft[]. + */ + + // Initialize sum variable to 0 + var s:Int = 0 + // Increment index + var index = _index + 1 + + while (index > 0){ + + // Adding tree node to sum + s += ft[index] + // Update tree node + index -= index and (-index) + } + // Return total sum + return s +} + + +// Update function +fun update(ft:Array,size:Int,_index:Int,value:Int){ + /* + Arguments + ft : Fenwick Tree + index : Index of ft to be updated + size : Length of the original array + val : Add val to the index "index" + Traverse all ancestors and add 'val'. + Add 'val' to current node of Fenwick Tree. + Update index to that of parent in update. + */ + + var index = _index + 1 + while (index <= size) { + + // Update tree node value + ft[index] += value + // Update node index + index += index and (-index) + } + +} + +// Construct function +fun construct(array:Array, size:Int):Array{ + /* + Argument + arr : The original array + size : The length of the given array + This function will construct the Fenwick Tree + from the given array of length "size" + + Return : Fenwick Tree array ft[] + */ + + // Init ft array of length size+1 with zero value initially + var ft = Array(size+1,{0}) + + // Constructing Fenwick Tree by Update operation + for (i in 0 until size){ + // Update operation + update(ft,size,i,array[i]) + } + // Return Fenwick Tree array + return ft +} + +fun main(){ + /* + INPUT + ------- + arr : [2, 1, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9] + Print sum of freq[0...5] + Update position 4 by adding 16 + Print sum of freq[2....7] after update + Update position 5 by adding 10 + Print sum of freq[2....7] after update + + OUTPUT + ------ + 12 + 33 + 43 + */ + + // Given array + var list = arrayOf(2, 1, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9) + + // Build Fenwick Tree + var ft = construct(list,list.size) + + // Print Sum of array from index = 0 to index = 5 + println(sum(ft,5)) + + // Increment list[4] by 16 + update(ft,list.size,4,16) + + // Print sum from index = 2 to index = 7 + println(sum(ft,7) - sum(ft,2)) + + // Increment list[5] by 10 + update(ft,list.size,5,10) + + // Print sum from index = 2 to index = 7 + println(sum(ft,7) - sum(ft,2)) +} + diff --git a/Fenwick_Tree/Fenwick_Tree.php b/Fenwick_Tree/Fenwick_Tree.php new file mode 100644 index 000000000..71801c8ca --- /dev/null +++ b/Fenwick_Tree/Fenwick_Tree.php @@ -0,0 +1,105 @@ + 0){ + // Adding tree node to sum + $s = $s + $ft[$index]; + // Update tree node + $index -= $index & (-$index); + } + // Return total sum + return $s; +} + +// Update function +function update ($ft, $size, $index, $val) { + /* + Arguments + ft : Fenwick Tree + index : Index of ft to be updated + size : Length of the original array + val : Add val to the index "index" + Traverse all ancestors and add 'val'. + Add 'val' to current node of Fenwick Tree. + Update index to that of parent in update. + */ + $index += 1; + while( $index <= $size){ + // Update tree node value + $ft[$index] = $ft[$index] + $val; + // Update node index + $index += $index and (-$index); + } + } + + +// Build function +function construct($array, $size) { + /* + Argument + array : The original array + size : The length of the given array + This function will construct the Fenwick Tree + from the given array of length "size" + + Return : Fenwick Tree array ft[] + */ + // Init ft array of length 1000 with zero value initially + $ft = array(); + // Constructing Fenwick Tree by Update operation + for( $i = 0; $i < $size; $i++) { + // Update operation + update($ft, $size, $i, $array[$i]); + } + // Return Fenwick Tree array + return $ft; +} + +//Driver code to test above methods +function main() { + $array = array(2, 1, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9); + $n = construct($freq, sizeof($array)); + echo implode(sum($n, 5)); + $array[3] = $array[3] + 6; + update($n, sizeof($array), 3, 6) ; + echo implode(sum($n, 5)); +} + +/* +INPUT +------- +array : [2, 1, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9] +Sum of elements in array[0..5] is 12 +Sum of elements in array[0..5] after update is 18 + +OUTPUT +------ +12 +18 +*/ + +?> diff --git a/Fibonacci_Number_Using_DP_Approach/Fibonacci_Number_Using_DP_Approach.c b/Fibonacci_Number_Using_DP_Approach/Fibonacci_Number_Using_DP_Approach.c new file mode 100644 index 000000000..530cb4c1d --- /dev/null +++ b/Fibonacci_Number_Using_DP_Approach/Fibonacci_Number_Using_DP_Approach.c @@ -0,0 +1,53 @@ +#include +int dp[100005] = {0}; + +int fibDP(int n) +{ + if(n == 0 || n == 1) + { + return n; + } + /* This is used to print the values or series of given fibonacci number + if(dp[n] != 0) + { + return dp[n]; + }*/ + + /* This recursion is to hold the values till cand1 = 1(from 5-4-3-2-1), cand2 = 1(5-3-1) */ + int cand1 = fibDP(n - 1); + int cand2 = fibDP(n - 2); + + /* + Later, it will go back to its previous values(2-3), cand1, cand2 values will be updated. + after, getting values (1,1), those values get added and updated at 5th index. + this will repeat in each iteration, + You can check(print) manually the values of cand1, cand2, n and dp[n] + at multiple instances to get a proper idea of structure of the program + dp[n] = cand1 + cand2; This statement is used to store the fibonacci series in the array + here, we will be returning the final values of cand1, cand2. */ + return (cand1 + cand2); +} + +int main(int argc, char const *argv[]) +{ + int n, result; + + printf("Enter a Number to find the Fibonacci using DP apporach: "); + scanf("%d", &n); + + result = fibDP(n); + printf("\n Fibonacci of %d is: %d", n, result); + + return 0; +} + +/* +TestCase-1: +Sample Input: 6 +Sample Output: 8 + +TestCase-2: +Sample Input: 10 +Sample Output: 55 +*/ + diff --git a/Fibonacci_Number_Using_DP_Approach/Fibonacci_Number_Using_DP_Approach.cpp b/Fibonacci_Number_Using_DP_Approach/Fibonacci_Number_Using_DP_Approach.cpp new file mode 100644 index 000000000..c0507595f --- /dev/null +++ b/Fibonacci_Number_Using_DP_Approach/Fibonacci_Number_Using_DP_Approach.cpp @@ -0,0 +1,51 @@ +#include +using namespace std; +int dp[100005] = {0}; + +int fibDP(int n) +{ + if(n == 0 or n == 1) + { + return n; + } + + /* This is used to print the values or series of given fibonacci number. + if(dp[n] != 0) + { + return dp[n]; + }*/ + + /* This recursion is to hold the values till cand1 = 1(from 5-4-3-2-1), cand2 = 1(5-3-1) */ + int cand1 = fibDP(n - 1); + int cand2 = fibDP(n - 2); + + /* + Later, it will go back to its previous values(2-3), cand1, cand2 values will be updated. + after, getting values (1,1), those values get added and updated at 5th index. + this will repeat in each iteration, + You can check(print) manually the values of cand1, cand2, n and dp[n] + at multiple instances to get a proper idea of structure of the program + dp[n] = cand1 + cand2; This statement is used to store the fibonacci series in the array + here, we will be returning the final values of cand1, cand2. */ + return (cand1 + cand2); +} + +int main(int argc, char const *argv[]) +{ + int n; + cout << "Enter a Number to find the Fibonacci using DP apporach: "; + cin >> n; + cout << "Fibonacci of " << n << " is: " << fibDP(n); + return 0; +} + +/* +TestCase-1: +Sample Input: 6 +Sample Output: 8 + +TestCase-2: +Sample Input: 10 +Sample Output: 55 +*/ + diff --git a/Fibonacci_Number_Using_DP_Approach/Fibonacci_Number_Using_DP_Approach.java b/Fibonacci_Number_Using_DP_Approach/Fibonacci_Number_Using_DP_Approach.java new file mode 100644 index 000000000..3029aa51e --- /dev/null +++ b/Fibonacci_Number_Using_DP_Approach/Fibonacci_Number_Using_DP_Approach.java @@ -0,0 +1,60 @@ +import java.util.*; + +class findingFib +{ + int dp[] = new int[100005]; + + int fibDP(int n) + { + if(n == 0 || n == 1) + { + return n; + } + + /* This is used to print the values or series of given fibonacci number. + if(dp[n] != 0) + { + return dp[n]; + }*/ + + /* This recursion is to hold the values till cand1 = 1(from 5-4-3-2-1), cand2 = 1(5-3-1) */ + int cand1 = fibDP(n-1); + int cand2 = fibDP(n-2); + + /* Later, it will go back to its previous values(2-3), cand1, cand2 values will be updated. + after, getting values (1,1), those values get added and updated at 5th index. + this will repeat in each iteration, + You can check(print) manually the values of cand1, cand2, n and dp[n] + at multiple instances to get a proper idea of structure of the program + dp[n] = cand1 + cand2; This statement is used to store the fibonacci series in the array + here, we will be returning the final values of cand1, cand2. */ + return (cand1 + cand2); + } +} + +class Mainer +{ + public static void main(String args[]) + { + findingFib ob1 = new findingFib(); + int n, result; + + Scanner s = new Scanner(System.in); + System.out.print("Enter a Number to find the Fibonacci using DP apporach: "); + n = s.nextInt(); + + result = ob1.fibDP(n); + System.out.println("Fibonacci of " + n + " is: " + result); + } +} + +/* +TestCase-1: +Sample Input: 6 +Sample Output: 8 + +TestCase-2: +Sample Input: 10 +Sample Output: 55 +*/ + diff --git a/Floyd_Cycle_Detection_Algorithm/README.md b/Floyd_Cycle_Detection_Algorithm/README.md new file mode 100644 index 000000000..cb8606196 --- /dev/null +++ b/Floyd_Cycle_Detection_Algorithm/README.md @@ -0,0 +1,36 @@ +# Flyod's_Cycle_Detection + +Floyd's cycle-finding algorithm is a pointer algorithm that uses only two pointers, which move through the sequence at different speeds. It determines if a singly linked list is circular and if it is, It is going to return the node where the cycle begins +It was invented by **Robert W. Floyd** in late 1960s. +The algorithm is also popularly known as **The Tortoise and the Hare (Floyd’s Algorithm)** + + +## Algorithm + +1. Initialize two pointers (tortoise and hare) that both point to the head of the linked list +2. Loop as long as the hare does not reach null +3. Set tortoise to next node +4. Set hare to next, next node +5. If they are at the same node, reset the tortoise back to the head. +6. Have both tortoise and hare both move one node at a time until they meet again +7. Return the node in which they meet +8. Else, if the hare reaches null, then return null + +## Pseudo code +``` +Node Cycle_detection(Node Hare, Node Tortoise) + while(Tortoise and Hare and Hare->next) + Tortoise = Tortoise->next + Hare = Hare->next->next + if(Hare == Tortoise) + return Hare + return null +``` +## Example + +![Gif-hare-tortoise](https://miro.medium.com/max/780/1*clbAFjEFicLYjsq4pVVP4g.gif) + +## Complexity + +Time Complexity - O(N) , N :- Length of List
+Space Complexity - O(1) \ No newline at end of file diff --git a/Floyd_Warshall_Algorithm/Floyd_Warshall.js b/Floyd_Warshall_Algorithm/Floyd_Warshall.js new file mode 100644 index 000000000..5af0847ed --- /dev/null +++ b/Floyd_Warshall_Algorithm/Floyd_Warshall.js @@ -0,0 +1,88 @@ +/*The Floyd Warshall Algorithm is for solving the All Pairs Shortest Path problem. +The problem is to find shortest distances between every pair of vertices in a given +edge weighted directed Graph.This is Floyd Warshall algorithm in java script.*/ + +class Graph { + constructor() { + this.edges = {}; + this.nodes = []; + } + + addNode(node) { + this.nodes.push(node); + this.edges[node] = []; + } + + addEdge(node1, node2, weight =1) { + this.edges[node1].push({node:node2, weight:weight }); + this.edges[node2].push({node:node1, weight:weight }); + } + + floydWarshallAlgorithm() { + let dist = {}; + for (let i = 0; i < this.nodes.length; i++) { + dist[this.nodes[i]] = {}; + + // For existing edges assign the dist to be same as weight + this.edges[this.nodes[i]].forEach(e = > (dist[this.nodes[i]][e.node] = e.weight)); + + this.nodes.forEach(n = > { + // For all other nodes assign it to infinity + if (dist[this.nodes[i]][n] == undefined) + dist[this.nodes[i]][n] = Infinity; + // For self edge assign dist to be 0 + if (this.nodes[i] == = n) dist[this.nodes[i]][n] = 0; + }); + } + + this.nodes.forEach(i = > { + this.nodes.forEach(j = > { + this.nodes.forEach(k = > { + // Check if going from i to k then from k to j is better + // than directly going from i to j. If yes then update + // i to j value to the new value + if (dist[i][k] + dist[k][j] < dist[i][j]) + dist[i][j] = dist[i][k] + dist[k][j]; + }); + }); + }); + return dist; + } +} + + let g = new Graph(); + + var edges = prompt("Please enter number of edges", "5"); + + var vertices = prompt("Please enter number of vertices", "5"); + + for(let i=0;i, nVertices: Int) { + val dist = Array(nVertices) { DoubleArray(nVertices) { Double.POSITIVE_INFINITY } } + for (w in weights) dist[w[0] - 1][w[1] - 1] = w[2].toDouble() + val next = Array(nVertices) { IntArray(nVertices) } + for (i in 0 until next.size) { + for (j in 0 until next.size) { + if (i != j) next[i][j] = j + 1 + } + } + for (k in 0 until nVertices) { + for (i in 0 until nVertices) { + for (j in 0 until nVertices) { + if (dist[i][k] + dist[k][j] < dist[i][j]) { + dist[i][j] = dist[i][k] + dist[k][j] + next[i][j] = next[i][k] + } + } + } + } + printResult(dist, next) + } + + private fun printResult(dist: Array, next: Array) { + var u: Int + var v: Int + var path: String + println("pair dist path") + for (i in 0 until next.size) { + for (j in 0 until next.size) { + if (i != j) { + u = i + 1 + v = j + 1 + path = ("%d -> %d %2d %s").format(u, v, dist[i][j].toInt(), u) + do { + u = next[u - 1][v - 1] + path += " -> " + u + } while (u != v) + println(path) + } + } + } + } +} + +fun main(args: Array) { + val weights = arrayOf( + intArrayOf(1, 3, -2), + intArrayOf(2, 1, 4), + intArrayOf(2, 3, 3), + intArrayOf(3, 4, 2), + intArrayOf(4, 2, -1) + ) + val nVertices = 4 + FloydWarshall.doCalcs(weights, nVertices) +} + +/* +* Output: +* +* pair dist path +* 1 -> 2 -1 1 -> 3 -> 4 -> 2 +* 1 -> 3 -2 1 -> 3 +* 1 -> 4 0 1 -> 3 -> 4 +* 2 -> 1 4 2 -> 1 +* 2 -> 3 2 2 -> 1 -> 3 +* 2 -> 4 4 2 -> 1 -> 3 -> 4 +* 3 -> 1 5 3 -> 4 -> 2 -> 1 +* 3 -> 2 1 3 -> 4 -> 2 +* 3 -> 4 2 3 -> 4 +* 4 -> 1 3 4 -> 2 -> 1 +* 4 -> 2 -1 4 -> 2 +* 4 -> 3 1 4 -> 2 -> 1 -> 3 +* +*/ + diff --git a/Floyd_Warshall_Algorithm/Floyd_Warshall_Algorithm.rb b/Floyd_Warshall_Algorithm/Floyd_Warshall_Algorithm.rb new file mode 100644 index 000000000..c416f3b36 --- /dev/null +++ b/Floyd_Warshall_Algorithm/Floyd_Warshall_Algorithm.rb @@ -0,0 +1,96 @@ +## Floyd Warshall Algorithm In Ruby + +def floyd_warshall(node, edge) + dist = Array.new(node){|i| Array.new(node){|j| i == j ? 0 : Float::INFINITY}} + next_node = Array.new(node){Array.new(node)} + edge.each do |u, v, w| + dist[u - 1][v - 1] = w + next_node[u - 1][v - 1] = v - 1 + end + + node.times do |k| + node.times do |i| + node.times do |j| + if dist[i][j] > dist[i][k] + dist[k][j] + dist[i][j] = dist[i][k] + dist[k][j] + next_node[i][j] = next_node[i][k] + end + end + end + end + + ## Displaying The Output + puts "Pair Distance Path" + node.times do |i| + node.times do |j| + next if i == j + u = i + path = [u] + path << (u = next_node[u][j]) while u != j + path = path.map{|u| u + 1}.join(" -> ") + puts "%d -> %d %6d %s" % [i + 1, j + 1, dist[i][j], path] + end + end +end + +## User Input For Number Of Nodes +puts "Enter the number of Nodes: " +nodes = gets.to_i + +## User Input For Number Of Edge Pairs +puts "Enter number of Edge Pairs: " +pair = gets.to_i + +puts "\nFor Edge Matrix, Enter Starting Node, Ending Node & Distance Between Them..." + +edge_matrix = Array.new(pair) { Array.new(3) } + +i = 0 +counter = 0 + +while(counter != pair) + i = 0 + puts "\nEnter the values of row #{counter + 1}: " + while(i != 3) + edge_matrix[counter][i] = gets.to_i + i += 1 + end + counter += 1 +end + +puts + +floyd_warshall(nodes, edge_matrix) + += begin + +Enter the number of Nodes: 4 +Enter number of Edge Pairs: 5 + +For Edge Matrix, Enter Starting Node, Ending Node & Distance Between Them... + +Enter the values of row 1: 1 3 -2 + +Enter the values of row 2: 2 1 4 + +Enter the values of row 3: 2 3 3 + +Enter the values of row 4: 3 4 2 + +Enter the values of row 5: 4 2 -1 + +Pair Distance Path +1 -> 2 -1 1 -> 3 -> 4 -> 2 +1 -> 3 -2 1 -> 3 +1 -> 4 0 1 -> 3 -> 4 +2 -> 1 4 2 -> 1 +2 -> 3 2 2 -> 1 -> 3 +2 -> 4 4 2 -> 1 -> 3 -> 4 +3 -> 1 5 3 -> 4 -> 2 -> 1 +3 -> 2 1 3 -> 4 -> 2 +3 -> 4 2 3 -> 4 +4 -> 1 3 4 -> 2 -> 1 +4 -> 2 -1 4 -> 2 +4 -> 3 1 4 -> 2 -> 1 -> 3 + += end diff --git a/Floyd_Warshall_Algorithm/README.md b/Floyd_Warshall_Algorithm/README.md new file mode 100644 index 000000000..8ddcf4081 --- /dev/null +++ b/Floyd_Warshall_Algorithm/README.md @@ -0,0 +1,111 @@ +# Floyd Warshall Algorithm + +In computer science, the **Floyd–Warshall algorithm** is an algorithm for finding +shortest paths in a weighted graph with positive or negative edge weights (but +with no negative cycles). A single execution of the algorithm will find the +lengths (summed weights) of shortest paths between all pairs of vertices. + +## Algorithm + +The Floyd–Warshall algorithm compares all possible paths through the graph between +each pair of vertices. It is able to do this with `O(|V|^3)` comparisons in a graph. +This is remarkable considering that there may be up to `|V|^2` edges in the graph, +and every combination of edges is tested. It does so by incrementally improving an +estimate on the shortest path between two vertices, until the estimate is optimal. + +Consider a graph `G` with vertices `V` numbered `1` through `N`. Further consider +a function `shortestPath(i, j, k)` that returns the shortest possible path +from `i` to `j` using vertices only from the set `{1, 2, ..., k}` as +intermediate points along the way. Now, given this function, our goal is to +find the shortest path from each `i` to each `j` using only vertices +in `{1, 2, ..., N}`. + +![Recursive Formula](https://wikimedia.org/api/rest_v1/media/math/render/svg/f9b75e25063384ccca499c56f9a279abf661ad3b) + +![Recursive Formula](https://wikimedia.org/api/rest_v1/media/math/render/svg/34ac7c89bbb18df3fd660225fd38997079e5e513) +![Recursive Formula](https://wikimedia.org/api/rest_v1/media/math/render/svg/0326d6c14def89269c029da59eba012d0f2edc9d) + +This formula is the heart of the Floyd–Warshall algorithm. + +### Pseudo Code: + +``` +FLOYD - WARSHALL (W) + 1. n ← rows [W]. + 2. D0 ← W + 3. for k ← 1 to n + 4. do for i ← 1 to n + 5. do for j ← 1 to n + 6. do d(i, j, k) ← min ( d(i, j, k-1),d(i, k, k-1) + d(k, j, k-1) ) + 7. return D(n) +``` + +## Time complexity +The strategy adopted by the Floyd-Warshall algorithm is Dynamic Programming. +The running time of the Floyd-Warshall algorithm is determined by the triply nested for loops of lines 3-6. +Each execution of line 6 takes O (1) time. The algorithm thus runs in time θ(n3 ). + +## Example + +The algorithm above is executed on the graph on the left below: + +![Example](https://upload.wikimedia.org/wikipedia/commons/2/2e/Floyd-Warshall_example.svg) + +In the tables below `i` is row numbers and `j` is column numbers. + + +**k = 0** + +| | 1 | 2 | 3 | 4 | +|:-----:|:---:|:---:|:---:|:---:| +| **1** | 0 | ∞ | −2 | ∞ | +| **2** | 4 | 0 | 3 | ∞ | +| **3** | ∞ | ∞ | 0 | 2 | +| **4** | ∞ | −1 | ∞ | 0 | + + +**k = 1** + +| | 1 | 2 | 3 | 4 | +|:-----:|:---:|:---:|:---:|:---:| +| **1** | 0 | ∞ | −2 | ∞ | +| **2** | 4 | 0 | 2 | ∞ | +| **3** | ∞ | ∞ | 0 | 2 | +| **4** | ∞ | − | ∞ | 0 | + + +**k = 2** + +| | 1 | 2 | 3 | 4 | +|:-----:|:---:|:---:|:---:|:---:| +| **1** | 0 | ∞ | −2 | ∞ | +| **2** | 4 | 0 | 2 | ∞ | +| **3** | ∞ | ∞ | 0 | 2 | +| **4** | 3 | −1 | 1 | 0 | + + +**k = 3** + +| | 1 | 2 | 3 | 4 | +|:-----:|:---:|:---:|:---:|:---:| +| **1** | 0 | ∞ | −2 | 0 | +| **2** | 4 | 0 | 2 | 4 | +| **3** | ∞ | ∞ | 0 | 2 | +| **4** | 3 | −1 | 1 | 0 | + + +**k = 4** + +| | 1 | 2 | 3 | 4 | +|:-----:|:---:|:---:|:---:|:---:| +| **1** | 0 | −1 | −2 | 0 | +| **2** | 4 | 0 | 2 | 4 | +| **3** | 5 | 1 | 0 | 2 | +| **4** | 3 | −1 | 1 | 0 | + + +## Implementation +* [CPP Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Floyd_Warshall_Algorithm/Floyd_Warshall_Algorithm.cpp) +* [Go Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Floyd_Warshall_Algorithm/Floyd_Warshall_Algorithm.go) +* [Java Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Floyd_Warshall_Algorithm/Floyd_Warshall_Algorithm.java) +* [Python Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Floyd_Warshall_Algorithm/Floyd_Warshall_Algorithm.py) diff --git a/Ford_Fulkerson_Method/Ford_Fulkerson_Method.js b/Ford_Fulkerson_Method/Ford_Fulkerson_Method.js new file mode 100644 index 000000000..fc177a725 --- /dev/null +++ b/Ford_Fulkerson_Method/Ford_Fulkerson_Method.js @@ -0,0 +1,142 @@ +//+++++++++++++++Utility+++++++++++++++++ +//Queue Data Structure implemented +function Queue() { + this.elements = []; + } + Queue.prototype.enqueue = function (e) { + this.elements.push(e); + }; + // remove an element from the front of the queue +Queue.prototype.dequeue = function () { + return this.elements.shift(); +}; +// check if the queue is empty +Queue.prototype.isEmpty = function () { + return this.elements.length == 0; +}; +// get the element at the front of the queue +Queue.prototype.peek = function () { + return !this.isEmpty() ? this.elements[0] : undefined; +}; +Queue.prototype.length = function() { + return this.elements.length; +} + +//++++++++++++++++++++++++++++++++++++++++++ +//Function to do breadth first search in graph +function bfs(reducedGraph, source, sink, path, V) +{ + //array to store if the node is visited or not + var visited = [V]; + //intially no node is visited + for (var i = 0; i < V; i++) + visited[i] = false; + let q = new Queue(); + //Starting from source + q.enqueue(source); + visited[source] = true; + //parent of starting node will be nothing hence -1 is stored in it + path[source] = -1; + + while (!q.isEmpty()) + { + var u = q.peek(); + q.dequeue(); + for(var v = 0; v < V; v++) + { + if(visited[v] === false && reducedGraph[u][v] > 0) + { + q.enqueue(v); + path[v] = u; + visited[v] = true; + } + } + } + //If there exist path from source to sink then it will return true else false + return (visited[sink] === true); +} + +function fordFulkerson(graph,source,sink,V) +{ + //reducedGraph is used to store the remaining capacity. reducedGraph[i][j] + //indicates remaining capacity of edge from i to jif edge exists. + var reducedGraph = []; + for( var i = 0; i < V; i++) + { + reducedGraph[i] = []; + for(var j = 0; j < V; j++) + { + reducedGraph[i][j] = graph[i][j]; + } + } + //Path is used to store parent + var path = [V]; + //variable to store maximum flow in the path chosen + var max_flow = 0; + while (bfs(reducedGraph, source, sink, path, V)) + { + var path_flow = Number.MAX_VALUE; + //Finding maximum flow in the path selected + for(var v = sink; v != source; v = path[v]) + { + var u = path[v]; + path_flow = Math.min( path_flow, reducedGraph[u][v]); + } + //Updating remaining capacity odf the edges + for( var v = sink ; v != source; v = path[v]) + { + var u = path[v]; + reducedGraph[u][v] -= path_flow; + reducedGraph[v][u] += path_flow; + } + max_flow += path_flow; + } + return max_flow; +} +//Used synchronous readline package to take console input +var readlineSync = require('readline-sync'); +//Input number of nodes in a graph +var V = readlineSync.question('Enter number of nodes in a graph: '); +//Input the weight matrix for the directed graph + +var graph = []; +for(var i = 0; i < V; i++) +{ + graph[i] = []; + for(var j = 0; j < V; j++) + { + console.log(`Enter the weight form ` , i , `to `,j, `: `); + var a = readlineSync.question(); + graph[i][j] = a; + } +} +var source = readlineSync.question("Enter source: "); +var sink = readlineSync.question("Enter Sink: "); +var ans = fordFulkerson(graph,source,sink,V); +console.log('Maximum flow from source to sink is: ', ans); +/*Input1: +V = 6 +graph = [ [0, 16, 13, 0, 0, 0], + [0, 0, 10, 12, 0, 0], + [0, 4, 0, 0, 14, 0], + [0, 0, 9, 0, 0, 20], + [0, 0, 0, 7, 0, 4], + [0, 0, 0, 0, 0, 0] + ]; +source = 0 sink = 5 +Output1: 23 + +Input2: +V = 6 +graph = [ [0, 10, 0, 3, 0, 0], + [0, 0, 8, 2, 0, 0], + [0, 0, 0, 0, , 10], + [0, 0, 6, 0, 7, 0], + [0, 0, 0, 0, 10, 0], + [0, 0, 0, 0, 0, 0] + ]; +source = 0 +sink = 5 +Output2: 10 +*/ + diff --git a/Ford_Fulkerson_Method/README.md b/Ford_Fulkerson_Method/README.md new file mode 100644 index 000000000..74c1fddd7 --- /dev/null +++ b/Ford_Fulkerson_Method/README.md @@ -0,0 +1,70 @@ +# Ford-Fulkerson Algorithm + +The Ford-Fulkerson algorithm is an algorithm that tackles the max-flow min-cut problem. That is, given a network with vertices and edges between those vertices that have certain weights, how much "flow" can the network process at a time? Flow can mean anything, but typically it means data through a computer network. + +It was discovered in 1956 by Ford and Fulkerson. This algorithm is sometimes referred to as a method because parts of its protocol are not fully specified and can vary from implementation to implementation. An algorithm typically refers to a specific protocol for solving a problem, whereas a method is a more general approach to a problem. + +The Ford-Fulkerson algorithm assumes that the input will be a graph, GG, along with a source vertex, ss, and a sink vertex, tt. The graph is any representation of a weighted graph where vertices are connected by edges of specified weights. There must also be a source vertex and sink vertex to understand the beginning and end of the flow network. + +Ford-Fulkerson has a complexity of O\big(|E| \cdot f^{*}\big),O(∣E∣⋅f +∗ + ), where f^{*}f +∗ + is the maximum flow of the network. The Ford-Fulkerson algorithm was eventually improved upon by the Edmonds-Karp algorithm, which does the same thing in O\big(V^2 \cdot E\big)O(V +2 + ⋅E) time, independent of the maximum flow value. + +## ALGORITHM +Follow 3 basic steps: +1. Find augmented path +2. Complete the bottle neck capacity +3. Augment each edge and total flow +Repeat these steps until the augmented path is reached + +### Example: +![step1](https://github.com/syedareehaquasar/hello-world/blob/master/e.PNG) +here only 2 spaces are there in DT so taking 2 +![step2](https://github.com/syedareehaquasar/hello-world/blob/master/ee.PNG) +Similarly another path +![step3](https://github.com/syedareehaquasar/hello-world/blob/master/eee.PNG) +Similarly another path +![step5](https://github.com/syedareehaquasar/hello-world/blob/master/eeeee.PNG) +Similarly another path +![step6](https://github.com/syedareehaquasar/hello-world/blob/master/eeeeeeeeeee.PNG) +Here paths SA and CD are full but we require 2 in AC but place of only 1 in CD so we have reached our answer ->19 +![final answer](https://github.com/syedareehaquasar/hello-world/blob/master/eeeeeeeeeeeeeee.PNG) + +## PSEUDOCODE + +The pseudo-code for this method is quite short; however, there are some functions that bear further discussion. The simple pseudo-code is below. +This pseudo-code is not written in any specific computer language. Instead, it is an informal, high-level description of the algorithm. + +Ford-Fulkerson Algorithm ((Graph GG, source ss, sink t):t): +``` +initialize flow to 0 +path = findAugmentingPath(G, s, t) +while path exists: + augment flow along path #This is purposefully ambiguous for now + G_f = createResidualGraph() + path = findAugmentingPath(G_f, s, t) +return flow +``` + +# Time Complexity +O(max_flow * E) +Time complexity of the above algorithm is O(max_flow * E). We run a loop while there is an augmenting path. In worst case, we may add 1 unit flow in every iteration. Therefore the time complexity becomes O(max_flow * E) +![tc](https://github.com/syedareehaquasar/hello-world/blob/master/h.PNG) + +# Implementation + + - [c code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Ford_Fulkerson_Method/Ford_Fulkerson_Method.c) + - [coffee code] + - [cpp code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Ford_Fulkerson_Method/Ford-Fulkerson.cpp) + - [c# code] + - [go code] + - [java code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Ford_Fulkerson_Method/Ford_Fulkerson_Method.java) + - [javaScript code] + - [kotlin code] + - [python code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Ford_Fulkerson_Method/Ford_Fulkerson_Method.py) + - [ruby code] + - [dart code] diff --git a/Freq_Of_Elements_Of_Array/CountFrequencyOfArrayElements.java b/Freq_Of_Elements_Of_Array/CountFrequencyOfArrayElements.java new file mode 100644 index 000000000..d44303278 --- /dev/null +++ b/Freq_Of_Elements_Of_Array/CountFrequencyOfArrayElements.java @@ -0,0 +1,62 @@ +/*Problem Statement + * Given an array of elements count the frequency of every element in the array. + */ + +import java.util.HashMap; +import java.util.Scanner; + +public class CountFrequencyOfArrayElements +{ + + public static void main(String[] args) + { + Scanner sc = new Scanner(System.in); + + // input size of array + int n = sc.nextInt(); + // input array + int a[] = new int[n]; + for(int i = 0; i < n; i++) + a[i] = sc.nextInt(); + + countFreq(a, n); + + sc.close(); + } + + // function to count frequency + private static void countFreq(int[] a, int n) { + // using hashmap to store the freq + HashMap hm = new HashMap<>(); + for(int i = 0; i < n; i++) + { + if( hm.containsKey(a[i]) ) + hm.put( a[i], hm.get(a[i]) + 1); + else + hm.put(a[i], 1); + } + + //display the frequencies + System.out.println("Element \t Frequency"); + hm.forEach( + (k,v) -> + { + System.out.println(k + " \t\t " + v); + } + ); + } + +} + +/* + * Input : +5 +2 1 1 6 1 + + * Output : +Element Frequency +1 3 +2 1 +6 1 + + * */ diff --git a/GenericTree_Levelorder_Traversal/GenericTree_Levelorder_Traversal.java b/GenericTree_Levelorder_Traversal/GenericTree_Levelorder_Traversal.java new file mode 100644 index 000000000..cb1726cf7 --- /dev/null +++ b/GenericTree_Levelorder_Traversal/GenericTree_Levelorder_Traversal.java @@ -0,0 +1,94 @@ +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.Scanner; + +public class GenericTree_Levelorder_Traversal { + Scanner scn = new Scanner(System.in); + + private class Node { + int data; + ArrayList children = new ArrayList<>(); + } + + private Node root; + + public GenericTree_Levelorder_Traversal() { + root = takeInput(null, -1); + } + + private Node takeInput(Node parent, int ith) { + if (parent == null) { + System.out.println("Enter the data for Root Node ?"); + } else { + System.out.println( + "Enter data for " + ith + " child of " + parent.data); + } + + // take input + int item = scn.nextInt(); + // make a new node + Node nn = new Node(); + nn.data = item; + + System.out.println("No. of children for " + nn.data + " ?"); + int noc = scn.nextInt(); + + for (int i = 0; i < noc; i++) { + + Node child = takeInput(nn, i); + // add children in array list + nn.children.add(child); + } + return nn; + } + + public void display() { + display(root); + } + + // function to display generic tree + private void display(Node node) { + String str = node.data + " -> "; + + for (Node child : node.children) { + str += child.data + ", "; + } + + str += "."; + System.out.println(str); + + for (Node child : node.children) { + display(child); + } + } + + // level order traversal + public void levelorder() { + // create a linked list which will be used as queue + LinkedList queue = new LinkedList(); + // add root node to last of queue + queue.addLast(root); + + while (!queue.isEmpty()) { + + // remove node from front and print + Node rn = queue.removeFirst(); + + System.out.print(rn.data + " "); + + // add children of current node to the end of queue + for (Node child : rn.children) { + queue.addLast(child); + } + } + System.out.println(); + } + + public static void main(String[] args) { + GenericTree_Levelorder_Traversal gt = new GenericTree_Levelorder_Traversal(); + gt.levelorder(); + } +} + +//SAMPLE INPUT: 10 3 20 2 50 0 60 0 30 0 40 0 +//OUTPUT: 10 20 30 40 50 60 diff --git a/Gnome_Sort/Gnome_Sort.c b/Gnome_Sort/Gnome_Sort.c new file mode 100644 index 000000000..ee2987699 --- /dev/null +++ b/Gnome_Sort/Gnome_Sort.c @@ -0,0 +1,62 @@ +#include + +// A function which is used to sort the algorithm using gnome sort +void gnome_sort(int arr[], int n) { + + int index = 0; + while (index < n){ + + if (index == 0 || arr[index - 1] <= arr[index]){ + index++; + } + else{ + int temp = arr[index-1]; + arr[index - 1] = arr[index]; + arr[index] = temp; + index = index - 1; + + } + + } + +} + +// Main function. +int main() +{ + int n; + printf("Enter the size of an Array: "); + scanf("%d", &n); + int arr[n]; + + for(int i = 0; i < n; i++){ + scanf("%d", &arr[i]); + } + + gnome_sort(arr, n); + + for(int i = 0; i < n; i++){ + printf("%d\n", arr[i]); + } + + return 0; +} + +/* + Sample Driver Code: + INPUT: + Enter the size of an Array: 5 + 3 + 2 + 1 + -5 + 7 + + OUTPUT: + -5 + 1 + 2 + 3 + 7 + +*/ diff --git a/Gnome_Sort/Gnome_Sort.cpp b/Gnome_Sort/Gnome_Sort.cpp new file mode 100644 index 000000000..9912482c9 --- /dev/null +++ b/Gnome_Sort/Gnome_Sort.cpp @@ -0,0 +1,62 @@ +#include + +using namespace std; + +// A function that is used to sort the algorithm using gnome sort +void gnome_sort(int arr[], int n) { + + // Implementation Logic Begins here + int index = 0; + + while (index < n) { + // Intially Index is set to Zero then It will be incremented to 1 + if (index == 0) + index++; + // Checking the values between the array elements + if (arr[index] >= arr[index - 1]) + index++; + else { + swap(arr[index], arr[index - 1]); + index--; + } + } +} + +// Main function. +int main() +{ + + int n; + cout << "Enter the size of an Array: "; + cin >> n; + int arr[n]; + for(int i = 0; i < n; i++){ + cin >> arr[i]; + } + gnome_sort(arr, n); + + for(int i = 0; i < n; i++){ + cout << arr[i] <= arr[index - 1]) + index++; + else { + int temp = 0; + temp = arr[index]; + arr[index] = arr[index - 1]; + arr[index - 1] = temp; + index--; + } + } + } + + // Sample Input to test above function + public static void main(String[] args) { + + Scanner sc = new Scanner(System.in); + System.out.print("Enter the Size of an Array: "); + int n = sc.nextInt(); + int arr[] = new int[n]; + for(int i=0; i= arr[index - 1]: + index = index + 1 + else: + arr[index], arr[index-1] = arr[index-1], arr[index] + index = index - 1 + + return arr + +# Test Code +n = int(input("Enter the size of an Array: ")) +arr = list() +for i in range(n): + val = int(input()) + arr.append(val) +# Function Call +result = gnome_sort(arr,n) +print(result) + +''' + Sample Driver Code: + INPUT: + Enter the size of an Array: 5 + 3 + 2 + 1 + -5 + 7 + + OUTPUT: + -5 + 1 + 2 + 3 + 7 + +''' diff --git a/Gray_Code/Gray_Code.cpp b/Gray_Code/Gray_Code.cpp new file mode 100644 index 000000000..2c349500b --- /dev/null +++ b/Gray_Code/Gray_Code.cpp @@ -0,0 +1,53 @@ +//C++ program to generate the Gray Code for any input bit length + +#include +#define pb push_back +using namespace std; + +// Function to generate the Gray Code sequence +void Gray(int n){ + //If input size is less than or equal to 0 + if(n <= 0){ + cout << "Invalid input"; + return; + } + + vector v; + v.pb("0"); + v.pb("1"); + + for(int i = 2; i < (1 << n); i <<= 1){ + for(int j = i - 1; j >= 0; j--) + v.pb(v[j]); + + for(int j = 0; j < i; j++) + v[j] = "0" + v[j]; + + for(int j = i; j < 2 * i; j++) + v[j] = "1" + v[j]; + } + + cout << "Gray Code for bit length = " << n << " : " << endl; + + for(int i = 0; i < v.size(); i++) + cout << v[i] << endl; +} + +int main(){ + int n; + cout << "Enter the bit length for Gray Code generation : "; + cin >> n; + Gray(n); +} + +/* Sample input-output +Enter the bit length for Gray Code generation : 3 +Gray Code for bit length = 3 : +000 +001 +011 +010 +110 +111 +101 +100 */ diff --git a/Heap_Sort/heap_sort.php b/Heap_Sort/heap_sort.php new file mode 100644 index 000000000..f16b141cc --- /dev/null +++ b/Heap_Sort/heap_sort.php @@ -0,0 +1,74 @@ + $data[$index]) // If left child is larger than root + $largest = $left; + else + $largest = $index; + + if ($right < $heapSize && $data[$right] > $data[$largest]) // If right child is larger than largest so far + $largest = $right; + + if ($largest != $index) // If largest is not root + { + $temp = $data[$index]; + $data[$index] = $data[$largest]; + $data[$largest] = $temp; + + //Recursively heapify the affected sub-tree + MaxHeapify($data, $heapSize, $largest); + } +} + +function HeapSort(&$data, $count) { + $heapSize = $count; + + // Build heap (rearrange array) + for ($p = ($heapSize - 1) / 2; $p >= 0; $p--) + MaxHeapify($data, $heapSize, $p); + + // One by one extract an element from heap + for ($i = $count - 1; $i > 0; $i--) + { + $temp = $data[$i]; + $data[$i] = $data[0]; + $data[0] = $temp; + + $heapSize--; + MaxHeapify($data, $heapSize, 0); + } +} + +// example of driver function +$array = array(20 , 43 , 65 , 88 , 11 , 33 , 56 , 74); +HeapSort($array , 8); +print_r($array); + + // output + /*Array + ( + [0] => 11 + [1] => 20 + [2] => 33 + [3] => 65 + [4] => 43 + [5] => 56 + [6] => 74 + [7] => 88 + ) + +*/ + +?> diff --git a/Heap_Sort/heapsort.go b/Heap_Sort/heapsort.go new file mode 100644 index 000000000..16b1548d3 --- /dev/null +++ b/Heap_Sort/heapsort.go @@ -0,0 +1,99 @@ +/* Heap Sort is a comparison-based sorting method performed on a Heap data structure. + Here we build a max heap first to later sort the elements in the heap in ascending order. +*/ + +package main +import "fmt" + +func max_heapify(arr []int, n int, i int) { + + largest := i // Initialize largest as root + l := 2 * i + 1 // left child + r := 2 * i + 2 // right child + + // If left child is larger than root + if l < n && arr[l] > arr[largest] { + largest = l + } + + // If right child is larger than largest so far + if r < n && arr[r] > arr[largest] { + largest = r + } + + // If largest is not root + if largest != i { + + //swapping + arr[i], arr[largest] = arr[largest], arr[i] + + // Recursively heapify the affected sub-tree + max_heapify(arr, n, largest) + } +} + +func heapSort(arr []int, n int) { + + // Build heap (rearrange array) + for i := n / 2 - 1; i >= 0; i-- { + max_heapify(arr, n, i) + } + + // One by one extract an element from heap + for i := n - 1; i >= 0; i-- { + + // Move current root to end + arr[0], arr[i] = arr[i], arr[0]; + + // call heapify on the reduced heap + max_heapify(arr, i, 0); + } +} + +func printArray(arr []int, no int) { + + //printing the sorted array + for i := 0; i < no; i++ { + fmt.Print(arr[i], " ") + } + +} + +func main() { + var n int + fmt.Println("Enter the number of elements :") + + //accepting the number of elements from the user + fmt.Scan(&n) + arr := make([]int, n) + for i := 0; i < n; i++ { + + //accepting input elements + fmt.Scan(&arr[i]) + } + fmt.Println(arr) + + fmt.Println("\nSorted array is") + heapSort(arr, n) + printArray(arr, n) +} + +/* OUTPUT: + +Enter the number of elements : 7 +Enter the elements : +0 +12 +11 +13 +5 +6 +7 + +Original Array: [0 12 11 13 5 6 7] + +Sorted array is +0 5 6 7 11 12 13 + +*/ + diff --git a/Huffman_Encoding/Huffman_Encoding_STL.cpp b/Huffman_Encoding/Huffman_Encoding_STL.cpp new file mode 100644 index 000000000..771039956 --- /dev/null +++ b/Huffman_Encoding/Huffman_Encoding_STL.cpp @@ -0,0 +1,100 @@ +#include +using namespace std; + +// A Huffman tree node +struct MinHeap_Node{ + // Count of the character + int count; + + // One of the input characters + char data; + + // Left and right child + MinHeap_Node *left, *right; + MinHeap_Node(int count, char data){ + left = right = NULL; + this -> count = count; + this -> data = data; + } +}; + +// For comparison of two heap nodes(needed in min heap) +struct compare{ + bool operator()(MinHeap_Node *l, MinHeap_Node *r){ + return l -> count > r -> count; + } +}; + +// Prints huffman codes from the root of Huffman Tree +void print_node(MinHeap_Node *node, string s){ + if(!node) + return; + if(node -> data != '#') + cout << node -> data << " " << s << endl; + print_node(node -> left, s + "0"); + print_node(node -> right, s + "1"); +} + +// The main function that builds a Huffman Tree +// and print codes by traversing the built Huffman Tree +void Huffman(int count[], char data[], int n){ + // Min heap & inserting all characters of data[] + priority_queue, compare> heap; + + for(int i = 0; i < n; i++) + heap.push(new MinHeap_Node(count[i], data[i])); + + while(heap.size() != 1){ + // Extract the two minimum freq items from min heap + MinHeap_Node *left = heap.top(); + heap.pop(); + MinHeap_Node *right = heap.top (); + heap.pop(); + + /* Create a new internal node with count equal to the sum of + the two nodes counts.Make the two extracted node as left and + right children of this new node.Add this node to the min heap + '#' is a special value for internal nodes, not used */ + + MinHeap_Node *top = new MinHeap_Node(left -> count + right -> count, '#'); + top -> left = left; + top -> right = right; + heap.push(top); + } + + // Print Huffman codes using the Huffman tree + print_node(heap.top(), ""); +} + +int main (){ + cout << "Enter the number of input characters: "; + int n; + cin >> n; + + cout << "\nEnter the characters and corresponding count: "; + char data[n]; + int count[n]; + for(int i = 0; i < n; i++) + cin >> data[i] >> count[i]; + + cout << "Following is the Huffman Encoding:\n"; + Huffman(count, data, n); +} + +/* Sample Input-Output +Enter the number of input characters: 6 + +Enter the characters and corresponding count: a 5 +b 9 +c 12 +d 13 +e 16 +f 45 +Following is the Huffman Encoding: +f 0 +c 100 +d 101 +a 1100 +b 1101 +e 111 +*/ diff --git a/Insertion_Sort.php b/Insertion_Sort.php new file mode 100644 index 000000000..bcac45d95 --- /dev/null +++ b/Insertion_Sort.php @@ -0,0 +1,64 @@ +arr = $arr; + } + + //Printing the array + public function printArray($array) + { + for($i = 0; $i < count($array); $i++) + { + echo $array[$i]." "; + } + } + + //Sorting the array + public function sort() + { + for($i = 1; $i < count($this->arr); $i++) + { + $temp = $this->arr[$i]; + while($i > 0 && $temp < $this->arr[$i-1]) + { + $this->arr[$i] = $this->arr[$i-1]; + --$i; + } + $this->arr[$i] = $temp; + } + return $this->arr; + } +} + +//Driver Code +echo "

Implementing Insertion Sort Algorithm :

"; +$num = array(); + + for($i = 1; $i <= rand(1, 10); $i++) + { + $num[] = $i; + } + shuffle($num); + + $is = new InsertionSort($num); + +//Printing Unsorted array +echo "
Unsorted Array : "; +$is->printArray($num); + +//Printing Sorted array +echo "
Sorted Array : "; +$is->printArray($is->sort()); + +/* +Implementing Insertion Sort Algorithm : + +Unsorted Array : 5 2 3 4 8 6 1 7 + +Sorted Array : 1 2 3 4 5 6 7 8 +*/ +?> diff --git a/Insertion_Sort/Insertion_Sort.rs b/Insertion_Sort/Insertion_Sort.rs new file mode 100644 index 000000000..dcd8f880e --- /dev/null +++ b/Insertion_Sort/Insertion_Sort.rs @@ -0,0 +1,42 @@ +use std::io; +use std::str::FromStr; + +fn main() { + println!("Enter the numbers to be sorted (separated by space) : "); + let mut i = read_values :: ().unwrap(); + insertion_sort(&mut i); + println!("Sorted array: {:?}", i) +} + +fn insertion_sort(arr: &mut Vec) { + for i in 1..arr.len() { + let mut j = i; + while j > 0 && arr[j] < arr[j - 1] { + arr.swap(j, j - 1); + j = j - 1; + } + } +} + +fn read_values() -> Result, T::Err> { + let mut s = String::new(); + io::stdin() + .read_line(&mut s) + .expect("could not read from stdin"); + s.trim() + .split_whitespace() + .map(|word| word.parse()) + .collect() +} + +/* + +Sample Input : + Enter the numbers to be sorted (separated by space) : + 45 34 112 50 91 + +Sample Output : + Sorted array: [34, 45, 50, 91, 112] + +*/ + diff --git a/Insertion_Sort/README.md b/Insertion_Sort/README.md new file mode 100644 index 000000000..d1add4837 --- /dev/null +++ b/Insertion_Sort/README.md @@ -0,0 +1,130 @@ +# INSERTION SORT + +[Insertion Sort](https://en.wikipedia.org/wiki/Insertion_Sort) is a simple sorting algorithm that builds the final sorted array (or list) one item at a time. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. + +## EXAMPLE + +Given below is an unsorted array. `Insertion sort` takes O(n) time in Best Case and Ο(n2) time for Average and Worst Case. + +![Insertion Sort](https://www.tutorialspoint.com/data_structures_algorithms/images/unsorted_array.jpg) + +`Insertion sort` compares the first two elements + +![Insertion Sort](https://www.tutorialspoint.com/data_structures_algorithms/images/insertion_sort_1.jpg) + +It finds that both 14 and 33 are already in ascending order. For now, 14 is in sorted sub-list. + +![Insertion Sort](https://www.tutorialspoint.com/data_structures_algorithms/images/insertion_sort_2.jpg) + +Insertion sort moves ahead and compares 33 with 27. + +![Insertion Sort](https://www.tutorialspoint.com/data_structures_algorithms/images/insertion_sort_3.jpg) + +And finds that 33 is not in the correct position. + +![Insertion Sort](https://www.tutorialspoint.com/data_structures_algorithms/images/insertion_sort_4.jpg) + +It swaps 33 with 27. It also checks with all the elements of sorted sub-list. Here we see that the sorted sub-list has only one element 14, and 27 is greater than 14. Hence, the sorted sub-list remains sorted after swapping. + +![Insertion Sort](https://www.tutorialspoint.com/data_structures_algorithms/images/insertion_sort_5.jpg) + +By now we have 14 and 27 in the sorted sub-list. Next, it compares 33 with 10. + +![Insertion Sort](https://www.tutorialspoint.com/data_structures_algorithms/images/insertion_sort_6.jpg) + +These values are not in a sorted order. + +![Insertion Sort](https://www.tutorialspoint.com/data_structures_algorithms/images/insertion_sort_7.jpg) + +So we swap them. + +![Insertion Sort](https://www.tutorialspoint.com/data_structures_algorithms/images/insertion_sort_8.jpg) + +However, swapping makes 27 and 10 unsorted. + +![Insertion Sort](https://www.tutorialspoint.com/data_structures_algorithms/images/insertion_sort_9.jpg) + +Hence, we swap them too. + +![Insertion Sort](https://www.tutorialspoint.com/data_structures_algorithms/images/insertion_sort_10.jpg) + +Again we find 14 and 10 in an unsorted order. + +![Insertion Sort](https://www.tutorialspoint.com/data_structures_algorithms/images/insertion_sort_11.jpg) + +We swap them again. By the end of third iteration, we have a sorted sub-list of 4 items. + +![Insertion Sort](https://www.tutorialspoint.com/data_structures_algorithms/images/insertion_sort_12.jpg) + +This process goes on until all the unsorted values are covered in a sorted sub-list. Now we shall see some programming aspects of insertion sort. + +## ALGORITHM + +``` +Step 1 − If it is the first element, it is already sorted. return 1; +Step 2 − Pick next element +Step 3 − Compare with all elements in the sorted sub-list +Step 4 − Shift all the elements in the sorted sub-list that is greater than the value to be sorted +Step 5 − Insert the value +Step 6 − Repeat until list is sorted +``` + +## PSEUDOCODE + +Pseudocode of InsertionSort algorithm can be expressed as − + +``` +procedure insertionSort( A : array of items ) + int holePosition + int valueToInsert + + for i = 1 to length(A) inclusive do: + + /* select value to be inserted */ + valueToInsert = A[i] + holePosition = i + + /*locate hole position for the element to be inserted */ + + while holePosition > 0 and A[holePosition-1] > valueToInsert do: + A[holePosition] = A[holePosition-1] + holePosition = holePosition -1 + end while + + /* insert the number at hole position */ + A[holePosition] = valueToInsert + + end for + +end procedure +``` + +## COMPLEXITY + +**Time complexity** + +_Best Case_: O(n) + +_Average and Worst Case_: О(n2) + +where _n_ is the number of items being sorted. + +**Space complexity** - O(1), due to auxillary space only. + +## Implementation + +- [C Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Insertion_Sort/Insertion_Sort.c) + +- [CoffeeScript Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Insertion_Sort/Insertion_Sort.coffee) + +- [C++ Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Insertion_Sort/Insertion_Sort.cpp) + +- [C# Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Insertion_Sort/Insertion_Sort.cs) + +- [Java Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Insertion_Sort/Insertion_Sort.java) + +- [JavaScript Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Insertion_Sort/Insertion_Sort.js) + +- [PHP Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Insertion_Sort/Insertion_Sort.php) + +- [Python Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Insertion_Sort/Insertion_Sort.py) diff --git a/Integer_to_Roman/Integer_to_Roman.cpp b/Integer_to_Roman/Integer_to_Roman.cpp new file mode 100644 index 000000000..2b08ff0af --- /dev/null +++ b/Integer_to_Roman/Integer_to_Roman.cpp @@ -0,0 +1,67 @@ +/* +Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. +Symbol Value +I 1 +V 5 +X 10 +L 50 +C 100 +D 500 +M 1000 +For example, two is written as II in Roman numeral, just two one's added together. +Twelve is written as, XII, which is simply X + II. +The number twenty seven 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. +Given an integer, convert it to a roman numeral. + Input is guaranteed to be within the range from 1 to 3999. +*/ + +#include +using namespace std; +class Solution { +public: + string intToRoman(int num) { + int a[] = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000}; + string s[] = {"I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"}; + string ans = ""; + int i = 12; + while(num > 0) + { + int d = num / a[i]; + num = num % a[i]; + while(d--) + { + ans = ans + s[i]; + } + i--; + } + return ans; + } +}; + +int stringToInteger(string input) { + return stoi(input); +} + +int main() { + string line; + while (getline(cin, line)) { + int num = stringToInteger(line); + string ret = Solution().intToRoman(num); + string out = (ret); + cout << out << endl; + } + return 0; +} +/* +Input: 58 +Output: "LVIII" +Explanation: L = 50, V = 5, III = 3. +*/ diff --git a/Intro_Sort/README.md b/Intro_Sort/README.md new file mode 100644 index 000000000..b01e32410 --- /dev/null +++ b/Intro_Sort/README.md @@ -0,0 +1,111 @@ +# Introsort + +1. It was invented by David Musser in 1997. +2. It is also known as introspective sort. +3. It is a hybrid sorting algorithm(combines two or more other algorithms that solve the same problem,either choosing one depending upon the data or switching between them over the course of algorithm). +4. It provides both fast average performance and optimal worst performance,thus allowing the performance requirement to become more strict and effective. +5. It combines the good part of three algorithm i.e quick sort, heap sort,insertion sort. + +## ALGORITHM + +``` +procedure sort(A : array): + let maxdepth = ⌊log(length(A))⌋ × 2 + introsort(A, maxdepth) + +procedure introsort(A, maxdepth): + n ← length(A) + // base case + if n ≤ 1: + return + else if maxdepth = 0: + heapsort(A) + // assume this function does pivot selection, p is the final position of the pivot + else: + p ← partition(A) + introsort(A[0:p-1], maxdepth- 1) + introsort(A[p+1:n], maxdepth - 1) + +The factor 2 in the maximum depth is arbitrary; it can be tuned for practical performance. A[i:j] denotes the array slice of items i to j. +``` + +## Example + +![Introsort](https://media.geeksforgeeks.org/wp-content/uploads/20190322164239/page-11.png) + +**Input:** 2, 10, 24, 2, 10, 11, 27, 4, 2, 4, 28, 16, 9, 8, 28, 10, 13, 24, 22, 28, 0, 13, 27, 13, 3, 23, 18, 22, 8, 8 + +**Step 1:** + +begin = 0, end = 29 depthLimit = 8, a[pivot] = 8. + +As the number of elements > 16,the pivot element is calculated based on the quicksort algorithm. Using the median-of-3 concept,the pivot element is calculated and the a[pivot]=8. The method partition() finds the correct position of the a[pivot] and helps in array split-up for further recursion. Here,the element 8 (in comment) lies in the correct position and in the further steps recursion will be carried over for the sub array before and after + + 8. 2, 2, 4, 2, 4, 8, 0, 3, 8, /8/, 28, 16, 9, 11, 28, 10, 13, 24, 22, 28, 27, 13, 27, 13, 24, 23, 18, 22, 10, 10 + + +**Step 2:** From the previous step, + +begin = 0, end = 29, a[pivot] = 8 + +The recursion starts for the sub-array a[begin, pivot - 1] and a[pivot + 1, end] + +2, 2, 4, 2, 4, 8, 0, 3, 8, 8, 28, 16, 9, 11, 28, 10, 13, 24, 22, 28, 27, 13, 27, 13, 27, 13, 24, 23, 18, 22, 10, 10 + +depthLimit = 7, depthLimit = 7, begin = 0, end = 8 begin = 10, end = 29 + +Number of element <= 16 Number of element > 16, + +Hence sortDataUtil(10,29) that calculates the pivot and a[partition] = 27. + +Hence insertionSort (0,8) + +0, 2, 2, 2, 3, 4, 4, 8, 8, 8, 16, 9, 11, 10, 13, 24, 22, 10, 13, 27, 13, 24, 23, 18, 22, 10, 27, 28, 28, 28 + + +**Step 3:** From the previous step, + +depthLimit = 6, begin = 10, end = 29 + +The recursion starts for the sub-array a[begin, partition - 1] and a[partition + 1, end] + +` 0, 2, 2, 2, 3, 4, 4, 8, 8, 8, 16, 9, 11, 10, 13, 24, 22, 10, 13, 27, 13, 24, 23, 18, 22, 10, 27, 28, 28, 28 ` + + `sorted! depthLimit=6 depthLimit=6 ` + +Hence,no further recursion. + + begin = 10, end = 25 begin = 10, end = 25 + +As the number of elements < 16, insertionSort (10,25) + +As the number of element < 16, insertionSort(27,29) + +` 0, 2, 2, 2, 3, 4, 4, 8, 8, 8, 9, 10, 10, 10, 11, 13, 13, 13, 16, 18, 22, 22, 23, 24, 27, 27, 28, 28, 28 ` + +​ `Sorted! Sorted! Sorted! ` + +Hence, no further recursion hence no further recursion hence no further recursion. + + +**Step 4:** + +Output: 0, 2, 2, 2, 3, 4, 4, 8, 8, 8, 9, 10, 10, 11, 13, 13, 13, 16, 18, 22, 22, 23, 24, 24, 27, 27, 28, 28, 28 + +In the above example, the depthLimit came until 6, and for bigger datasets the depthLimit might reach 0 for certain sub-array. The heapSort is carried out only for those sub-array for sorting them. + +Output: 0, 2, 2, 2, 3, 4, 4, 8, 8, 8, 9, 10, 10, 10, 11, 13, 13, 13, 16, 18, 22, 22, 23, 24, 24, 27, 27, 28, 28, 28 + + +## Time Complexity + +Average performance O(n log n) Optimal worst performance O(n log n) where, n = number of elements to be sorted. + +## SEE ALSO : + +https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Intro_Sort/introsort.py + +## REFERENCES : + +1. https://en.wikipedia.org/wiki/Introsort +2. https://www.geeksforgeeks.org/introsort-or-introspective-sort/ diff --git a/Intro_Sort/introsort.py b/Intro_Sort/introsort.py new file mode 100644 index 000000000..b8b1ab814 --- /dev/null +++ b/Intro_Sort/introsort.py @@ -0,0 +1,101 @@ +''' +Introsort sort is a sorting algorithm that initially uses quicksort, +but switches to heap sort if the depth of the recursion is too deep, +and uses insertion sort for small cases. +''' + +#a function that takes a list as argument. +def introsort(nlist): + + #maxdepth is chosen equal to 2 times floor of log base 2 of the length of the list. + maxdepth = (len(nlist).bit_length() - 1 ) * 2 + # Call introsort_helper with start = 0 and end = len(alist). + introsort_helper(nlist, 0, len(nlist), maxdepth) + +#The function sorts the list from indexes start to end. +def introsort_helper(nlist, start, end, maxdepth): + if end - start <= 1: + return + elif maxdepth == 0: + heapsort(alist, start, end) + else: + p = partition(nlist, start, end) + introsort_helper(nlist, start, p + 1, maxdepth - 1) + introsort_helper(nlist, p + 1, end, maxdepth - 1) + +#partition function uses Hoare partition scheme to partition the list. +def partition(nlist, start, end): + pivot = nlist[start] + i = start - 1 + j = end + + while True: + i = i + 1 + while nlist[i] < pivot: + i = i + 1 + j = j - 1 + while nlist[j] > pivot: + j = j - 1 + + if i >= j: + return j + + swap(nlist, i, j) + +#function for swapping +def swap(nlist, i, j): + nlist[i], nlist[j] = nlist[j], nlist[i] + +#heapsort from indexes start to end - 1 +def heapsort(alist, start, end): + build_max_heap(nlist, start, end) + for i in range(end - 1, start, -1): + swap(alist, start, i) + max_heapify(nlist, index = 0, start = start, end = i) + +#rearrange the list into a list representation of a heap. +def build_max_heap(nlist, start, end): + def parent(i): + return (i - 1) // 2 + length = end - start + index = parent(length - 1) + while index >= 0: + max_heapify(nlist, index, start, end) + index = index - 1 + +#modifies the heap structure at and below the node at given index to make it satisfy the heap property. +def max_heapify(nlist, index, start, end): + def left(i): + return 2 * i + 1 + def right(i): + return 2 * i + 2 + + size = end - start + l = left(index) + r = right(index) + if (l < size and nlist[start + l] > nlist[start + index]): + largest = l + else: + largest = index + if (r < size and nlist[start + r] > nlist[start + largest]): + largest = r + if largest != index: + swap(alist, start + largest, start + index) + max_heapify(alist, largest, start, end) + +#taking list as input from user (dynamic input) +nlist = input('Enter the list of numbers: ').split() +nlist = [int(n) for n in nlist] +introsort(nlist) +print('Sorted list: ', end = '') +#printing sorted list +print(nlist) + + +''' +Sample input +Enter the list of numbers: 8 4 3 2 1 + +Sample output +Sorted list: [1, 2, 3, 4, 8] +''' diff --git a/Jhonson_Algoritm/Jhonson.cs b/Jhonson_Algoritm/Jhonson.cs new file mode 100644 index 000000000..b5a41b194 --- /dev/null +++ b/Jhonson_Algoritm/Jhonson.cs @@ -0,0 +1,76 @@ +// C# Program Implementing Jhonson Algorithm. + +using System; + +namespace ConsoleApp1 +{ + class Jhonson_Algorithm + { + public static void Main(String[] args) + { + int vert, edge, i, j, k, c; + int INF = 999999; + int[,] cost = new int[10, 10]; + int[,] adj = new int[10, 10]; + + Console.WriteLine("Enter no of vertices: "); + vert = Convert.ToInt32(Console.ReadLine()); + Console.WriteLine("Enter no of Edges: "); + edge = Convert.ToInt32(Console.ReadLine()); + Console.WriteLine("Enter the EDGE cost: "); + + for (k = 1; k <= edge; k++) + { + //take the input and store it into adj and cost matrix + i = Convert.ToInt32(Console.ReadLine()); + j = Convert.ToInt32(Console.ReadLine()); + c = Convert.ToInt32(Console.ReadLine()); + adj[i, j] = cost[i, j] = c; + } + + for (i = 1; i <= vert; i++) + for (j = 1; j <= vert; j++) + { + if (adj[i, j] == 0 && i != j) + //If its not a edge put infinity + adj[i, j] = INF; + } + for (k = 1; k <= vert; k++) + for (i = 1; i <= vert; i++) + for (j = 1; j <= vert; j++) + //Finding the minimum + //find minimum path from i to j through k + adj[i, j] = (adj[i, k] + adj[k, j]) > adj[i, j] ? adj[i, j] : (adj[i, k] + adj[k, j]) ; + Console.WriteLine("The distance matrix of the graph.\n"); + // Output the resultant matrix + for (i = 1; i <= vert; i++) + { + for (j = 1; j <= vert; j++) + { + if (adj[i, j] != INF) + Console.Write("{0} ", adj[i,j]); + } + Console.WriteLine(" "); + } + } + } +} +/*Enter no of vertices: +3 +Enter no of Edges: +5 +Enter the EDGE cost: +1 2 8 + +2 1 12 + +1 3 22 + +3 1 6 + +2 3 4 +The distance matrix of the graph. + +0 8 12 +10 0 4 +6 14 0*/ diff --git a/Jhonson_Algoritm/Jhonson_Algorithm.kt b/Jhonson_Algoritm/Jhonson_Algorithm.kt new file mode 100644 index 000000000..e3fdc8cb8 --- /dev/null +++ b/Jhonson_Algoritm/Jhonson_Algorithm.kt @@ -0,0 +1,76 @@ +fun main() +{ + var vert = 0 + var edge = 0 + var i = 0 + var j = 0 + var k = 0 + var c = 0 + var inf = 999999; + var cost = Array(10, {IntArray(10)}) + var adj = Array(10, {IntArray(10)}) + + println("Enter no of vertices: ") + vert = readLine() !!.toInt() + println("Enter no of Edges: "); + edge = readLine() !!.toInt() + println("Enter the EDGE cost: "); + + for (k in 1..edge) + { + i = readLine() !!.toInt() + j = readLine() !!.toInt() + c = readLine() !!.toInt() + adj[i][j] = c + cost[i][j] = c + } + + for (i in 1..vert) + for (j in 1..vert) + { + if (adj[i][j] == 0 && i != j) + //If its not a edge put infinity + adj[i][j] = inf + } + + for (k in 1..vert) + for (i in 1..vert) + for (j in 1..vert) + //Finding the minimum + //find minimum path from i to j through k + if ((adj[i][k] + adj[k][j]) > adj[i][j]) + adj[i][j] = adj[i][j] + else + adj[i][j] = (adj[i][k] + adj[k][j]) + + println("The distance matrix of the graph."); + // Output the resultant matrix + for (i in 1..vert) + { + for (j in 1..vert) + { + if (adj[i][j] != inf) + print("${adj[i][j]} "); + } + println(" "); + } +} + +/*Enter no of vertices: +3 +Enter no of Edges: +5 +Enter the EDGE cost: +1 2 8 + +2 1 12 + +1 3 22 + +3 1 6 + +2 3 4 +The distance matrix of the graph. +0 8 12 +10 0 4 +6 14 0*/ diff --git a/Jhonson_Algoritm/Jhonson_Algorithm.php b/Jhonson_Algoritm/Jhonson_Algorithm.php new file mode 100644 index 000000000..59a2d1885 --- /dev/null +++ b/Jhonson_Algoritm/Jhonson_Algorithm.php @@ -0,0 +1,62 @@ + diff --git a/Johnson_Algorithm/Johnson_Algorithm.c b/Johnson_Algorithm/Johnson_Algorithm.c new file mode 100644 index 000000000..e68aeac41 --- /dev/null +++ b/Johnson_Algorithm/Johnson_Algorithm.c @@ -0,0 +1,359 @@ +// Implementation of Johnson's algorithm in C + +#include +#include +#include +#include + +// Structure to represent Edge of graph +struct Edge { + // Edge with a source and destination and weight as distance between source and destination + int source, destination, weight; +}; + +// Structure to represent a connected, weighted and directed graph +struct Graph { + // V is number of vertices + // E is Number of Edges + int V, E; + + // Array of Edge structure + struct Edge* edge; +}; + +struct Graph* createGraph(int V, int E) +{ + // Allocate memory to V vertices of graph + struct Graph* graph = malloc(V * sizeof(int)); + graph -> V = V; + graph -> E = E; + + // Allocate memory to E Edges of graph + graph -> edge = malloc(E * sizeof(int)); + + // Information Message + // printf("The graph is created with %d vertices and %d edges.\n", V, E); + return graph; +} + +struct Graph* addEdge(struct Graph* graph, int src, int des, int wt, int i) +{ + graph -> edge[i].source = src; + graph -> edge[i].destination = des; + graph -> edge[i].weight = wt; + + return graph; +} + +void printGraph(struct Graph* graph) +{ + int E = graph -> E; + + for(int i = 0; i < E; i++) + { + printf("The distance from %d to %d is: %d\n", graph -> edge[i].source, graph -> edge[i].destination, graph -> edge[i].weight); + } + printf("\n"); +} + +int* BellmanFord(struct Graph* graph, int extra, int* dist) +{ + int V = graph -> V; + int E = graph -> E; + + // Initialize distance from extra vertex to all vertices as Infinite(INT_MAX) + for(int i = 0; i < V + 1; i++) + { + dist[i] = INT_MAX; + } + + // Distance from extra vertex to itself is zero + dist[extra] = 0; + + // Shortest path from any vertex can have atmost V-1 edges + for(int i = 1; i <= V; i++) + { + for(int j = 0; j < E + V; j++) + { + int u = graph -> edge[j].source; + int v = graph -> edge[j].destination; + int w = graph -> edge[j].weight; + + // Check if old distance is greater than new distance + if(dist[u] != INT_MAX && dist[v] > dist[u] + w) + { + // Update old distance with new distance + dist[v] = dist[u] + w; + } + } + } + + return dist; +} + +struct Graph* updateEdge(struct Graph* graph, int dist[], int E) +{ + // Update Edge after getting distance from extra vertex to each original vertex + // To make distance between all vertices poitive + for(int i = 0; i < E; i++) + { + int u = graph -> edge[i].source; + int v = graph -> edge[i].destination; + + // Update distance between from vertex u to v as => distance of u from extra vertex - distance of v from extra vertex + original distance from u to v + graph -> edge[i].weight = dist[u] - dist[v] + graph -> edge[i].weight; + } + + return graph; +} + +int minDistance(int dist[], bool visited[], int V) +{ + // Find closest vertex from source vertex that has not been visited + + // Initialize as min as INFINITY(INT_MAX) + int min = INT_MAX, min_index; + + for(int v = 0; v < V; v++) + { + // If vertex is not visited and is smaller than current min + if(!visited[v] && dist[v] <= min) + { + min = dist[v]; + min_index = v; + } + } + return min_index; +} + +int askGraph(struct Graph* graph, int u, int v, int E) +{ + // Return distance from vertex u to vertex v + + for(int i = 0; i < E; i++) + { + if(graph -> edge[i].source == u && graph -> edge[i].destination == v) + { + return graph -> edge[i].weight; + } + } + // return INT_MIN if edge from u to v does not exist + return INT_MIN; +} + +int* Dijsktra(struct Graph* graph, int V, int E, int src, int* dist) +{ + // Calculate shortest path from source vertex to all other vertices + + // checks if vertex i is visited and is finalized + bool visited[V]; + + // Initialize all distances as INT_MAX and visited[] as false + for(int i = 0; i < V; i++) + { + dist[i] = INT_MAX; + visited[i] = false; + } + + // Distance of source vertex from itself is zero + dist[src] = 0; + + // Shortest path from any vertex can have atmost V-1 edges + for(int i = 0; i < V - 1; i++) + { + // Pick the minimum distance vertex from all vertices + int u = minDistance(dist, visited, V); + + // Picked vertex is visited + visited[u] = true; + + // Update distance of adjacent vertices from picked vertex + for(int v = 0; v < V; v++) + { + // Update dist[v] only if it is not in visited, + // Distance from src to v is smaller through src to u to v + + // Distance from u to v + int temp = askGraph(graph, u, v, E); + + if(!visited[v] && dist[u] != INT_MAX && temp != INT_MIN && dist[v] > dist[u] + temp) + { + // Update old distance + dist[v] = dist[u] + temp; + } + } + + } + + return dist; +} + +int main(){ + + // V is number of vertices and E is number of Edges in graph + int V, E; + + scanf("%d %d", &V, &E); + + // Information Message + // printf("%d\n",V); + // printf("%d\n",E); + + // Declaring source, destination and weight for edges + int src, des, wt; + + // One Extra vertex (V+1) is considered for calculating distance with each vertex present in original graph + // Additional V edges (E+V) from extra vertex to all original vertices is considered + + struct Graph* graph = createGraph(V + 1, E + V); + + // Add each edge to graph with source, destination and weight + for(int i = 0; i < E + V; i++) + { + if(i < E) // Original E Edges + { + scanf("%d %d %d", &src, &des, &wt); + // printf("%d %d %d %d\n",src,des,wt, i); + graph = addEdge(graph, src, des, wt, i); + } + else // Extra V edges from one extra vertex to original vertices with 0 weight + { + // printf("%d %d %d %d\n",V,i-E,0, i); + graph = addEdge(graph, V, i - E, 0, i); + } + } + + // printf("\n"); + + // Print graph + // printf("Original Graph:\n\n"); + // printGraph(graph); + + // Store distance of each original vertex from extra vertex(including itself) + int _dist[V + 1]; + + // BellmanFord Algorithm to calculate distance of all original vertices with negative edges from extra vertex + int* dist = BellmanFord(graph, V, _dist); + + // Update new edge weights between vertices + graph = updateEdge(graph, dist, E); + + // Now will consider original E Edges only, rest V will be ignored from extra vertex total of E+V + // Also extra vertex will be ignored + // As was required only to convert negative weight distance between vertices to positive weight distance + + // New graph with all positive weight distance + // printf("Updated Graph:\n\n"); + // printGraph(graph); + + // Matrix to store distance of every vertex with every other vertex + int distance[V][V]; + // Running Dijsktra for every vertex as source + for(int i = 0; i < V; i++) + { + int __dist[V]; + + // Calculating shortest distance from source i to every other vertices using Dijsktra + int* dist_final = Dijsktra(graph, V, E, i, __dist); + + // Update the final matrix distance + for(int j = 0; j < V; j++) + { + distance[i][j] = dist_final[j]; + } + } + + printf("Final Result\n"); + printf("(Value 2147483648 indicates vertex v is not reachable from vertex u)\n\n"); + for(int i = 0; i < V; i++) + { + for(int j = 0; j < V; j++) + { + if(distance[i][j] == INT_MAX) + { + distance[i][j] = INT_MAX; + // To indicate that j vertex is not reachable from i vertex + // No Edge from i to j + } + printf("Distance from %d to %d is :%d\n", i, j, distance[i][j]); + } + printf("\n"); + } +} + +/* + INPUT: + + 7 9 + 0 1 -1 + 0 2 0 + 3 0 12 + 3 2 5 + 2 5 -6 + 5 4 3 + 4 1 4 + 6 5 8 + 1 6 -7 + + OUTPUT: + + Final Result +(Value -2147483648 indicates vertex v is not reachable from vertex u) + +Distance from 0 to 0 is :0 +Distance from 0 to 1 is :0 +Distance from 0 to 2 is :0 +Distance from 0 to 3 is :-2147483648 +Distance from 0 to 4 is :0 +Distance from 0 to 5 is :0 +Distance from 0 to 6 is :0 + +Distance from 1 to 0 is :-2147483648 +Distance from 1 to 1 is :0 +Distance from 1 to 2 is :-2147483648 +Distance from 1 to 3 is :-2147483648 +Distance from 1 to 4 is :6 +Distance from 1 to 5 is :6 +Distance from 1 to 6 is :0 + +Distance from 2 to 0 is :-2147483648 +Distance from 2 to 1 is :2 +Distance from 2 to 2 is :0 +Distance from 2 to 3 is :-2147483648 +Distance from 2 to 4 is :0 +Distance from 2 to 5 is :0 +Distance from 2 to 6 is :2 + +Distance from 3 to 0 is :12 +Distance from 3 to 1 is :7 +Distance from 3 to 2 is :5 +Distance from 3 to 3 is :0 +Distance from 3 to 4 is :5 +Distance from 3 to 5 is :5 +Distance from 3 to 6 is :7 + +Distance from 4 to 0 is :-2147483648 +Distance from 4 to 1 is :2 +Distance from 4 to 2 is :-2147483648 +Distance from 4 to 3 is :-2147483648 +Distance from 4 to 4 is :0 +Distance from 4 to 5 is :8 +Distance from 4 to 6 is :2 + +Distance from 5 to 0 is :-2147483648 +Distance from 5 to 1 is :2 +Distance from 5 to 2 is :-2147483648 +Distance from 5 to 3 is :-2147483648 +Distance from 5 to 4 is :0 +Distance from 5 to 5 is :0 +Distance from 5 to 6 is :2 + +Distance from 6 to 0 is :-2147483648 +Distance from 6 to 1 is :8 +Distance from 6 to 2 is :-2147483648 +Distance from 6 to 3 is :-2147483648 +Distance from 6 to 4 is :6 +Distance from 6 to 5 is :6 +Distance from 6 to 6 is :0 + + */ diff --git a/Johnson_Algorithm/Johnson_Algorithm.dart b/Johnson_Algorithm/Johnson_Algorithm.dart new file mode 100644 index 000000000..e1cbc70f9 --- /dev/null +++ b/Johnson_Algorithm/Johnson_Algorithm.dart @@ -0,0 +1,180 @@ +/* +Johnson’s algorithm for All-pairs shortest paths + +Given a weighted Directed Graph where the weights may be negative, +find the shortest path between every pair of vertices in the Graph using +Johnson’s Algorithm. + */ + +int MAX_INT = 9223372036854775807; + +int minDistance(distance, visited) +{ + var minimum = MAX_INT; + var minVertex = 0; + + var v = distance.length; + + for(var vertex = 0; vertex < v; vertex++) + { + if( (minimum > distance[vertex]) && (visited[vertex] == false) ) + { + minimum = distance[vertex]; + minVertex = vertex; + } + } + return minVertex; +} + +void Dijkstra(graph, modified, src) +{ + var num_vertices = graph.length; + var distance = new List(num_vertices); + + var visited = new List(num_vertices); + + for (var i = 0; i < num_vertices; i++) + { + distance[i] = MAX_INT; + visited[i] = false; + } + + distance[src] = 0; + + for(var count = 0; count < num_vertices; count++) + { + var curVertex = minDistance(distance, visited); + visited[curVertex] = true; + for(var vertex = 0; vertex < num_vertices; vertex++) + { + if ((visited[vertex] == false) && (distance[vertex] > (distance[curVertex] + + modified[curVertex][vertex])) && (graph[curVertex][vertex] != 0)) + { + distance[vertex] = (distance[curVertex] + modified[curVertex][vertex]); + } + } + } + + for(var vertex = 0; vertex < num_vertices; vertex++) + { + print('Vertex ${vertex} : ${distance[vertex]}'); + } +} + +List BellmanFord(edges, graph, num_vertices) +{ + var distance = new List(num_vertices+1); + + for(var i = 0; i <= num_vertices; i++) + { + distance[i]=MAX_INT; + } + + distance[num_vertices] = 0; + + for(var i = 0; i < num_vertices; i++) + { + edges.add([num_vertices, i, 0]); + } + + for(var i = 0; i < num_vertices; i++) + { + for(var j in edges) + { + + if((distance[j[0]] != MAX_INT) && (distance[j[0]] + j[2] < distance[j[1]]) ) + { + distance[j[1]] = distance[j[0]] + j[2]; + } + } + } + + return distance; +} + + +void JohnsonAlgorithm(graph) +{ + var edges = new List(); + + for(var i = 0; i < graph.length ; i++) + { + for(var j = 0; j < graph[i].length; j++) + { + if(graph[i][j] != 0) + { + edges.add([i, j, graph[i][j]]); + } + } + } + + var modifiedwei = BellmanFord(edges, graph, graph.length); + + var modified = [[0,0,0,0], + [0,0,0,0], + [0,0,0,0], + [0,0,0,0]]; + + for(var i = 0; i < graph.length; i++) + { + for(var j = 0; j < graph[i].length; j++) + { + if(graph[i][j] != 0) + { + modified[i][j] = (graph[i][j] + + modifiedwei[i] - modifiedwei[j]); + } + } + } + + print ('Modified Graph: ${modified}'); + + for(var src = 0; src < graph.length; src++) + { + print ('\nShortest Distance with vertex ${src} as the source:\n'); + Dijkstra(graph, modified, src); + } +} + +void main() { + + var graph = [[0, -8, 2, 4], + [0, 0, 2, 6], + [0, 0, 0, 2], + [0, 0, 0, 0]]; + + JohnsonAlgorithm(graph); +} + +/* +Modified Graph: [[0, 0, 8, 8], [0, 0, 0, 2], [0, 0, 0, 0], [0, 0, 0, 0]] + +Shortest Distance with vertex 0 as the source: + +Vertex 0 : 0 +Vertex 1 : 0 +Vertex 2 : 0 +Vertex 3 : 0 + +Shortest Distance with vertex 1 as the source: + +Vertex 0 : 9223372036854775807 +Vertex 1 : 0 +Vertex 2 : 0 +Vertex 3 : 0 + +Shortest Distance with vertex 2 as the source: + +Vertex 0 : 9223372036854775807 +Vertex 1 : 9223372036854775807 +Vertex 2 : 0 +Vertex 3 : 0 + +Shortest Distance with vertex 3 as the source: + +Vertex 0 : 9223372036854775807 +Vertex 1 : 9223372036854775807 +Vertex 2 : -9223372036854775801 +Vertex 3 : 0 + + */ diff --git a/Kadane_Algorithm/Kadane_Algorithm.go b/Kadane_Algorithm/Kadane_Algorithm.go new file mode 100644 index 000000000..d9bf09646 --- /dev/null +++ b/Kadane_Algorithm/Kadane_Algorithm.go @@ -0,0 +1,55 @@ +// Go program to print largest contiguous array sum + +package main + +import "fmt" + +func KAlgo(a []int, n int) int { + var max int + var check_max int + max = 0 + check_max = 0 + + for i := 0; i < n; i++ { + check_max = check_max + a[i] + + // Minimum sum will be 0 + if check_max < 0 { + check_max = 0 + } + if max < check_max { + max = check_max + } + } + return max +} + +//Main Function +func main() { + var n int + fmt.Print("Enter number of Elements ") + fmt.Scan(&n) + ope(n) +} + +func ope(n int) { + fmt.Print("\nEnter Elements ") + a := make([]int, n) + + // Array input + for i := 0; i < n; i++ { + fmt.Scan(&a[i]) + } + + var output int + + // Function Calling for the Algo + output = KAlgo(a, n) + fmt.Println("\nSum of the sub array: ", output) +} + +/* +Enter Number of Elements 6 +Enter Elements 2 -4 -5 -6 8 10 +Sum of the sub array: 18 +*/ diff --git a/Kadane_Algorithm/Kandane_Algorithm.dart b/Kadane_Algorithm/Kandane_Algorithm.dart new file mode 100755 index 000000000..bda39c82e --- /dev/null +++ b/Kadane_Algorithm/Kandane_Algorithm.dart @@ -0,0 +1,85 @@ +/* Dart implementation of Kadane's Algorithm to find the Maximum Subarray Sum +including the extra phase required when all the numbers in array are negative */ + +import 'dart:io'; + +// Function that returns maximum between Two Numbers +int max(a, b){ + if(a > b) + return a; + else + return b; +} + + +// Function implementing Kadane's Algorithm (array contains at least one positive number) +int kadane( input , n ){ + int currentmax = 0, maxsofar = 0; + + for( int i = 0; i < n; i++ ) + { + currentmax = max( 0 , currentmax + input[i] ); + maxsofar = max( maxsofar, currentmax ); + } + return maxsofar; +} + +void main() { + + int maxsubarraysum, size; + + // Input array + stdout.write("Enter the number of elements in the array:"); + String input = stdin.readLineSync(); + size = int.parse(input); + List array = []; + for( int i = 0; i < size; i++ ) + { + String x1 = stdin.readLineSync(); + int x2 = int.parse(x1); + array.add(x2); + } + + // Size of array + int n = array.length; + + // Flag variable to check if all the numbers in array are negative or not + int flag = 0; + + // Smallest_negative variable will store the maximum subarray sum if all the numbers are negative in array + int largestinnegative = array[0]; + + // Scanning each element in array + for( int i = 0; i < n; i++ ) + { + // If any element is positive, kadane's algo can be applied + if(array[i] >= 0) + { + flag = 1; + break; + } + else + { // If all the elements are negative, find the largest in them + if( array[i] > largestinnegative ) + { + largestinnegative = array[i]; + } + } + } + + // Kadane's algo applicable + if(flag == 1) + { + maxsubarraysum = kadane( array , n ); + } + else + { // Kadane 's algo not applicable, + maxsubarraysum = largestinnegative; + } + + // hence the max_subarray_sum will be the largest number in array itself + print("Maximum Subarray Sum is: $maxsubarraysum"); +} + +// sample input = [-2, 1, -6, 4, -1, 2, 1, -5, 4] +// sample output = Maximum Subarray Sum is: 6 diff --git a/Karatsuba_Algorithm/Karatsuba_Algorithm.dart b/Karatsuba_Algorithm/Karatsuba_Algorithm.dart new file mode 100644 index 000000000..6fa0b0b3c --- /dev/null +++ b/Karatsuba_Algorithm/Karatsuba_Algorithm.dart @@ -0,0 +1,57 @@ +import 'dart:io'; +import 'dart:math'; + +// function to find minimun of two integers +int minof(a, b){ + if(a < b) + return a; + else return b; +} + +int karatSuba(num1, num2){ + + // for single digit number multiply directly + if (num1 < 10 || num2 < 10) { + return num1 * num2; + } + + String num1Str = num1.toString(); + String num2Str = num2.toString(); + int n = minof(num1Str.length, num2Str.length); + int half = (n / 2).round(); + + // divide num1 into two halves + int num1_H = int.parse(num1Str.substring(0, num1Str.length - half)); + int num1_L = int.parse(num1Str.substring(num1Str.length - half, num1Str.length)); + + // divide num2 into two halves + int num2_H = int.parse(num2Str.substring(0, num2Str.length - half)); + int num2_L = int.parse(num2Str.substring(num2Str.length - half, num2Str.length)); + + // using the KaratSuba Definition + int s1 = karatSuba(num1_L, num2_L); + int s2 = karatSuba(num1_L + num1_H, num2_L + num2_H); + int s3 = karatSuba(num1_H, num2_H); + int s4 = s2 - s3 - s1; + + // karatsuba formula for finding product + int result = s3 * pow(10, 2 * half) + s4 * pow(10, half) + s1; + + return result; +} + +void main(){ + String a, b; + a = stdin.readLineSync(); + b = stdin.readLineSync(); + print(karatSuba(int.parse(a), int.parse(b))); +} + +/* +Sample input: +12345 +6789 + +Sample Output: +83810205 +*/ diff --git a/Karatsuba_Algorithm/Karatsuba_Algorithm.go b/Karatsuba_Algorithm/Karatsuba_Algorithm.go new file mode 100644 index 000000000..19f3ceba6 --- /dev/null +++ b/Karatsuba_Algorithm/Karatsuba_Algorithm.go @@ -0,0 +1,136 @@ +// Karatsuba Algorithm In GO + +/** + +The Karatsuba Algorithm is a fast multiplication algorithm. +It was discovered by Anatoly Karatsuba in 1960. It reduces +the multiplication of two n-digit numbers to at most single +digit multiplications in general. It is therefore faster +than classical multiplication operation. + +*/ + +package main + +// Importing Necessary Packages +import +( + "fmt" + "math" +) + +// Input Function To Get The Digits +func getDigits(number int64) uint { + + var ans uint + + if number == 0 { + return 1 + } + + if number < 0 { + number = -number + } + + for number > 0 { + ans++ + number = number / 10 + } + + return ans +} + +func getHighAndLowDigits(num int64, digits uint) (int64, int64) { + + divisor := int64(math.Pow(10, float64(digits))) + + if num >= divisor { + return num / divisor, num % divisor + } + else { + return 0, num + } +} + +// Karatsuba Algorithm Function +func karatsuba(x int64, y int64) int64 { + + var max_digits uint + positive := true + + if x == 0 || y == 0 { + return 0 + } + + if (x > 0 && y < 0) || (x < 0 && y > 0) { + positive = false + } + + if x < 0 { + x = -x + } + + if y < 0 { + y = -y + } + + if x < 10 || y < 10 { + return x * y + } + + x_digits := getDigits(x) + y_digits := getDigits(y) + + if x_digits >= y_digits { + max_digits = x_digits / 2 + } + else { + max_digits = y_digits / 2 + } + + x_high, x_low := getHighAndLowDigits(x, max_digits) + y_high, y_low := getHighAndLowDigits(y, max_digits) + + z0 := karatsuba(x_low, y_low) + z1 := karatsuba((x_low + x_high), (y_low + y_high)) + z2 := karatsuba(x_high, y_high) + + if positive { + return (z2 * int64(math.Pow(10, float64(2 * max_digits)))) + + (z1 - z2 - z0) * int64(math.Pow(10, float64(max_digits))) + z0 + } + else { + return -((z2 * int64(math.Pow(10, float64(2 * max_digits)))) + + (z1 - z2 - z0) * int64(math.Pow(10, float64(max_digits))) + z0) + } +} + +// Main Function & Taking User Inputs +func main() { + + fmt.Println("Enter the first number: ") + var first int64 + fmt.Scanln(&first) + + fmt.Println("Enter the second number: ") + var second int64 + fmt.Scanln(&second) + fmt.Println() + + fmt.Print("Result: ") + fmt.Println(karatsuba(first, second)) +} + +/** + +Enter the first number: 121547 +Enter the second number: 1855324 + +Result: 225509066228 + +Enter the first number: -8859460 +Enter the second number: 1154486 + +Result: -10228122537560 + +*/ diff --git a/Karatsuba_Algorithm/Karatsuba_Algorithm.js b/Karatsuba_Algorithm/Karatsuba_Algorithm.js new file mode 100644 index 000000000..be1d99d8b --- /dev/null +++ b/Karatsuba_Algorithm/Karatsuba_Algorithm.js @@ -0,0 +1,42 @@ +/* +The Karatsuba Algorithm implements faster multiplication, +than the traditional approach. +*/ + +const karatSuba = (num1, num2) => { + + // for single digit number multiply directly + if (num1 < 10 || num2 < 10) { + return num1 * num2; + } + + let num1Str = num1.toString(); + let num2Str = num2.toString(); + let n = Math.min(num1Str.length, num2Str.length); + let half = Math.round(n / 2); + + // divide num1 into two halves + let num1_H = parseInt(num1Str.substring(0, num1Str.length - half)); + let num1_L = parseInt(num1Str.substring(num1Str.length - half, num1Str.length)); + + // divide num2 into two halves + let num2_H = parseInt(num2Str.substring(0, num2Str.length - half)); + let num2_L = parseInt(num2Str.substring(num2Str.length - half, num2Str.length)); + + // using the KaratSuba Definition + let s1 = karatSuba(num1_L, num2_L); + let s2 = karatSuba(num1_L + num1_H, num2_L + num2_H); + let s3 = karatSuba(num1_H, num2_H); + let s4 = s2 - s3 - s1; + + // karatsuba formula for finding product + let result = s3 * Math.pow(10, 2 * half) + s4 * Math.pow(10, half) + s1; + + return result; +}; + +// I/O and O/P Examples + +// The result is: 83810205 +console.log(karatSuba(12345, 6789)); +console.log(12345 * 6789); diff --git a/Karatsuba_Algorithm/Karatsuba_Algorithm.php b/Karatsuba_Algorithm/Karatsuba_Algorithm.php new file mode 100644 index 000000000..2a7c98f54 --- /dev/null +++ b/Karatsuba_Algorithm/Karatsuba_Algorithm.php @@ -0,0 +1,50 @@ + diff --git a/Karatsuba_Algorithm/Karatsuba_Algorithm.rb b/Karatsuba_Algorithm/Karatsuba_Algorithm.rb new file mode 100644 index 000000000..691ec4808 --- /dev/null +++ b/Karatsuba_Algorithm/Karatsuba_Algorithm.rb @@ -0,0 +1,68 @@ +# Karatsuba Algorithm In Ruby + += begin + + The Karatsuba Algorithm is a fast multiplication algorithm. + It was discovered by Anatoly Karatsuba in 1960. It reduces + the multiplication of two n-digit numbers to at most single + digit multiplications in general. It is therefore faster + than classical multiplication operation. + += end + +def karatsuba(num1, num2) + + num1, num2 = num1.to_s, num2.to_s + num1_mid_point = (num1.length / 2) + num2_mid_point = (num2.length / 2) + + a = num1[0...num1_mid_point].to_i + b = num1[num1_mid_point..-1].to_i + c = num2[0...num2_mid_point].to_i + d = num2[num2_mid_point..-1].to_i + + # Step 1: Computing the products of a * c + a_c = a * c + + # Step 2: Computing the products of a * c + b_d = b * d + + # Step 3: Computing the products of (a+b) and (c+d) + sum_product = ((a + b) * (c + d)) + + # Step 4: Subtracting first two products from Step 3 + sub_products = sum_product - (a_c + b_d) + + # Step 5: Padding summation + result = (a_c * (10 ** num1.length)) + b_d + (sub_products * (10 ** num1_mid_point)) + +end + +puts "Enter The First Number: " +x = gets.to_i + +puts "Enter The Second Number: " +y = gets.to_i +puts + +answer = karatsuba(x, y) +puts "Result: ", answer +puts + +# Sample Input and Output + += begin + +Enter The First Number: 121547 +Enter The Second Number: 1855324 + +Result: 23133311228 + +-------------------------------------------------- + +Enter The First Number: -8859460 +Enter The Second Number: 1154486 + +Result: -10206279662440 + += end diff --git a/Karatsuba_Algo/Karatsuba_multiplication_algo.cpp b/Karatsuba_Algorithm/Karatsuba_multiplication_algo.cpp similarity index 100% rename from Karatsuba_Algo/Karatsuba_multiplication_algo.cpp rename to Karatsuba_Algorithm/Karatsuba_multiplication_algo.cpp diff --git a/Karatsuba_Algorithm/Readme.md b/Karatsuba_Algorithm/Readme.md new file mode 100644 index 000000000..7df095146 --- /dev/null +++ b/Karatsuba_Algorithm/Readme.md @@ -0,0 +1,54 @@ +# Karatsuba Multiplication +Karatsuba multiplication is an effective and efficient way of multiplication, which comes handy when multiplying really large numbers. It is different from the steps followed in conventional multiplication technique due to the fact that, it recursively performs the multiplication, thereby, making it possible to accomodate really large numbers. + +#### Consider the following example: +#### 5678 x 1234 = 7006652 + +While carrying out traditional multiplication(I mean the method we're usually taught at schools), we first have to multiply 5678 by 4, then by 3...upto 1 and then add all the intermediary products. It turns out that, while implementing this logic in code, we have to make 2n operations(n being the number of digits in the larger number) - (n operations to calculate the intermediary products + n operations to add those products,a long with keeping track of the carry overs). This is a lot of computation. + +#### Now let's have a look at how karatsuba multiplication, decreases the computations +#### Following are the steps for karatsuba multiplication: +- Consider the above 2 numbers, let x = 5678 and y = 1234 +- Break each number into 2 halves and store them in variables +- In this case, let a = 56, b = 78, c = 12, d = 34 +- Now we can express x and y as, x = 10 ^ (n/2) * a + b and y = 10 ^ (n/2) * c + d, where a,b,c,d are n/2 digit numbers. +- Therefore, x * y = 10 ^ n * a * c + 10 ^ (n/2) * (a * d + b * c) + b * d +- Now, on the first look it may seem that there are 4 recursive calls, to compute ac, ad, bc and bd - but here is the trick: +- It's also called as Gauss's trick - which requires only 3 recursive calls. +- If we carefully observe, we have already computed ac and bd in the first 2 steps, so if we subtract this result from the result of (a+b) * (c+d), we reduce 1 recursive call. +- It may seems strange, but when the computations to be performed are of very high level(multiplying really large digit numbers in this case), reducing even a single recursive call significantly affects performance. +- Checkout the code in python, to understand the recursive work flow better as well as the base case for the recursive function. + +### Pseudo code +``` +karatsuba(x, y): + + m = ceil(n/2) + + a = floor(x / 10**m) + b = x % (10**m) + + c = floor(y / 10**m) + d = y % (10**m) + + #recursive steps + ac = karatsuba(a,c) + bd = karatsuba(b,d) + ad_plus_bc = karatsuba(a + b, c + d) - ac - bd + + return int(ac*(10**(m*2)) + ad_plus_bc*(10**m) + bd) +``` + +### Complexity + +To analyze the complexity of the Karatsuba algorithm, consider the number of multiplications the algorithm performs as a function of n, M(n). + +The algorithm multiplies together two nn-bit numbers. If n=2^k for some k then the algorithm recurses three times on n/2-bit number. The recurrence for this is: + +M(n) = 3M(n/2) + +This takes care of the multiplications required for Karatsuba--now to consider the additions and subtractions. There are O(n)O(n) additions and subtractions required for the algorithm. Therefore, the overall recurrence for the Karatsuba algorithm is: + +T(n) = 3T(n/2) + O(n) + +Using the master theorem on the above recurrence yields that the running time of the Karatsuba algorithm is: $\Theta$(nlog23) \ No newline at end of file diff --git a/Karatsuba_Algorithm/karatsuba.py b/Karatsuba_Algorithm/karatsuba.py new file mode 100755 index 000000000..1fa796bcb --- /dev/null +++ b/Karatsuba_Algorithm/karatsuba.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +from math import ceil, floor + +def karatsuba(x,y): + # base case + if x < 10 and y < 10: # in other words, if x and y are single digits + return x*y + + n = max(len(str(x)), len(str(y))) + m = ceil(n/2) # Cast n into a float because n might lie outside the representable range of integers. + + a = floor(x / 10**m) + b = x % (10**m) + + c = floor(y / 10**m) + d = y % (10**m) + + # recursive steps + ac = karatsuba(a,c) + bd = karatsuba(b,d) + ad_plus_bc = karatsuba(a + b, c + d) - ac - bd + + return int(ac*(10**(m*2)) + ad_plus_bc*(10**m) + bd) + +# INPUT 123456789, 987654321 +a,b = map(int, input().split(' ')) + +# OUTPUT 121932631112635269 +print(karatsuba(a, b)) diff --git a/Knapsack/01_knapsack.cpp b/Knapsack/01_knapsack.cpp new file mode 100644 index 000000000..7ef322ca4 --- /dev/null +++ b/Knapsack/01_knapsack.cpp @@ -0,0 +1,56 @@ +#include +#include +using namespace std; + +// Function to return maximum profit +int knapsack(vector profit, vector weight, int capacity, int n) { + + if(capacity == 0 || n == 0 ) { + return 0; + } + if(weight[n - 1] > capacity) { + return knapsack(profit, weight, capacity, n - 1); + } + else { + return max(profit[n - 1] + knapsack(profit, weight, capacity - weight[n - 1], n - 1), knapsack(profit, weight, capacity, n - 1)); + } +} + +int max(int a, int b) { + if(a > b) { + return a; + } + else { + return b; + } +} + +int main() { + int capacity, n; + cout << "Enter the number of elements to be stored: "; + cin >> n; + vector profit(n), weight(n); + cout << "Enter the profit values of all elements: "; + for(int i = 0; i < n; i++) { + cin >> profit[i]; + } + cout << "Enter the weights of all elements: "; + for(int i = 0; i < n; i++) { + cin >> weight[i]; + } + cout << "Enter the capacity: "; + cin >> capacity; + cout << "The maximum profit will be: " << knapsack(profit, weight, capacity, n); + return 0; +} + +/* +SAMPLE INPUT: +Enter the number of elements to be stored: 6 +Enter the profit values of all elements: 10 20 30 44 56 72 +Enter the weights of all elements: 5 10 15 25 20 15 +Enter the capacity: 70 + +SAMPLE OUTPUT: +The maximum profit will be: 192 +*/ diff --git a/Knuth_Morris_Pratt_Algorithm/KMP.c b/Knuth_Morris_Pratt_Algorithm/KMP.c new file mode 100644 index 000000000..b3e804867 --- /dev/null +++ b/Knuth_Morris_Pratt_Algorithm/KMP.c @@ -0,0 +1,70 @@ +// Program to implement KnuthMorrisPratt Algorithm in C + +#include +#include +#include + +void KnuthMorrisPratt(const char* X, const char* Y, int m, int n) +{ + if (*X == '\0' || m < n) + printf("Pattern is not found"); + + if (*X == '\0' || m < n) + printf("Pattern is not found"); + + if (*Y == '\0' || n == 0) + printf("Pattern with shift 0"); + + int alternate[n + 1]; + + for (int i = 0; i < n + 1; i++) + alternate[i] = 0; + + for (int i = 1; i < n; i++) + { + int j = alternate[i + 1]; + while (j > 0 && Y[j] != Y[i]) + j = alternate[j]; + + if (j > 0 || Y[j] == Y[i]) + alternate[i + 1] = j + 1; + } + + for (int i = 0, j = 0; i < m; i++) + { + if (*(X + i) == *(Y + j)) + { + if (++j == n) + printf("Pattern occurs with shift %d\n", i - j + 1); + } + else if (j > 0) { + j = alternate[j]; + i--; + } + } +} + +// Program to implement KnuthMorrisPratt Algorithm in C +int main(void) +{ + char word[20]; + gets(word); + + char pattern[20]; + gets(pattern); + + int n = strlen(word); + int m = strlen(pattern); + + KnuthMorrisPratt(word, pattern, n, m); + + return 0; +} + +///Sample IP: +// BACPARKWRPARM +// PAR + +///Sample OP: +// Pattern occurs with shift 3 +// Pattern occurs with shift 9 diff --git a/Knuth_Morris_Pratt_Algorithm/KMP.dart b/Knuth_Morris_Pratt_Algorithm/KMP.dart new file mode 100644 index 000000000..318f7b788 --- /dev/null +++ b/Knuth_Morris_Pratt_Algorithm/KMP.dart @@ -0,0 +1,73 @@ +/*The KMP matching algorithm uses degenerating property (pattern having same sub-patterns appearing more than once in the pattern) +of the pattern and improves the worst case complexity to O(n). The basic idea behind KMP’s algorithm is: whenever we detect a mismatch +(after some matches), we already know some of the characters in the text of the next window. This information is used to avoid +matching the characters that will anyway match.*/ +import 'dart:io'; + +List prefix_function (String pattern) +{ + var m = pattern.length; + var pi = []; + pi.add(-1); + var k = -1; + for (var j = 1; j < m; j++) + { + while (k > -1 && pattern[k + 1] != pattern[j]) + { + k = pi[k]; + } + if (pattern[k + 1] == pattern[j]) + { + k = k + 1; + } + pi.insert(j,k); + } + return pi; +} + +void KMP_matcher (String text, String pattern) +{ + var n = text.length; + var m = pattern.length; + var pi = []; + pi = prefix_function(pattern); + + var j = -1; //number of chars matched + for (var i = 0; i < n; i++) + { + while (j >= 0 && pattern[j+1] != text[i]) + { + j = pi[j]; //next char doesnot match + } + if (pattern[j+1] == text[i]) + { + j = j + 1; + } + if (j == m - 1) + { + var result = i - m + 2; + print ("Pattern found at position: $result"); + j = pi[j]; + } + } +} + +main() +{ + print ("Enter Text:"); + String text = stdin.readLineSync(); + print ("Enter Pattern:"); + String pattern = stdin.readLineSync(); + KMP_matcher (text, pattern); + return 0; +} + +/* +Enter Text: +gfmghdmgmgcc +Enter Pattern: +mg +Pattern found at position: 3 +Pattern found at position: 7 +Pattern found at position: 9 */ + diff --git a/Knuth_Morris_Pratt_Algorithm/KMP.js b/Knuth_Morris_Pratt_Algorithm/KMP.js new file mode 100644 index 000000000..884336313 --- /dev/null +++ b/Knuth_Morris_Pratt_Algorithm/KMP.js @@ -0,0 +1,95 @@ +/* Function to create Longest Proper Prefix for given pattern that we want to search in the text*/ +function lpsValues( lps, pattern, len_pattern) +{ + //length of longest prefix that is also suffix, will be zero for 1st charater as no prefix ans no suffix + lps[0] = 0; + //length of previous longest prefix that is also suffix + var len_prev = 0; + //iterator to calculate values lps[1].....lps[len_pattern] + var i = 1; + while (i < len_pattern ) + { + if (pattern.charAt(i) === pattern.charAt( len_prev)) + { + len_prev = len_prev+1;; + lps[i] = len_prev; + i++; + } + else // (pat[i] != pat[len]) + { + + if (len_prev != 0) + { + len_prev = lps[len_prev - 1]; + } + + else // if (len == 0) as no prefix found + { + lps[i] = 0; + i++; + } + } + } +} + + +function KmpPatternSearch(pattern, text) +{ + len_pattern = pattern.length; + len_text = text.length; + + //We find Longest Proper Prefix to decide which chater will be matched next + var lps = new Array(len_pattern); + + lpsValues(lps, pattern, len_pattern); + + //iterator + var i = j = 0; + while (i < len_text) + { + if (pattern.charAt(j) === text.charAt(i)) + { + //Pattern ans text matched + i = i+1; + j = j+1; + } + if (j === len_pattern) + { + return i-j; + j = lps[j-1]; + } + else if (j != len_pattern && pattern.charAt(j) != text.charAt(i)) + { + + if (j != 0) + { + j = lps[j-1]; + } + else + { + i = i+1; + } + } + } +} +//Used synchronous readline package to take console input +var readlineSync = require('readline-sync'); +//User input for text to be searched +var a = readlineSync.question('Enter text to be searched: '); +//User input for pattern to be searched in text +var b = readlineSync.question('Enter the pattern to be searched: '); +var index=KmpPatternSearch(b,a); +if (index == undefined) +{ + console.log("Pattern not found."); +} +else +{ + console.log("Pattern observed at index:", index); +} +//Input 1: text :"abcabaabcabac" pattern:"abaa" +//Output will be 3 +//Input 2: text:"aabbcdefgh" pattern:"fgh" +//Output will be 7 +//Input 3: text:"aaaaaa" pattern:"bb" +//Output: Pattern not found diff --git a/Knuth_Morris_Pratt_Algorithm/KMP.kt b/Knuth_Morris_Pratt_Algorithm/KMP.kt new file mode 100644 index 000000000..8882c1623 --- /dev/null +++ b/Knuth_Morris_Pratt_Algorithm/KMP.kt @@ -0,0 +1,83 @@ +/* +Knuth Morris Pratt String Searching Algorithm +Given a text txt[0..n-1] and a pattern pat[0..m-1], the algo will find all occurrences of pat[] in txt[] +*/ + +import java.util.* + +internal class KMP { + fun kmpSearch(pat: String, txt: String) { + val m = pat.length + val n = txt.length + // longest_prefix_suffix array + val lps = IntArray(m) + + // index for pat[] + var j = 0 + + //calculate lps[] array + computeLPSArray(pat, m, lps) + + //index for txt[] + var i = 0 + while (i < n) { + if (pat[j] == txt[i]) { + j++ + i++ + } + if (j == m) { + println("Found pattern at index" + (i - j)) + j = lps[j - 1] + } else if (i < n && pat[j] != txt[i]) { + if (j != 0) j = lps[j - 1] else i += 1 + } + } + } + + // length of the previous longest prefix suffix + private fun computeLPSArray(pat: String, M: Int, lps: IntArray) { + var len = 0 + var i = 1 + + //lps[0] is always 0 + lps[0] = 0 + + //calculate lps[i] for i=1 to M-1 + while (i < M) + { + if (pat[i] == pat[len]) { + len++ + lps[i] = len + i++ + } + else { + if (len != 0) len = lps[len - 1] else { + lps[i] = len + i++ + } + } + } + } + + companion object { + //Driver program to test above function + @JvmStatic + fun main(args: Array) { + val sc = Scanner(System.`in`) + val txt = sc.nextLine() + val pat = sc.nextLine() + KMP().kmpSearch(pat, txt) + } + } +} + +/* +Sample Input +namanchamanbomanamansanam +aman + +Sample Output: +Patterns occur at shift = 1 +Patterns occur at shift = 7 +Patterns occur at shift = 16 + */ diff --git a/Knuth_Morris_Pratt_Algorithm/KMP.php b/Knuth_Morris_Pratt_Algorithm/KMP.php new file mode 100644 index 000000000..568383d77 --- /dev/null +++ b/Knuth_Morris_Pratt_Algorithm/KMP.php @@ -0,0 +1,86 @@ + \ No newline at end of file diff --git a/Knuth_Morris_Pratt_Algorithm/KMP.rb b/Knuth_Morris_Pratt_Algorithm/KMP.rb new file mode 100644 index 000000000..677e37f10 --- /dev/null +++ b/Knuth_Morris_Pratt_Algorithm/KMP.rb @@ -0,0 +1,76 @@ +# Given a text and a pattern, we need to find all occurrences of pattern in text + +def kmp_search(pattern, text) + pattern_size = pattern.length + text_size = text.length + + lps = Array.new(pattern_size) # longest_prefix_suffix array + lps = calculate_lps(pattern, lps) # compute lps[] + i = 0 # index for pattern[] + j = 0 # index for text[] + + while i < text_size + if pattern[j] == text[i] + i += 1 + j += 1 + end + + if j == pattern_size + puts "Pattern found at #{i - j + 1}" + j = lps[j - 1] + elsif i < text_size && pattern[j] != text[i] + if j != 0 + j = lps[j - 1] + else + i += 1 + end + end + end +end + +# function to preprocess lps[] to hold the longest prefix suffix values for pattern +def calculate_lps(pattern, lps) + len = 0 + lps[0] = 0 + + i = 1 + while i < pattern.length + if pattern[i] == pattern[len] + len += 1 + lps[i] = len + i += 1 + else + if len != 0 + len = lps[len - 1] + else + lps[i] = 0 + i += 1 + end + end + end + + return lps +end + +# Driver Code +puts "Enter the text:" +text = gets.chomp + +puts "Enter the pattern:" +pattern = gets.chomp + +kmp_search(pattern, text) + +=begin +Enter the text: +namanchamanbomanamansanam + +Enter the pattern: +aman + +Output + +Pattern found at 2 +Pattern found at 8 +Pattern found at 17 +=end diff --git a/Knuth_Morris_Pratt_Algorithm/Knuth-Morris_Pratt_Algorithm_README.md b/Knuth_Morris_Pratt_Algorithm/Knuth-Morris_Pratt_Algorithm_README.md new file mode 100644 index 000000000..985a7fe74 --- /dev/null +++ b/Knuth_Morris_Pratt_Algorithm/Knuth-Morris_Pratt_Algorithm_README.md @@ -0,0 +1,134 @@ +# Knuth-Morris Pratt Algorithm + +1. It was invented by Donald Knuth and Vaughan Pratt. +2. It was the first linear time complexity algorithm for string matching which is used to find a pattern in a text. +3. This algorithm compares character by character from left to right. + +## Components of Knuth-Morris Pratt algorithm + +Prefix Table : In this algorithm whenever a mismatch occurs,it uses a preprocessed table known as Prefix Table to skip characters comparison while matching. + +LPS Table : It stands for Longest proper Prefix which is also suffix. Sometimes prefix table is also known as LPS Table. + +## Steps for Creating LPS Table + +1. Define a one dimensional array with the size equal to the length of the Pattern. (LPS[size]) +2. Define variables i & j. Set i = 0, j = 1 and LPS[0] = 0. +3. Compare the characters at Pattern[i] and Pattern[j]. +4. If both are matched then set LPS[j] = i + 1 and increment both i & j values by one. Go to Step 3. +5. If both are not matched then check the value of variable 'i'. If it is '0' then set LPS[j] = 0 and increment 'j' value by one, if it is not '0' then set i = LPS[i - 1]. Step 3. +6. Repeat above steps until all the values of LPS[] are filled. + +## ALGORITHM + +**Input** the main text, and the pattern, which will be searched. + +``` +Begin + n := size of text + m := size of pattern + + call findPrefix(pattern, m, prefArray) + while i < n, do + if text[i] = pattern[j], then + increase i and j by 1 + + if j = m, then + print the location (i-j) as there is the pattern + j := prefArray[j-1] + else if i < n AND pattern[j] ≠ text[i] then + if j ≠ 0 then + j := prefArray[j - 1] + else + increase i by 1 + done + End +``` + +**Output**: The location where patterns are found. + +## How The Knuth-Morris Pratt Algorithm Work? + +Let us see an example + +Consider the following Text and Pattern + +Text : ABC ABCDAB ABCDABCDABDE + +Pattern : ABCDABD + +LPS[] table for the above pattern is as follows + +LPS[] is {0,1,2,3,4,5,6} + +**Step 1:** Start comparing first character of pattern with first character of Text from left to right + +Text: ABC ABCDAB ABCDABCDABDE + +Pattern: ABCDABD + +0123456 + +Here mismatch occurred at Pattern[3],so we need to consider LPS[2] value. Since LPS[2] value is '0' we must compare first character in pattern with next character in Text. + +**Step 2:** Start comparing first character of pattern with next character of Text. + +Text : ABC ABCDAB ABCDABCDABDE + +Pattern : ABCDABD + +0123456 + +Here mismatch occurred at Pattern[6], so we need to consider LPS[5] value. Since LPS[5] value is '2' we compare Pattern[2] character with mismatched character in Text. + +**Step 3:** Since LPS value is '2' no need to compare the Pattern[0] and Pattern[1] values + +Text : ABC ABCDAB ABCDABCDABDE + +Pattern : ABCDABD + +0123456 + +Here mismatch occurred at pattern[2],so we need to consider LPS[1] value. Since LPS[1] value is '0' we must compare first character in Pattern with next character in Text. + +**Step 4** Compare Pattern[0] with next character in Text + +Text : ABC ABCDAB ABCDABCDABDE + +Pattern : ABCDABD + +0123456 + +Here mismatch occurred at Pattern[6], so we need to consider LPS[5] value. Since LPS[5] value is '2' we compare Pattern[2] character with mismatched character in Text. + +**Step 5:** Compare Pattern[2] with mismatched character in Text. + +Text : ABC ABCDAB ABCDABCDABDE + +Pattern : ABCDABD + +0123456 + +Here all the characters of Patterns matched with a substring in Text which is starting from index value 15. + +So, we conclude that given Pattern found at index 15 in Text. + +**TIME COMPLEXITY** + +The time complexity of Knuth-Morris Pratt Algorithm is O(n). + +**SPACE COMPLEXITY** + +It also has a space complexity of O (m) because there’s some pre-processing involved. + +**SEE ALSO** + +1. https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Knuth_Morris_Pratt_Algorithm/KMP.cpp +2. https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Knuth_Morris_Pratt_Algorithm/KMP.java +3. https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Knuth_Morris_Pratt_Algorithm/KMP.py +4. https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Knuth_Morris_Pratt_Algorithm/KMP.cs + +**REFERENCES** + +1. https://www.geeksforgeeks.org/kmp-algorithm-for-pattern-searching/ +2. [https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm](https://en.wikipedia.org/wiki/Knuth–Morris–Pratt_algorithm) \ No newline at end of file diff --git a/Kosaraju_Algorithm/Kosaraju_Algorithm.cs b/Kosaraju_Algorithm/Kosaraju_Algorithm.cs new file mode 100644 index 000000000..1c2046d8f --- /dev/null +++ b/Kosaraju_Algorithm/Kosaraju_Algorithm.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; + +namespace Declaring_Method +{ + public static class Kosaraju_Algorithm + { + public static void Main(string[] args) + { + List[] g = new List[3]; + for (int i = 0; i < g.Length; i++) + g[i] = new ArrayList<>(); + + //Initializing the List. + g[2].Add(0); + g[2].Add(1); + g[0].Add(1); + g[1].Add(0); + + List> components = scc(g); + + //Final Output + foreach (int i in components) + { + Console.WriteLine(i); + } + } + + public static List> scc(List[] graph) + { + int n = graph.Length; // Storing length of the graph + bool[] used = new bool[n]; + List order = new ArrayList<>(); + for (int i = 0; i < n; i++) + if (!used[i]) + dfs(graph, used, order, i); + + List[] reverseGraph = new List[n]; + for (int i = 0; i < n; i++) + reverseGraph[i] = new ArrayList<>(); + for (int i = 0; i < n; i++) + foreach (int j in graph[i]) + reverseGraph[j].Add(i); + + List> components = new ArrayList<>(); + fill(used, false); + order.Reverse(); // Reversing the contents + + foreach (int u in order) + if (!used[u]) + { + List component = new ArrayList<>(); + dfs(reverseGraph, used, component, u); + components.Add(component); + } + + return components; + } + + //Depth First Search + static void dfs(List[] graph, bool[] used, List res, int u) + { + used[u] = true; + foreach (int v in graph[u]) + if (!used[v]) + dfs(graph, used, res, v); + res.Add(u); + } + + //To fill the bool array + public static void fill(this T[] originalArray, T with) + { + for (int i = 0; i < originalArray.Length; i++) + { + originalArray[i] = with; + } + } + + } +} +/*OUTPUT: +2 +1 +0*/ diff --git a/Kosaraju_Algorithm/Kosaraju_Algorithm.kt b/Kosaraju_Algorithm/Kosaraju_Algorithm.kt new file mode 100644 index 000000000..0cbe967b0 --- /dev/null +++ b/Kosaraju_Algorithm/Kosaraju_Algorithm.kt @@ -0,0 +1,70 @@ +import java.util.* + +object SCCKosaraju +{ + fun scc(graph: Array>): List> + { + // Storing length of the graph + val n: Int = graph.size + //Boolean Array Initialisation + val used = BooleanArray(n) + val order: MutableList = ArrayList() + for (i in 0 until n) + if (!used[i]) + dfs(graph, used, order, i) + + val reverseGraph: Array> = arrayOf>(n) + for (i in 0 until n) + reverseGraph[i] = ArrayList() + for (i in 0 until n) + for (j in graph[i]) + reverseGraph[j].add(i) + + val components: MutableList> = ArrayList() + Arrays.fill(used, false) + Collections.reverse(order) // Reversing the contents + + for (u in order) if (!used[u]) + { + val component: MutableList = ArrayList() + dfs(reverseGraph, used, component, u) + components.add(component) + } + return components + } + + //Depth First Search + fun dfs(graph: Array>, used: BooleanArray, res: MutableList, u: Int) + { + used[u] = true + for (v in graph[u]) + if (!used[v]) + dfs(graph, used, res, v) + res.add(u) + } + + // Usage example + @JvmStatic + fun main(args: Array) + { + val g: Array> = arrayOf>(3) + for (i in g.indices) + g[i] = ArrayList() + + //Initializing the List. + g[2].add(0) + g[2].add(1) + g[0].add(1) + g[1].add(0) + val components = scc(g) + println(components) + } +} +/*Input:- +0 +1 +1 +0 +Output:- +[[2],[1, 0]]*/ + diff --git a/Kosaraju_Algorithm/Kosaraju_Algorithm.py b/Kosaraju_Algorithm/Kosaraju_Algorithm.py new file mode 100644 index 000000000..a7c0bca7b --- /dev/null +++ b/Kosaraju_Algorithm/Kosaraju_Algorithm.py @@ -0,0 +1,83 @@ +# Python implementation of Kosaraju's Algorithm +# Kosaraju's Algorithm is used to print all Strongly Connected Components (SCCs) in a directed graph +# A component is said to be strongly connected if there is a path between all pairs of vertices in it. + +# Kosaraju’s Algorithm involves two passes of Depth First Search in order to find the number of SCCs + +# defaultdict is a useful technique for building graphs. +from collections import defaultdict + +# Function for first DFS pass and to fill vertices in finishStack +def firstDFS(g, v, visited, finishStack): + visited[v] = True + for i in g[v]: + if visited[i] == False: + firstDFS(g, i, visited, finishStack) + finishStack = finishStack.append(v) + +# Function for second DFS pass +def secondDFS(gt, v, visited): + visited[v] = True + print(v, end = " ") + for i in gt[v]: + if visited[i] == False: + secondDFS(gt, i, visited) + +# Create Graph +v = int(input("Enter number of vertices in the graph: ")) + +# g represents original graph +g = defaultdict(list) + +# gt represents transpose of original graph +gt = defaultdict(list) + +e = int(input("Enter number of edges in the graph: ")) +for i in range(1 , e + 1): + print("Edge no. %d - "%(i), end = "") + num = list(map(int, input(' ').split())) + g[num[0]].append(num[1]) + gt[num[1]].append(num[0]) + +# Stack to be filled according to finishing time +finishStack = [] + +# Maintaining visited array of size v +# All vertices are marked False for first DFS pass +visited = [False] * v + +# First DFS on g +for i in range(v): + if visited[i] == False: + firstDFS(g, i, visited, finishStack) + +print ("Strongly connected components(SCCs) in the graph are: ") + +# Maintaining visited array of size v +# All vertices are marked False for second DFS pass +visited = [False] * v + +# Second DFS on gt +while finishStack: + i = finishStack.pop() + if visited[i] == False: + secondDFS(gt, i, visited) + print() + +''' +Sample Input: +Enter number of vertices in the graph: 6 +Enter number of edges in the graph: 7 +Edge no. 1 - 0 1 +Edge no. 2 - 1 2 +Edge no. 3 - 2 0 +Edge no. 4 - 2 3 +Edge no. 5 - 3 4 +Edge no. 6 - 4 5 +Edge no. 7 - 5 3 + +Sample Output: +Strongly connected components(SCCs) in the graph are: +0 2 1 +3 5 4 +''' diff --git a/Kosaraju_Algorithm/Kosaraju_algorithm.cpp b/Kosaraju_Algorithm/Kosaraju_algorithm.cpp new file mode 100644 index 000000000..8b969d461 --- /dev/null +++ b/Kosaraju_Algorithm/Kosaraju_algorithm.cpp @@ -0,0 +1,105 @@ +//Strongly connected components(KOSARAJU ALGORITHM) +#include +#include +#include +#include +using namespace std; + +//dfs to store vertices in a stack as per their finish time +void dfs(vector* edges, int start, unordered_set &visited, stack &finishStack) { + visited.insert(start); + for (int i = 0; i < edges[start].size(); i++) { + int adjacent = edges[start][i]; + if (visited.count(adjacent) == 0) { + dfs(edges, adjacent, visited, finishStack); + } + } + finishStack.push(start); +} + +//dfs of a transpose graph +void dfs2(vector* edges, int start, unordered_set* component, unordered_set & visited) { + visited.insert(start); + component->insert(start); + for (int i = 0; i < edges[start].size(); i++) { + int adjacent = edges[start][i]; + if (visited.count(adjacent) == 0) { + dfs2(edges, adjacent, component, visited); + } + } +} + +unordered_set*>* getSCC(vector* edges, vector* edgesT, int n) { + unordered_set visited; + stack finishedVertices; + for (int i = 0; i < n; i++) { + if (visited.count(i) == 0) { + dfs(edges, i, visited, finishedVertices); + } + } + unordered_set*>* output = new unordered_set*>(); + visited.clear(); + while (finishedVertices.size() != 0) { + int element = finishedVertices.top(); + finishedVertices.pop(); + if (visited.count(element) != 0) { + continue; + } + unordered_set* component = new unordered_set(); + dfs2(edgesT, element, component, visited); + output->insert(component); + } + return output; +} + +int main() { + int n; //no.of vertices + cout<<"Enter the no. of vertices : "<> n; + vector* edges = new vector[n]; //using a adjacency list to implement + vector* edgesT = new vector[n]; //transpose of a graph + int m; // no.of edges + cout<<"Enter the no. of edges : "<> m; + + for (int i = 0; i < m; i++) { + int j, k; + cin >> j >> k; + edges[j - 1].push_back(k - 1); + edgesT[k - 1].push_back(j - 1); + } + + unordered_set*>* components = getSCC(edges, edgesT, n); + unordered_set*>::iterator it = components->begin(); + + while (it != components->end()) { + unordered_set* component = *it; + unordered_set::iterator it2 = component->begin(); + while (it2 != component->end()) { + cout <<*it2 + 1<< " "; + it2++; + } + cout << endl; + delete component; + it++; + } + + delete components; + delete [] edges; + delete [] edgesT; +} + +/*INPUTS +Enter the no. of vertices : 6 +Enter the no. of edges :7 +1 2 +2 3 +3 4 +4 1 +3 5 +5 6 +6 5 + +OUTPUT +6 5 +2 3 4 1 */ diff --git a/Kosaraju_Algorithm/Kosaraju_algorithm.dart b/Kosaraju_Algorithm/Kosaraju_algorithm.dart new file mode 100644 index 000000000..f1c4d73d2 --- /dev/null +++ b/Kosaraju_Algorithm/Kosaraju_algorithm.dart @@ -0,0 +1,211 @@ +/** + * Kosaraju's Algorithm + * ---------------------------------------- + * + * This algorithm is used to find the number of strongly connected components + * in a directed graph. It uses DFS. It performs DFS twice to achieve the goal based on the fact that + * finishing time of starting vertex will be greater than the finishing times of vertices in other SCCs. + * + */ +// Importing required libraries +import 'dart:io'; +import 'dart:collection'; + +// Class definition for a graph +class Graph{ + + // Total number of vertices in a graph + int numVertices; + // Adjacency list of the graph + var adj; + + // Constructor + Graph(int v){ + this.numVertices = v; + this.adj = List(this.numVertices); + for(int i = 0; i < this.numVertices; i ++){ + adj[i] = List(); + } + } + + // Method to add an edge to a graph + void add_edge(int source, int destination){ + adj[source].add(destination); + } + + // Utility method to fill the stack through DFS. + void fillOrder(int v, List visited, Queue stack){ + visited[v] = true; + var temp = this.adj[v]; + int m = temp.length; + int i = 0; + while(i < m){ + if(!visited[this.adj[v][i]]){ + fillOrder(this.adj[v][i], visited, stack); + } + i ++; + } + stack.add(v); + } + + // Utility method to find the transpose of the graph + Graph getTranspose(){ + + Graph transpose = Graph(this.numVertices); + + for(int i = 0; i < transpose.numVertices; i ++){ + int destination = i; + for(int j = 0; j < this.adj[i].length; j ++){ + transpose.adj[this.adj[i][j]].add(destination); + } + } + + return transpose; + } + + // Utility method that performs DFS. + void DFSUtil(int v, List visited, List result){ + visited[v] = true; + result.add(v); + int m = this.adj[v].length; + + for(int i = 0; i < m; i ++){ + if(!visited[this.adj[v][i]]){ + DFSUtil(this.adj[v][i], visited, result); + } + } + } + + // Utility method to print strongly connected components. + void printStronglyConnectedComponents(){ + // Using a LIFO queue as stack + Queue stack = Queue(); + var visited = List(this.numVertices); + + // Initializing the visited list. + for(int i = 0; i < this.numVertices; i ++){ + visited[i] = false; + } + + // Filling the stack through DFS + for(int i = 0; i < this.numVertices; i ++){ + if(visited[i] == false){ + fillOrder(i, visited, stack); + } + } + + // Finding transpose of the graph + Graph g = getTranspose(); + for(int i = 0; i < this.numVertices; i ++){ + visited[i] = false; + } + + + int count = 0; + + // Finding strongly connected components using DFS on all vertices in stack. + while(!stack.isEmpty){ + int v = stack.removeLast(); + + if(visited[v] == false){ + var result = List(); + g.DFSUtil(v, visited, result); + print("Strongly Connected Component ${count+1}:"); + print(result.join(" ")); + count += 1; + } + } + } +} + +// Driver method of the program +void main(){ + + // Input of number of vertices + print("Enter number of vertices in the graph:"); + var input = stdin.readLineSync(); + int n = int.parse(input); + Graph g = Graph(n); + + // Input of number of edges + print("Enter number of edges:"); + input = stdin.readLineSync(); + int m = int.parse(input); + + // Input of edges + for(int i = 0; i < m; i ++){ + print("Edge ${i+1}:"); + print("Enter source vertex:"); + input = stdin.readLineSync(); + int source = int.parse(input); + print("Enter destination vertex:"); + input = stdin.readLineSync(); + int destination = int.parse(input); + g.add_edge(source, destination); + } + + // Output of Strongly Connected Components. + g.printStronglyConnectedComponents(); + +} + +/* + * Sample Input and Output + * ----------------------------- + * Enter number of vertices in the graph: + * 8 + * Enter number of edges: + * 9 + * Edge 1: + * Enter source vertex: + * 0 + * Enter destination vertex: + * 1 + * Edge 2: + * Enter source vertex: + * 3 + * Enter destination vertex: + * 0 + * Edge 3: + * Enter source vertex: + * 1 + * Enter destination vertex: + * 2 + * Edge 4: + * Enter source vertex: + * 2 + * Enter destination vertex: + * 3 + * Edge 5: + * Enter source vertex: + * 2 + * Enter destination vertex: + * 4 + * Edge 6: + * Enter source vertex: + * 4 + * Enter destination vertex: + * 5 + * Edge 7: + * Enter source vertex: + * 5 + * Enter destination vertex: + * 6 + * Edge 8: + * Enter source vertex: + * 6 + * Enter destination vertex: + * 7 + * Edge 9: + * Enter source vertex: + * 6 + * Enter destination vertex: + * 4 + * Strongly Connected Component 1: + * 0 3 2 1 + * Strongly Connected Component 1: + * 4 6 5 + * Strongly Connected Component 1: + * 7 + * + */ diff --git a/Kosaraju_Algorithm/kosaraju_algorithm.js b/Kosaraju_Algorithm/kosaraju_algorithm.js new file mode 100644 index 000000000..c54e8630e --- /dev/null +++ b/Kosaraju_Algorithm/kosaraju_algorithm.js @@ -0,0 +1,147 @@ +// Program to implement Kosaraju Algorithm for Strongly Connected Components +class Graph { + constructor(nodes) { + //2 class variables + this.nodes = nodes; // no of vertices + this.adj = new Array(nodes); // adjacency list + for (let i = 0; i < nodes; i++) { + this.adj[i] = new Array(); + } + } + //A function to print graph in readable format + showGraph() { + const { + nodes, + adj + } = this; // destructuring for clarity + + for (let i = 0; i < nodes; i++) { + console.log(`Vertex ${i} is connected to verices `, adj[i]); + } + }; + //Create Graph by adding edge between the nodes + addEdge(x, y) { + const { + nodes, + adj + } = this; + // x is connected to y + // Directed Graph + adj[x].push(y); + }; + // Recursive function to visit neighbouring nodes + dfsHelper(arr, start, visited) { + const { + nodes, + adj + } = this; + + visited[start] = true; + arr.push(start); + for (let x of adj[start]) { + if (!visited[x]) { + this.dfsHelper(arr, x, visited); + } + } + }; + //A function which will return transpose of a graph + transposeGraph() { + const gr = new Graph(this.nodes); + for (let v = 0; v < this.nodes; v++) { + // Reverse the edges of each node + let neighNodes = this.adj[v]; + for (let i of neighNodes) { + gr.adj[i].push(v); + } + } + return gr; + }; + // A Function to create stack in order to process nodes in DFS + // Stack will be created according to the finish time of node + // The node with maximum finish time will be at the top of stack + createStackOrder(v, visited, Stack) { + // Current node marked as visited + visited[v] = true; + + let neighNodes = this.adj[v]; + for (let i of neighNodes) { + if (!visited[i]) + this.createStackOrder(i, visited, Stack); + } + // All the nodes reachable by v has been traversed, pushing vertix 'v' + Stack.push(v); + }; + // A Function to print strongly connected components in a graph + stronglyConnectedComponents() { + const { + nodes, + } = this; + let Stack = []; + // All the values by default are undefined in JavaScript + // Therefore creating a visited array and marking all the nodes as not visited. + let visited = new Array(nodes); + for (let i = 0; i < nodes; i++) + visited[i] = false; + + // Creating order of stack in which the nodes will be processed + for (let i = 0; i < nodes; i++) + if (visited[i] === false) + this.createStackOrder(i, visited, Stack); + + // Create a reverse graph + let gr = this.transposeGraph(); + + // Now to perform DFS on transpose graph unmark all the visited nodes + for (let i = 0; i < nodes; i++) + visited[i] = false; + + // Performing DFS by poping each node from stack as start node, if it is not visited. + while (Stack.length) { + // Pop a vertex from stack + let n = Stack[Stack.length - 1]; + Stack.pop(); + // Array used for displaying strongly connected component in each line separately + let arr = []; + // Strongly connected component of node n + if (visited[n] == false) { + gr.dfsHelper(arr, n, visited); + console.log(arr); + } + } + } +}; + +// Implementation +let n = 7; // 7 vertices +let graph = new Graph(n); // initialise the graph + +// add edges +graph.addEdge(1, 0); +graph.addEdge(0, 2); +graph.addEdge(2, 1); +graph.addEdge(0, 3); +graph.addEdge(3, 4); +graph.addEdge(4, 5); +graph.addEdge(5, 3); +graph.addEdge(5, 6); + +console.log("The Graph is:"); +graph.showGraph(); +console.log("The Strongly Connected Components by Kosaraju Algorithm are: "); +graph.stronglyConnectedComponents(); + +// Output: +/* +The Graph is: +Vertex 0 is connected to verices [ 2, 3 ] +Vertex 1 is connected to verices [ 0 ] +Vertex 2 is connected to verices [ 1 ] +Vertex 3 is connected to verices [ 4 ] +Vertex 4 is connected to verices [ 5 ] +Vertex 5 is connected to verices [ 3, 6 ] +Vertex 6 is connected to verices [] +The Strongly Connected Components by Kosaraju Algorithm are: +[ 0, 1, 2 ] +[ 3, 5, 4 ] +[ 6 ] +*/ diff --git a/Kosaraju_Algorithm/readme.md b/Kosaraju_Algorithm/readme.md new file mode 100644 index 000000000..c0068c647 --- /dev/null +++ b/Kosaraju_Algorithm/readme.md @@ -0,0 +1,104 @@ +# Kosaraju Algorithm + +Kosaraju Algorithm is used to find strongly connected components in a directed graph. A directed graph is strongly connected if there is a path between all pairs of vertices. + +## Example + +Let's find strongly connected components in the directed graph given below. + +![Screenshot from 2020-05-13 18-30-06](https://user-images.githubusercontent.com/43384092/81815746-00185500-9548-11ea-961a-0d5a4506dd20.png) +- Create an empty stack 's'. Push the vertex in the stack only after all its neighbours are visited. + +- Create a boolean array 'visited' to keep track of all the vertices which are visited. + +- Let's start the DFS from vertex 0. Mark 0 as visited. Mark the neighbour of vertex 0 i.e. 2 as visited. Now mark the neighbour of 2 i.e. 1 as visited. There is only one neighbour of 1 i.e. 0 which is already visited. So, no neighbours of 1 are left to be traversed therefore push vertex 1 into the stack. Now, backtrack. There is no neighbour of vertex 2 left to be traversed. Push 2 into the stack.
+Stack: 1, 2
+ +- Now mark the another neighbour of 0 i.e. 3 as visited. Mark the neighbour of 3 i.e. 4 as visited. There is no neighbour of 4 left to be visited. Push 4 into the stack. Similarly, push 3 into the stack.
+Stack: 1, 2, 4, 3
+ +- All neighbours of vertex 0 are marked visited. Push 0 into the stack
+Stack: 1, 2, 4, 3, 0
+ +![a1](https://user-images.githubusercontent.com/43384092/81813457-18d33b80-9545-11ea-9324-ef0c72cb65b4.png) + +- Reverse directions of all arcs to obtain the transpose graph. Also, initialise the boolean array 'visited' as false. + +- Pop a vertex from stack 's' i.e. 0. Take vertex 0 as source and do DFS. Now, DFS will print the strongly connected component of vertex 0.
+Print: 0, 1, 2
+Stack: 1, 2, 4, 3
+ +- Pop again from the stack i.e. 3. Take vertex 3 as source and do DFS. Now, DFS will print the strongly connected component of vertex 3.
+Print: 0, 1, 2
+           3
+Stack: 1, 2, 4
+ +- Repeat the above step with vertex 4.
+Print: 0, 1, 2
+           3
+           4
+Stack: 1, 2
+ +- Now pop 2 from the stack. It is already marked as visited so no DFS will be performed. Similar case with vertex 1.
+Print: 0, 1, 2
+           3
+           4
+ +## Algorithm + +1. Create an empty stack ‘S’ and do DFS traversal of a graph. In DFS traversal, after calling recursive DFS for adjacent vertices of a vertex, push the vertex to stack.
+ +2. Reverse directions of all arcs to obtain the transpose graph.
+ +3. One by one pop a vertex from S while S is not empty. Let the popped vertex be ‘v’. Take v as source and do DFS (call DFSUtil(v)). The DFS starting from v prints strongly connected component of v.
+ +## Pseudocode +``` +Declare array of vectors adj and transpose, stack st and a boolean array visited. +Initialise all the elements of array visited with false. +dfs(s) + visited[s] = true + for(i = 0; i < adj[s].size; i++) + if(visited[adj[s][i]] == false) + dfs(adj[s][i]) + st.push(s) + +dfsUtil(s) + visited[s] = true + print(s) + for(i = 0; i < transpose[s].size; i++) + if(visited[transpose[s][i]] == false) + dfsUtil(transpose[s][i]) + +Kosaraju_Algorithm(nodes, edges, adj, src) + dfs(0) + Initialise all the elements of array visited with false. + for(i = 0; i < stack.size; i++) + top = stack.top + stack.pop + if(visited[top] is false): + dfsUtil(top) + print new line +``` + +## Complexity + + Time Complexity = O(V + E) + Space Complexity = O(V) + +where +>V = number of vertices
+>E = number of edges
+ +## Implementation + +* [C# Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Kosaraju_Algorithm/Kosaraju_Algorithm.cs) +* [Python Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Kosaraju_Algorithm/Kosaraju_Algorithm.py) +* [C++ Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Kosaraju_Algorithm/Kosaraju_Algorithm.cpp) + +## References + +* [Tutorial - GeeksforGeeks](https://www.geeksforgeeks.org/strongly-connected-components/) +* [Tutorial - OpenGenus](https://iq.opengenus.org/kosarajus-algorithm-for-strongly-connected-components/) +* [Wikipedia](http://en.wikipedia.org/wiki/Kosaraju%27s_algorithm) + diff --git a/Kruskal_Algorithm/Kruskal_Algorithm.c b/Kruskal_Algorithm/Kruskal_Algorithm.c new file mode 100644 index 000000000..4f7692296 --- /dev/null +++ b/Kruskal_Algorithm/Kruskal_Algorithm.c @@ -0,0 +1,153 @@ +// Kruskal Algorithm in C +#include +#define NUM 20 + +// Creating the edge +typedef struct edge +{ + int p; // Variable to contain all the first node of the edge + int q; // Variable to contain all the second node of the edge + int weight; // Variable to contain the weight of the edge +} edge; + +// Creating the Edgelist +typedef struct edgelist +{ + edge data[NUM]; + int n; +} edgelist; + +edgelist list; +int weights[NUM][NUM]; // Array for weights in the graph +int n; +edgelist listSpan; + +void kruskal_algo(); +void print(); +int find(int contain[], int vertexno); +void union1(int contain[], int c1, int c2); +void sort(); + +// Driver Program +int main() +{ + int total_cost; + printf("\nEnter number of vertices : "); + scanf("%d", &n); // Number of Vertices + + printf("\nEnter the adjacency matrix : \n"); + + for(int i = 0; i < n; i++) // Enter the Adjacency Matrix + for(int j = 0; j < n; j++) + scanf("%d", &weights[i][j]); + + kruskal_algo(); + print(); + return 0; +} + +// Function performing Kruskal's algorithm +void kruskal_algo() +{ + int contain[NUM], x, y; + list.n = 0; + + for(int i = 1; i < n; i++) + for(int j = 0; j < i; j++) + { + if(weights[i][j] != 0) + { + // Containing all the first node of the edges + list.data[list.n].p = i; + // Containing all the second node of the edges + list.data[list.n].q = j; + // Containing the weight of the edges + list.data[list.n].weight = weights[i][j]; + list.n++; + } + } + + // Sorting the edges according to their weight. + sort(); + + for(int i = 0; i < n; i++) + contain[i] = i; // Intializing the array with first node + + listSpan.n = 0; + + for(int i = 0; i < list.n; i++) + { + x = find(contain, list.data[i].p); // x is the first node of the edge + y = find(contain, list.data[i].q); // y is the second node of the edge + if(x != y) + { + listSpan.data[listSpan.n] = list.data[i]; + listSpan.n = listSpan.n+1; + union1(contain, x, y); + } + } +} + +// Returns the value present at k[vertex_number] +int find(int contain[], int vertex_number) +{ + return(contain[vertex_number]); +} + +void union1(int contain[], int c1, int c2) +{ + for(int i = 0; i < n; i++) + if(contain[i] == c2) + contain[i] = c1; +} + +// Sorting all the edges in increasing order +// according to their weight. +void sort() +{ + edge temp; + for(int i = 1; i < list.n; i++) + { + for(int j = 0; j < list.n-1; j++) + { + if(list.data[j].weight > list.data[j+1].weight) + { + temp = list.data[j]; + list.data[j] = list.data[j+1]; + list.data[j+1] = temp; + } + } + } +} + +// Printing the Output +void print() +{ + int cost = 0; + for(int i = 0; i < listSpan.n; i++) + { + printf("\n%d\t%d\t%d", listSpan.data[i].p, listSpan.data[i].q, listSpan.data[i].weight); + cost = cost + listSpan.data[i].weight; + } + printf("\nCost of the spanning tree = %d\n", cost); +} + +/* +INPUT : +Enter number of vertices : 6 +Enter the Adjacency Matrix : + 0 3 0 0 6 5 + 3 0 1 0 0 4 + 0 1 0 6 0 4 + 0 0 6 0 8 5 + 6 0 0 8 0 2 + 5 4 4 5 2 0 + +OUTPUT : + + 2 1 1 + 5 4 2 + 1 0 3 + 5 1 4 +Cost of the spanning tree = 15 +*/ diff --git a/Kruskal_Algorithm/Kruskal_Algorithm.dart b/Kruskal_Algorithm/Kruskal_Algorithm.dart new file mode 100644 index 000000000..e9fc32906 --- /dev/null +++ b/Kruskal_Algorithm/Kruskal_Algorithm.dart @@ -0,0 +1,159 @@ +/* +Kruskal's algorithm is a minimum spanning tree algorithm that takes a graph a +s input and finds the subset of the edges of that graph which + +(1) form a tree that includes every vertex +(2) has the minimum sum of weights among all the trees that can be + formed from the graph + */ + +import 'dart:io'; + +var INT_MAX = 9223372036854775807; + +int find(i, parent) +{ + while (parent[i] != i) { + i = parent[i]; + } + return i; +} + +void union1(i, j, parent) +{ + var a = find(i, parent); + var b = find(j, parent); + + parent[a] = b; +} + +void kruskal_mst(adjmat, V) +{ + var mincost = 0; + + var parent = new List(V); + + for (var i = 0; i < V; i++) + { + parent[i] = i; + } + + var edge_count = 0; + while (edge_count < V - 1) + { + var min = INT_MAX, a = -1, b = -1; + + for (var i = 0; i < V; i++) + { + for (var j = 0; j < V; j++) + { + if (find(i, parent) != find(j, parent) && adjmat[i][j] < min) + { + min = adjmat[i][j]; + a = i; + b = j; + } + } + } + + union1(a, b, parent); + print('Edge ${edge_count++}:(${a}, ${b}) cost:${min} \n'); + + mincost += min; + } + + print('\n Minimum cost= ${mincost} \n'); +} + +int main() +{ + print('Enter number of nodes 0 to ?'); + + var n = int.parse(stdin.readLineSync()); + var max_edges = (n + 1) * (n); + var adjmat = new List.generate(n+1, (_) => new List(n + 1)); + + for(var i = 0; i <= n; i++) + { + for(var j = 0; j <= n; j++) + { + adjmat[i][j] = INT_MAX; + } + } + + print('Enter in the following format\nsrc\ndest\nweight\n'); + for(var i = 0; i < max_edges; i++) + { + var src = int.parse(stdin.readLineSync()); + var dest = int.parse(stdin.readLineSync()); + var weight = int.parse(stdin.readLineSync()); + + print('*' * 20); + + if((src == -1) && (dest == -1)) + { + break; + } + + if(src > n || dest > n || src < 0 || dest < 0) + { + print('Invalid edge!\n'); + i--; + } + + else + { + adjmat[src][dest] = weight; + } + } + + kruskal_mst(adjmat , n + 1); + return 0; +} + +/* +Input: +Enter number of nodes 0 to ? +4 +Enter in the following format +Source +Destination +Weight + + Let the given graph is : + + (1)____1___(2) + / \ / \ + 3 4 4 6 + / \ / \ + / \ / \ +(0)___5___(5)____5___(3) + \ | / + \ | / + \ | / + \ 2 / + 6 | 8 + \ | / + \ | / + \ | / + \ | / + (4) + + adjmat = [ + [ 0, 3, 0, 0, 6, 5 ], + [ 3, 0, 1, 0, 0, 4 ], + [ 0, 1, 0, 6, 0, 4 ], + [ 0, 0, 6, 0, 8, 5 ], + [ 6, 0, 0, 8, 0, 2 ], + [ 5, 4, 4, 5, 2, 0 ] + ]; +Output: + + Edge: 0-1 cost: 3 + Edge: 1-2 cost: 1 + Edge: 1-5 cost: 4 + Edge: 5-4 cost: 2 + Edge: 5-3 cost: 5 + Minimum Weight is 15 + */ + diff --git a/Kruskal_Algorithm/Kruskal_Algorithm.js b/Kruskal_Algorithm/Kruskal_Algorithm.js new file mode 100644 index 000000000..176c56ea5 --- /dev/null +++ b/Kruskal_Algorithm/Kruskal_Algorithm.js @@ -0,0 +1,138 @@ +// Javascript Implementation of Kruskals Algorithm + +class UnionFind { + constructor(elements) { + this.count = elements.length; + this.parent = {}; + elements.forEach(e => (this.parent[e] = e)); + } + + union(a, b) { + let rootA = this.find(a); + let rootB = this.find(b); + if (rootA === rootB) return; + if (rootA < rootB) { + if (this.parent[b] != b) this.union(this.parent[b], a); + this.parent[b] = this.parent[a]; + } else { + if (this.parent[a] != a) this.union(this.parent[a], b); + this.parent[a] = this.parent[b]; + } + } + + find(a) { + while (this.parent[a] !== a) { + a = this.parent[a]; + } + return a; + } + + connected(a, b) { + return this.find(a) === this.find(b); + } +} + +class PriorityQueue { + constructor(maxSize) { + if (isNaN(maxSize)) { + maxSize = 10; + } + this.maxSize = maxSize; + this.container = []; + } + + isEmpty() { + return this.container.length === 0; + } + + isFull() { + return this.container.length >= this.maxSize; + } +} + +PriorityQueue.prototype.Element = class { + constructor (data, priority) { + this.data = data; this.priority = priority; + } +} + +function kruskalsMST() { + const MST = new Graph(); + this.nodes.forEach(node => MST.addNode(node)); + if (this.nodes.length === 0) { + return MST; + } + + edgeQueue = new PriorityQueue(this.nodes.length * this.nodes.length); + + + for (let node in this.edges) { + this.edges[node].forEach(edge => { + edgeQueue.enqueue([node, edge.node], edge.weight); + }); + } + + let uf = new UnionFind(this.nodes); + + + while (!edgeQueue.isEmpty()) { + let nextEdge = edgeQueue.dequeue(); + let nodes = nextEdge.data; + let weight = nextEdge.priority; + + if (!uf.connected(nodes[0], nodes[1])) { + MST.addEdge(nodes[0], nodes[1], weight); + uf.union(nodes[0], nodes[1]); + } + } + return MST; +} + +let g = new Graph(); + +g.addNode("A"); +g.addNode("B"); +g.addNode("C"); +g.addNode("D"); +g.addNode("E"); +g.addNode("F"); +g.addNode("G"); + +g.addEdge("A", "C", 100); +g.addEdge("A", "B", 3); +g.addEdge("A", "D", 4); +g.addEdge("C", "D", 3); +g.addEdge("D", "E", 8); +g.addEdge("E", "F", 10); +g.addEdge("B", "G", 9); +g.addEdge("E", "G", 50); + +g.kruskalsMST().display(); + +///Sample Input +// let g = new Graph(); +// g.addNode("A"); +// g.addNode("B"); +// g.addNode("C"); +// g.addNode("D"); +// g.addNode("E"); +// g.addNode("F"); +// g.addNode("G"); + +// g.addEdge("A", "C", 100); +// g.addEdge("A", "B", 3); +// g.addEdge("A", "D", 4); +// g.addEdge("C", "D", 3); +// g.addEdge("D", "E", 8); +// g.addEdge("E", "F", 10); +// g.addEdge("B", "G", 9); +// g.addEdge("E", "G", 50); + +/// Sample Output +// A->B, D +// B->A, G +// C->D +// D->C, A, E +// E->D, F +// F->E +// G->B diff --git a/Kruskal_Algorithm/Kruskal_Algorithm.py b/Kruskal_Algorithm/Kruskal_Algorithm.py new file mode 100644 index 000000000..973909899 --- /dev/null +++ b/Kruskal_Algorithm/Kruskal_Algorithm.py @@ -0,0 +1,93 @@ +#Implementation of Kruskal Algorithm using Disjoint + +graphData = [] +vertices = [] + +class Disjoint: + def __init__(self): + self.sets = [] + + def createSet(self, val): + self.sets.append([val]) + + def getSets(self): + return self.sets + + def findSet(self, val): + for oneSet in self.sets: + if val in oneSet: + return oneSet + + def mergeSets(self, val1, val2): + set1 = self.findSet(val1) + set2 = self.findSet(val2) + if set1 != set2: + set1.extend(set2) + self.sets.remove(set2) + +def kruskalAlgorithm(vertices, graphData): + MST = [] + minimumWeight = 0 + + adisjointSet = Disjoint() # Creating object of disjoint set + for vertex in vertices: + adisjointSet.createSet(vertex) + + graphData.sort() # Sort weights in increasing order + + for weight, vertex1, vertex2 in graphData: + if (adisjointSet.findSet(vertex1) != adisjointSet.findSet(vertex2)): + minimumWeight += weight + MST.append((weight, vertex1, vertex2)) + adisjointSet.mergeSets(vertex1, vertex2) + # To improve efficiency + # when length of disjoint set becomes 1 we can break loop + if (len(adisjointSet.sets) == 1): + break + + print("Minimum Weight : ", minimumWeight) + # To display in which order edges are added + for path in MST: + print((path[1], path[2]), "=>", path[0]) + +if __name__ == "__main__": + numberOfVertices = int(input("Enter number of vertices in graph : ")) + print("Enter vertices") + for _ in range(numberOfVertices): + vertex = input() + vertices.append(vertex) + + numberOfEdges = int(input("Enter number of edges in graph : ")) + print("Note :=> Enter graph data in following format weight vertex1 vertex2") + for _ in range(numberOfEdges): + weights, vertex1, vertex2 = input().split() + weights = int(weights) + graphData.append((weights, vertex1, vertex2)) + + kruskalAlgorithm(vertices, graphData) + +""" +Input/Output + +Enter number of vertices in graph : 5 +Enter vertices +a +b +c +d +e +Enter number of edges in graph : 7 +Note :=> Enter graph data in following format weight vertex1 vertex2 +1 a c +4 a b +2 c b +3 b d +7 c d +5 c e +6 d e +Minimum Weight : 11 +('a', 'c') => 1 +('c', 'b') => 2 +('b', 'd') => 3 +('c', 'e') => 5 +""" diff --git a/Largest_Common_Multiple/Largest_Common_Multiple_1-DArray.c b/Largest_Common_Multiple/Largest_Common_Multiple_1-DArray.c new file mode 100644 index 000000000..e25fcfbc9 --- /dev/null +++ b/Largest_Common_Multiple/Largest_Common_Multiple_1-DArray.c @@ -0,0 +1,47 @@ +// C program to find Largest_common_multiple of n elements +#include +#include + +// GCD of 'a' and 'b' +int gcd(int a, int b) +{ + if (b == 0) + return a; + return gcd(b, a % b); +} + +// Returns LCM of array elements +long long int findlcm(int arr[], int n) +{ + // Initialize result + long long int ans = arr[0]; + + // ans contains LCM of arr[0], ..arr[i] + // after i'th iteration, + int i; + for (i = 1; i < n; i++) + ans = (((arr[i] * ans)) / (gcd(arr[i], ans))); + + return ans; +} + +// Driver Code +int main() +{ + int n, i; + printf("Enter the no of elements of the array\n"); + scanf("%d", & n); + int arr[n]; + printf("Enter the elements of the array\n"); + for (i = 0; i < n; i++) { + scanf("%d", & arr[i]); + } + printf("LCM : %lld", findlcm(arr, n)); + return 0; +} + +/*Enter the no of elements of the array +5 +Enter the elements of the array +4 6 12 24 30 +LCM : 120*/ diff --git a/Largest_Common_Multiple/Largest_Common_Multiple_1-DArray.cpp b/Largest_Common_Multiple/Largest_Common_Multiple_1-DArray.cpp new file mode 100644 index 000000000..f6a75e43b --- /dev/null +++ b/Largest_Common_Multiple/Largest_Common_Multiple_1-DArray.cpp @@ -0,0 +1,53 @@ +/*This code is to find the Largest__common_multiple of an given array of elements*/ + +#include + +using namespace std; + +int getLCM(int a, int b) +{ + int m; + m = (a > b) ? a : b; + while (true) { + if (m % a == 0 && m % b == 0) + // returns the value to getLCMArray function + return m; + m++; + } +} + +int getLCMArray(int arr[], int n) +{ + int lcm = getLCM(arr[0], arr[1]); + for (int i = 2; i < n; i++) + { + // calls function getLCM to compute the LCM of two numbers + lcm = getLCM(lcm, arr[i]); + } + // returns LCM to main. + return lcm; +} + +int main() +{ + int n, i; + cout << "Enter the no. of elements of array\n"; + cin >> n; + int a[n]; + cout << "Enter the elements of array\n"; + for (i = 0; i < n; i++) + { + cin >> a[i]; + } + cout << "LCM of array elements: " << getLCMArray(a, n); +} + +/*Enter the no. of elements of array +5 +Enter the elements of array +4 +6 +12 +24 +30 +LCM of array elements: 120*/ diff --git a/Largest_Common_Multiple/Largest_Common_Multiple_1-DArray.java b/Largest_Common_Multiple/Largest_Common_Multiple_1-DArray.java new file mode 100644 index 000000000..cfc3cc5a4 --- /dev/null +++ b/Largest_Common_Multiple/Largest_Common_Multiple_1-DArray.java @@ -0,0 +1,54 @@ +// JAVA code to find Largest_common_multiple of n elements of the array + +import java.util.Scanner; +import java.util.Arrays; + +class LCM +{ + public static void main(String args[]) + { + int n; + Scanner s = new Scanner(System.in); + System.out.println("Enter no. of elements in array:"); + n = s.nextInt(); + int a[] = new int[n]; + System.out.println("Enter all the elements:"); + for (int i = 0; i < n; i++) + { + // Taking input from the user + a[i] = s.nextInt(); + } + int lcm = 1; + for (int each: a) + { + lcm = calculateLcm(lcm, each); + } + System.out.println("LCM for " + Arrays.toString(a) + " is : " + lcm); + } + + // Calculating LCM by using GCD + private static int calculateLcm(int lcm, int each) + { + return lcm * each / gcd(lcm, each); + } + + // Calculating GCD + private static int gcd(int val1, int val2) + { + if (val1 == 0 || val2 == 0) + return 0; + + if (val1 == val2) + return val1; + + if (val1 > val2) + return gcd(val1 - val2, val2); + return gcd(val1, val2 - val1); + } +} + +/*Enter no. of elements in array: +6 +Enter all the elements: +1 2 3 4 5 6 +LCM for [1, 2, 3, 4, 5, 6] is : 60*/ diff --git a/Last_Digit_of_Square_of_Nth_Fibonacci_Number/Last_Digit_of_Square_of_Nth_Fibonacci_Number.cpp b/Last_Digit_of_Square_of_Nth_Fibonacci_Number/Last_Digit_of_Square_of_Nth_Fibonacci_Number.cpp new file mode 100644 index 000000000..e5211db4e --- /dev/null +++ b/Last_Digit_of_Square_of_Nth_Fibonacci_Number/Last_Digit_of_Square_of_Nth_Fibonacci_Number.cpp @@ -0,0 +1,43 @@ +//C++ Program to find last digit of square of nth fibonacci numbers +#include +using namespace std; + +int main(){ + int a[60], n, i, c, b[60], j; + a[0] = 0; + a[1] = 1; + b[0] = 0; + b[1] = 1; + + /*Using the concept that after 60 numbers in a fibonacci + numbers the last digit repeats itself again and again*/ + + /*In this loop we store the last digits of squares of first 60 fibonacci number and + we will store last digits in new array and their index as position in fibonacci series*/ + + for(i = 2 ; i < 60 ; i++){ + a[i] = (a[i - 1] + a[i - 2]) % 10; + c = a[i]; + b[i] = (c * c) % 10; + } + cin>> n ; + + //print the last digit given in that position + + cout<< " \n The Last Digit of Square of this Number : " << b[ n % 60] ; + + return 0; +} +/* +Sample Input 1: +2344 + +Sample Output 1: +The Last Digit of Square of this Number : 9 + +Sample Input 2: +267 + +Sample Output 2: +The Last Digit of Square of this Number : 4 +*/ diff --git a/Linear_Search/Linear_Search.dart b/Linear_Search/Linear_Search.dart new file mode 100644 index 000000000..1afcfd8ff --- /dev/null +++ b/Linear_Search/Linear_Search.dart @@ -0,0 +1,129 @@ +//Linear search or sequential search is a method for finding an element within a list. +//It sequentially checks each element of the list until a match is found or the whole list has been searched. +import 'dart:io'; + +void linearSearch(List list, int x) { + int pass = 0; + list.forEach((val) { + if (val == x) { + print('Found $x in the List!'); + pass = 1; + } + }); + if (pass == 0) print('Did not find $x in the List!'); +} + +main() { + List list = new List(); + int task = 0; + print('Linear Search Program'); + while (task != 4) { + print( + '0 - Display List\n1 - Insert element in List \n2 - Search element in List\n3 - Quit\nSelect task:-'); + try { + task = int.parse(stdin.readLineSync()); + } on Exception { + print('Please enter valid Integer value!'); + continue; + } + switch (task) { + case 0: + if (list.length == 0) { + print('Empty List!'); + } else { + print('List:-'); + list.forEach((val) { + print(val); + }); + } + break; + case 1: + int val = null; + print('Enter value that needs to be inserted in List:- '); + try { + val = int.parse(stdin.readLineSync()); + } on Exception { + print('Please enter valid Integer value!'); + continue; + } + if (val == null) { + print('Failed to insert element in List!'); + continue; + } + list.add(val); + print('Successfully inserted $val in List!'); + break; + + case 2: + int val = null; + print('Enter value that needs to be searched in List:- '); + try { + val = int.parse(stdin.readLineSync()); + } on Exception { + print('Please enter valid Integer value!'); + continue; + } + if (val == null) { + print('Failed to search element in List!'); + continue; + } + linearSearch(list, val); + break; + + case 3: + print('Linear Search Program Complete'); + break; + + default: + continue; + } + } +} + +/* +Sample Input/Output: +Linear Search Program +0 - Display List +1 - Insert element in List +2 - Search element in List +3 - Quit +Select task:- //to insert element in list +1 +Enter value that needs to be inserted in List:- +1 +Successfully inserted 1 in List! +0 - Display List +1 - Insert element in List +2 - Search element in List +3 - Quit +Select task:- +1 +Enter value that needs to be inserted in List:- +2 +Successfully inserted 2 in List! +0 - Display List +1 - Insert element in List +2 - Search element in List +3 - Quit +Select task:- +1 +Enter value that needs to be inserted in List:- +3 +Successfully inserted 3 in List! +0 - Display List +1 - Insert element in List +2 - Search element in List +3 - Quit +Select task:- //to search the given element +2 +Enter value that needs to be searched in List:- +2 +Found 2 in the List! +0 - Display List +1 - Insert element in List +2 - Search element in List +3 - Quit +Select task:- //to end the linear program algorithm +3 +Linear Search Program Complete +*/ diff --git a/Linear_Search/Linear_Search.rs b/Linear_Search/Linear_Search.rs new file mode 100644 index 000000000..d6c5d2aef --- /dev/null +++ b/Linear_Search/Linear_Search.rs @@ -0,0 +1,68 @@ +// Rust program for Linear Search +use std::io; + +fn main() { + println!(" Enter number of elements to be entered in the array "); + let mut size = String::new(); + + io::stdin().read_line(&mut size).expect("failed to read input."); + let size: usize = size.trim_end().parse().expect("invalid input"); + let mut vector: Vec = Vec::with_capacity(size as usize); + + println!("Enter element to be searched " ); + let mut element = usize::new(); + + println!("Enter elements of array "); + let mut index = 0; + + // Enter values into vector + while index < size { + index += 1; + // Note: Rust takes spaces as non-intergral value + let mut temp_arr = String::new(); + io::stdin().read_line(&mut temp_arr).expect("failed to read input."); + let temp_arr: usize = temp_arr.trim_end().parse().expect("invalid input"); + vector.push(temp_arr); + } + + // Linear Search process + let mut checkpoint = 0; + for index in 0..size - 1 { + if element == vector[index]{ + checkpoint = 1; + println!("Element is found at index "); + println!("{:?}" , index + 1); + } + } + + if checkpoint == 0 { + println!("Element is not found in the array "); + } +} +/* +TEST CASE +INPUT + Enter number of elements to be entered in the array +3 +Enter element to be searched +2 +Enter elements of array +1 +2 +3 +OUTPUT +Element is found at index +2 +INPUT + Enter number of elements to be entered in the array +3 +Enter element to be searched +5 +Enter elements of array +1 +2 +3 +OUTPUT +Element is not found in the array +*/ + diff --git a/Linear_Search/Linear_Search.ts b/Linear_Search/Linear_Search.ts new file mode 100644 index 000000000..8f137d01a --- /dev/null +++ b/Linear_Search/Linear_Search.ts @@ -0,0 +1,36 @@ +/* Implementation of LinearSearch algorithm to find value 5 in a given array of numbers */ + +function LinearSearch(arr:number[], n:number, val:number) :number +{ + for (let i = 0; i < n; i++) + { + if (val == arr[i]) + return i; + } + return -1; +} + + +var result = 0 +var n = 0 +var val = 5 //input value +console.log(" value to be found: ", val); +var n: number = 10 //no. of elements in the array +var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; //input array +console.log(" Array of numbers is: ", arr); +result = LinearSearch(arr, n, val) +if (result != -1) +{ + console.log(" value ", val," found at index no. ", result," in the array "); +} +else +{ + console.log(" value ", val," not found "); +} + + +/* OUTPUT: + value to be found: 5 + Array of numbers is: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + value 5 found at index no. 4 in the array +*/ diff --git a/Linked_List/Length_of_Linked_List.c b/Linked_List/Length_of_Linked_List.c new file mode 100644 index 000000000..ec4fb18d1 --- /dev/null +++ b/Linked_List/Length_of_Linked_List.c @@ -0,0 +1,71 @@ +// Length of Linked List +#include +#include + +/* +This code is written for Char to store in LinkedList, if you want to store numericals or any other datatype, +just replace relevent data type in place of char in class Node. +*/ + +struct Node +{ + char data; + struct Node* next; +}; + +void pushing_data_to_LL(struct Node** headPointer, char newData) +{ + struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); + newNode -> data = newData; + newNode -> next = (*headPointer); + (*headPointer) = newNode; +} + +int gettingLength(struct Node* head) +{ + int count = 0; + struct Node* current = head; + while(current != NULL) + { + count++; + current = current -> next; + } + return count; +} + +int main() +{ + struct Node* head = NULL; + printf("Currently Length of Linkedlist is: %d", gettingLength(head)); + + pushing_data_to_LL(&head, 'G'); + pushing_data_to_LL(&head, 'S'); + pushing_data_to_LL(&head, 'S'); + pushing_data_to_LL(&head, 'O'); + pushing_data_to_LL(&head, 'C'); + + //Intermediate Checking + printf("\n Currently Length of Linkedlist is: %d", gettingLength(head)); + + pushing_data_to_LL(&head, '-'); + printf("\n Currently Length of Linkedlist is: %d", gettingLength(head)); + + pushing_data_to_LL(&head, '2'); + pushing_data_to_LL(&head, '0'); + pushing_data_to_LL(&head, '2'); + pushing_data_to_LL(&head, '0'); + + printf("\n Currently Length of Linkedlist is: %d", gettingLength(head)); + + return 0; +} + +/* +TestCase-1: +Sample Input: G S S O C 2 0 2 0 +Sample Output: 9 //9 letters + +TestCase-2: +Sample Input: O p e n - S o u r c e +Sample Output: 11 //11 letters +*/ diff --git a/Linked_List/Length_of_Linked_List.java b/Linked_List/Length_of_Linked_List.java new file mode 100644 index 000000000..627cf9145 --- /dev/null +++ b/Linked_List/Length_of_Linked_List.java @@ -0,0 +1,74 @@ +import java.util.*; + +/* +This code is written for Strings to store in LinkedList, if you want to store numericals or any other datatype, +just replace relevent data type in place of string in class Node. +*/ + +class Node +{ + String data; + Node next; + Node(String info) + { + data = info; + next = null; + } +} + +class LinkedListLength +{ + Node head; + public void pushing_data_to_LL(String new_data) + { + Node new_node = new Node(new_data); // Creating the node and assign the data. + new_node.next = head; // making the next node as head node + head = new_node; // making head to point to new Node + } + public int gettingLength() + { + Node temp = head; + int count = 0; + while(temp != null) + { + count++; + temp = temp.next; + } + return count; + } +} + +class Mainer +{ + public static void main(String[] args) + { + LinkedListLength thisList = new LinkedListLength(); + + System.out.println("Currently the Length of the LinkedList is: " + thisList.gettingLength()); + + thisList.pushing_data_to_LL("G"); + thisList.pushing_data_to_LL("S"); + thisList.pushing_data_to_LL("S"); + thisList.pushing_data_to_LL("O"); + thisList.pushing_data_to_LL("C"); + + System.out.println("Currently the Length of the LinkedList is: " + thisList.gettingLength()); + + thisList.pushing_data_to_LL("2"); + thisList.pushing_data_to_LL("0"); + thisList.pushing_data_to_LL("2"); + thisList.pushing_data_to_LL("0"); + + System.out.println("Currently the Length of the LinkedList is: " + thisList.gettingLength()); + } +} + +/* +TestCase-1: +Sample Input: G S S O C 2 0 2 0 +Sample Output: 9 //9 letters + +TestCase-2: +Sample Input: O p e n - S o u r c e +Sample Output: 11 //11 letters +*/ \ No newline at end of file diff --git a/Linked_List_Merge_Sort/Linked_List_Merge_Sort.c b/Linked_List_Merge_Sort/Linked_List_Merge_Sort.c new file mode 100644 index 000000000..fa759d249 --- /dev/null +++ b/Linked_List_Merge_Sort/Linked_List_Merge_Sort.c @@ -0,0 +1,157 @@ +/*C program for sorting a Single Linked List using Merge Sort technique. Merge Sort uses divide and conquer technique i.e. it + divides the input array into two halves, calls itself recursively for the two halves until one element remains and then merges + the two halves + + | 6 | 5 | 4 | 3 | 2 | 1 | * + / \ * + / \ * + | 6 | 5 | 4 | | 3 | 2 | 1 | * + / \ / \ * DIVIDE + / \ / \ * + | 6 | 5 | | 4 | | 3 | 2 | | 1 | * + / \ | / \ | * + |6| |5| | |3| |2| | * + \ / | \ / | + \ / | \ / | + | 5 | 6 | | | 2 | 3 | | * + \ | \ | * + \ | \ | * + | 4 | 5 | 6 | | 1 | 2 | 3 | * MERGE + \ / * + \ / * + | 1 | 2 | 3 | 4 | 5 | 6 | * + */ +#include +#include + +struct Node { + int data; + struct Node* next; +}; + +/*Merging the contents of the two linked list*/ +struct Node *merge(struct Node *l1, struct Node *l2) +{ + if(!l1) + return l2; + + if(!l2) + return l1; + + struct Node *head=NULL; + + if(l1->data < l2->data) + { + head = l1; + l1 = l1->next; + } + else + { + head = l2; + l2 = l2->next; + } + + struct Node *ptr = head; + + while(l1 && l2) + { + if(l1->data < l2->data) + { + ptr->next = l1; + l1 = l1->next; + } + else + { + ptr->next = l2; + l2 = l2->next; + } + ptr = ptr->next; + } + + if(l1) + ptr->next = l1; + else + ptr->next = l2; + + return head; +} + +/*Dividing the linked list*/ +struct Node* mergeSort(struct Node* head) { + + if(head==NULL || head->next==NULL) + return head; + + /*Dividing the linked list into two equal parts as done in merge sort*/ + struct Node *ptr1 = head; + struct Node *ptr2 = head->next; + + while(ptr2 && ptr2->next) + { + ptr1 = ptr1->next; + if(ptr2->next) + ptr2 = ptr2->next->next; + } + + ptr2 = ptr1->next; + ptr1->next = NULL; + + return merge(mergeSort(head),mergeSort(ptr2)); +} + +/* Function for printing the Single Linked List*/ +void printList(struct Node* head) { + + while (head != NULL) { + printf("%d-->", head->data); + head = head->next; + } + + printf("NULL"); +} + +int main() +{ + int test,n,ele; + scanf("%d", &test); + + /* Inserting elements into linked list*/ + while (test--) + { + struct Node* head = NULL; + struct Node *temp = NULL; + scanf("%d", &n); + + while(n--) + { + scanf("%d", &ele); + + struct Node *ptr = (struct Node*)malloc(sizeof(struct Node)); + ptr->data = ele; + ptr->next = NULL; + + if(head==NULL) + head = ptr; + else + temp->next = ptr; + + temp = ptr; + } + + head = mergeSort(head); + printList(head); + } + return 0; +} + +/* +Sample Input +1 - Test cases +5 - Total number of elements to be inserted in linked list +23 2 34 5 1 - Adding the contents of the linked list + +Sample Output +1-->2-->5-->23-->34-->NULL +*/ + + diff --git a/Linked_List_Merge_Sort/Linked_List_Merge_Sort.cpp b/Linked_List_Merge_Sort/Linked_List_Merge_Sort.cpp new file mode 100644 index 000000000..a5ddf503f --- /dev/null +++ b/Linked_List_Merge_Sort/Linked_List_Merge_Sort.cpp @@ -0,0 +1,156 @@ +/*C++ program for sorting a Single Linked List using Merge Sort technique. Merge Sort uses divide and conquer technique i.e. it + divides the input array into two halves, calls itself recursively for the two halves until one element remains and then merges + the two halves + | 6 | 5 | 4 | 3 | 2 | 1 | * + / \ * + / \ * + | 6 | 5 | 4 | | 3 | 2 | 1 | * + / \ / \ * DIVIDE + / \ / \ * + | 6 | 5 | | 4 | | 3 | 2 | | 1 | * + / \ | / \ | * + |6| |5| | |3| |2| | * + \ / | \ / | + \ / | \ / | + | 5 | 6 | | | 2 | 3 | | * + \ | \ | * + \ | \ | * + | 4 | 5 | 6 | | 1 | 2 | 3 | * MERGE + \ / * + \ / * + | 1 | 2 | 3 | 4 | 5 | 6 | * + */ + +#include +using namespace std; + +struct Node { + int data; + struct Node* next; + Node(int x) { + data = x; + next = NULL; + } +}; + +/*Merging the contents of the two linked list*/ +struct Node *merge(struct Node *l1, struct Node *l2) +{ + if(!l1) + return l2; + + if(!l2) + return l1; + + struct Node *head = NULL; + + if(l1->data < l2->data) + { + head = l1; + l1 = l1->next; + } + else + { + head = l2; + l2 = l2->next; + } + + struct Node *ptr = head; + + while(l1 && l2) + { + if(l1->data < l2->data) + { + ptr->next = l1; + l1 = l1->next; + } + else + { + ptr->next = l2; + l2 = l2->next; + } + ptr = ptr->next; + } + + if(l1) + ptr->next = l1; + else + ptr->next = l2; + + return head; +} + +/*Dividing the linked list*/ +struct Node* mergeSort(struct Node* head) { + + if(head == NULL || head->next == NULL) + return head; + + /*Dividing the linked list into two equal parts as done in merge sort*/ + struct Node *ptr1 = head; + struct Node *ptr2 = head->next; + + while(ptr2 && ptr2->next) + { + ptr1 = ptr1->next; + if(ptr2->next) + ptr2 = ptr2->next->next; + } + + ptr2 = ptr1->next; + ptr1->next = NULL; + + return merge(mergeSort(head),mergeSort(ptr2)); +} + +void printList(struct Node* head) { + + while (head != NULL) { + printf("%d-->", head->data); + head = head->next; + } + + printf("NULL"); +} + +int main() { + int test,n,ele; + cin >> test; + + while (test--) + { + struct Node *head = NULL; + struct Node *temp = NULL; + cin>>n; + + while(n--) + { + cin>>ele; + + struct Node *ptr = new Node(ele); + + if(head == NULL) + head = ptr; + else + temp->next = ptr; + + temp = ptr; + } + + head = mergeSort(head); + printList(head); + } + return 0; +} + +/* +Sample Input +1 - Test cases +5 - Total number of elements to be inserted in linked list +23 2 34 5 1 - Adding the contents of the linked list + +Sample Output +1-->2-->5-->23-->34-->NULL +*/ + + diff --git a/Linked_List_Merge_Sort/Linked_List_Merge_Sort.java b/Linked_List_Merge_Sort/Linked_List_Merge_Sort.java new file mode 100644 index 000000000..1021a2c0d --- /dev/null +++ b/Linked_List_Merge_Sort/Linked_List_Merge_Sort.java @@ -0,0 +1,165 @@ +/*JAVA program for sorting a Single Linked List using Merge Sort technique. Merge Sort uses divide and conquer technique i.e. + it divides the input array into two halves, calls itself recursively for the two halves until one element remains and then + merges the two halves + + | 6 | 5 | 4 | 3 | 2 | 1 | * + / \ * + / \ * + | 6 | 5 | 4 | | 3 | 2 | 1 | * + / \ / \ * DIVIDE + / \ / \ * + | 6 | 5 | | 4 | | 3 | 2 | | 1 | * + / \ | / \ | * + |6| |5| | |3| |2| | * + \ / | \ / | + \ / | \ / | + | 5 | 6 | | | 2 | 3 | | * + \ | \ | * + \ | \ | * + | 4 | 5 | 6 | | 1 | 2 | 3 | * MERGE + \ / * + \ / * + | 1 | 2 | 3 | 4 | 5 | 6 | * + */ + +import java.util.*; +import java.lang.*; +import java.io.*; + +class Node +{ + int data; + Node next; + Node(int key) + { + data = key; + next = null; + } +} + +class LinkedList +{ + /*Merging the contents of the two linked list*/ + + public static Node merge(Node l1, Node l2) + { + if(l1 == null) + return l2; + + if(l2 == null) + return l1; + + Node head = null; + + if(l1.data < l2.data) + { + head = l1; + l1 = l1.next; + } + else + { + head = l2; + l2 = l2.next; + } + + Node ptr = head; + + while(l1 != null && l2 != null) + { + if(l1.data < l2.data) + { + ptr.next = l1; + l1 = l1.next; + } + else + { + ptr.next = l2; + l2 = l2.next; + } + ptr = ptr.next; + } + + if(l1 != null) + ptr.next = l1; + else + ptr.next = l2; + + return head; + } + + /*Dividing the linked list*/ + public static Node mergeSort(Node head) + { + + if(head == null || head.next == null) + return head; + + Node ptr1 = head; + Node ptr2 = head.next; + + /*Dividing the linked list into two equal parts as done in merge sort*/ + while(ptr2 !=null && ptr2.next != null) + { + ptr1 = ptr1.next; + if(ptr2.next != null) + ptr2 = ptr2.next.next; + } + + ptr2 = ptr1.next; + ptr1.next = null; + + return merge(mergeSort(head),mergeSort(ptr2)); + } + + public static void printList(Node head) + { + if(head == null) + return; + + Node temp = head; + while(temp != null) + { + System.out.print(temp.data + "-->"); + temp = temp.next; + } + System.out.print("NULL"); + } + + public static void main (String[] args) + { + Scanner sc= new Scanner(System.in); + int t = sc.nextInt(); + + LinkedList l = new LinkedList(); + + while(t!=0) + { + int n = sc.nextInt(); + Node head = new Node(sc.nextInt()); + Node temp = head; + + n--; + + while(n!=0){ + temp.next = new Node(sc.nextInt()); + temp = temp.next; + n--; + } + + head = l.mergeSort(head); + l.printList(head); + t--; + } + } +} + +/* + Sample Input + 1 - Test cases + 5 - Total number of elements to be inserted in linked list + 23 2 34 5 1 - Adding the contents of the linked list + + Sample Output + 1-->2-->5-->23-->34-->NULL +*/ + diff --git a/Linked_List_Merge_Sort/Linked_List_Merge_Sort.py b/Linked_List_Merge_Sort/Linked_List_Merge_Sort.py new file mode 100644 index 000000000..5ed23598f --- /dev/null +++ b/Linked_List_Merge_Sort/Linked_List_Merge_Sort.py @@ -0,0 +1,149 @@ +''' + PYTHON program for sorting a Single Linked List using Merge Sort technique. Merge Sort uses divide and conquer technique i.e. + it divides the input array into two halves, calls itself recursively for the two halves until one element remains and then + merges the two halves + + | 6 | 5 | 4 | 3 | 2 | 1 | * + / \ * + / \ * + | 6 | 5 | 4 | | 3 | 2 | 1 | * + / \ / \ * DIVIDE + / \ / \ * + | 6 | 5 | | 4 | | 3 | 2 | | 1 | * + / \ | / \ | * + |6| |5| | |3| |2| | * + \ / | \ / | + \ / | \ / | + | 5 | 6 | | | 2 | 3 | | * + \ | \ | * + \ | \ | * + | 4 | 5 | 6 | | 1 | 2 | 3 | * MERGE + \ / * + \ / * + | 1 | 2 | 3 | 4 | 5 | 6 | * +''' + +import atexit +import io +import sys + +class Node: + + def __init__(self, data): + self.data = data + self.next = None + +# Linked List Class +class LinkedList: + def __init__(self): + self.head = None + + # creates a new node with given value and appends it at the end of the linked list + + def merge(self, l1, l2): + head = None + + # Base cases + if l1 == None: + return l2 + + if l2 == None: + return l1 + + # pick either l1 or l2 and recurse + if l1.data <= l2.data: + head = l1 + l1 = l1.next + else: + head = l2 + l2 = l2.next + + ptr=head + + while l1!=None and l2!=None: + + if l1.data < l2.data: + ptr.next = l1 + l1 = l1.next + else: + ptr.next = l2 + l2 = l2.next + + ptr = ptr.next + + if l1 != None: + ptr.next = l1 + else: + ptr.next = l2 + + return head + + + def mergeSort(self, head): + + if head == None or head.next == None: + return head + + ptr1 = head + ptr2 = head.next + + while(ptr2 != None and ptr2.next != None): + ptr1 = ptr1.next + if ptr2.next != None: + ptr2 = ptr2.next.next + + ptr2 = ptr1.next + ptr1.next = None + + return self.merge(self.mergeSort(head), self.mergeSort(ptr2)) + + +# prints the elements of linked list starting with head +def printList(head): + + if head is None: + return + + temp = head + + while temp: + print(temp.data,end="-->") + temp = temp.next + + print("NULL") + + +if __name__ == '__main__': + t=int(input()) + + for cases in range(t): + n = int(input()) + li = LinkedList() + + temp = li.head + + while n!=0: + ele = int(input()) + ptr = Node(ele) + + if li.head is None: + li.head = ptr + else + temp.next = ptr + + temp = ptr + n -= 1 + + li.head = li.mergeSort(li.head) + printList(li.head) + + ''' + Sample Input + 1 - Test cases + 5 - Total number of elements to be inserted in linked list + 23 2 34 5 1 - Adding the contents of the linked list + + Sample Output + 1-->2-->5-->23-->34-->NULL +''' + diff --git a/Longest_Common_Subsequence/Longest_Common_Subsequence.php b/Longest_Common_Subsequence/Longest_Common_Subsequence.php new file mode 100644 index 000000000..72a618ec1 --- /dev/null +++ b/Longest_Common_Subsequence/Longest_Common_Subsequence.php @@ -0,0 +1,78 @@ + 0 && $j > 0) + { + // If current character in X[] and Y are same, + // then current character is part of LCS + if ($X[$i - 1] == $Y[$j - 1]) + { + // Put current character in result + $lcs[$index - 1] = $X[$i - 1]; + $i--; + $j--; + $index--; // reduce values of i, j and index + } + + // If not same, then find the larger of two + // and go in the direction of larger value + else if ($L[$i - 1][$j] > $L[$i][$j - 1]) + $i--; + else + $j--; + } + + // Print the lcs + echo "LCS of " . $X . " and " . $Y . " is "; + for($k = 0; $k < $temp; $k++) + echo $lcs[$k]; +} + +// Driver Code +$X = "ABCDE"; +$Y = "BCDEF"; +$m = strlen($X); +$n = strlen($Y); +lcs($X, $Y, $m, $n); + +/* +OUTPUT: +LCS of ABCDE and BCDEF is BCDE +*/ + +?> diff --git a/Longest_Common_Subsequence/Longest_Common_Subsequence.rb b/Longest_Common_Subsequence/Longest_Common_Subsequence.rb new file mode 100644 index 000000000..27e5aa5ec --- /dev/null +++ b/Longest_Common_Subsequence/Longest_Common_Subsequence.rb @@ -0,0 +1,58 @@ +=begin +Problem Statement- Given two sequences, find +the length of longest subsequence present in both of them. +A subsequence is a sequence that can be derived +from another sequence by deleting some or +no elements without changing the order of the remaining elements. +=end + +def longest_common_subsequence(arr1, arr2, size1, size2) + lcs = Array.new(size1 + 1){Array.new(size2 + 1)} + + for i in 0..size1 + for j in 0..size2 + if (i == 0 || j == 0) + lcs[i][j] = 0 + # when the last character of both subsequences match, + # increase length of lcs by 1 + elsif (arr1[i - 1] == arr2[j - 1]) + lcs[i][j] = lcs[i - 1][j - 1] + 1 + # when the last character is not same, + # take maximum obtained by adding + # one character to one of the subsequences + else + lcs[i][j] = [lcs[i - 1][j], lcs[i][j - 1]].max + end + end + end + + lcs[size1][size2] +end + +# Driver Code +puts "Enter the size of first array:" +size1 = gets.to_i + +puts "Enter the first array elements:" +arr1 = gets.split(" ").map(&:to_i) + +puts "Enter the size of second array:" +size2 = gets.to_i + +puts "Enter the second array elements:" +arr2 = gets.split(" ").map(&:to_i) + +len = longest_common_subsequence(arr1, arr2, size1, size2) +puts "Length of Longest Common Subsequence is: #{len}" + +=begin +Enter the size of first array: +7 +Enter the first array elements: +10 15 20 25 30 35 40 +Enter the size of second array: +8 +Enter the second array elements: +10 12 23 25 28 30 32 40 +Length of Longest Common Subsequence is: 4 +=end diff --git a/Longest_Increasing_Subsequence/LIS.go b/Longest_Increasing_Subsequence/LIS.go new file mode 100644 index 000000000..ee84d0246 --- /dev/null +++ b/Longest_Increasing_Subsequence/LIS.go @@ -0,0 +1,67 @@ +/* Problem Statement : +To find the length of the Longest Increasing +Subsequence of a given sequence, that is all the +elements of the subsequence are in increasing sorted order. +*/ +package main + +import "fmt" + +func Max(lis []int) (max int) { + max = lis[0] + for i := 1; i < len(lis); i++ { + if lis[i] > max { + max = lis[i] + } + } + return +} + +func LIS(arr []int) { + length := len(arr) + + if length == 0 { + return + } + + // Slice to store the length of the LIS til some index + lis_arr := make([]int, length) + lis_arr[0] = 1 + + for i := 1; i < length; i++ { + lis_arr[i] = 1 + + // Computing LIS value in DP Bottom-up + for j := 0; j < i; j++ { + if ( arr[i] > arr[j] && lis_arr[i] < lis_arr[j] + 1) { + lis_arr[i] = lis_arr[j] + 1 + } + } + } + + fmt.Printf("Length of the Longest Increasing Subsequence : %d\n", Max(lis_arr)) +} + +func main() { + var n int + fmt.Println("Enter the size of the array : ") + fmt.Scan(&n) + fmt.Println("Enter the array elements : ") + arr := make([]int, n) + + for i := 0; i < n; i++ { + fmt.Scan(&arr[i]) + } + + LIS(arr) +} + +/* Sample Input : +Enter the size of the array : +8 +Enter the array elements : +15 26 13 38 26 52 43 62 + +Sample Output : +Length of the Longest Increasing Subsequence : 5 +*/ diff --git a/Longest_Increasing_Subsequence/LIS.java b/Longest_Increasing_Subsequence/LIS.java new file mode 100644 index 000000000..fb525d0a2 --- /dev/null +++ b/Longest_Increasing_Subsequence/LIS.java @@ -0,0 +1,54 @@ +/* +Problem Statement : +To find the length of the Longest Increasing +Subsequence of a given sequence, that is all the +elements of the subsequence are in increasing sorted order. +*/ + +import java.util.*; + +class LIS +{ + static int lis(int arr[], int n) + { + int lis[] = new int[n]; + int result = Integer.MIN_VALUE; + + for (int i = 0; i < n; ++i) + lis[i] = 1; + + for (int i = 1; i < n; ++i) + { + for (int j = 0; j < i; ++j) + { + if (arr[i] > arr[j] && lis[i] < lis[j] + 1) + lis[i] = lis[j] + 1; + } + result = Math.max(result, lis[i]); + } + + return result; + } + + public static void main(String args[]) + { + Scanner sc = new Scanner(System.in); + + System.out.print("Enter the size of array : "); + int n = sc.nextInt(); + + int[] arr = new int[n]; + System.out.print("Enter the array elements : "); + for (int i = 0; i < n; ++i) + arr[i] = sc.nextInt(); + + System.out.println("\nLength of the Longest Increasing Subsequence : " + lis(arr, n)); + } +} + +/* +Enter the size of the array : 8 +Enter the array elements : 15 26 13 38 26 52 43 62 + +Length of the Longest Increasing Subsequence : 5 +*/ diff --git a/Longest_Increasing_Subsequence/LIS.php b/Longest_Increasing_Subsequence/LIS.php new file mode 100644 index 000000000..2554faaf1 --- /dev/null +++ b/Longest_Increasing_Subsequence/LIS.php @@ -0,0 +1,43 @@ + $arr[$j] && $dp[$i] < $dp[$j] + 1) + $dp[$i] = $dp[$j] + 1; + } + + // find the max out of computed lengths of LIS + // ending at different indices + $max = PHP_INT_MIN; + for($i = 0; $i < $n; $i++){ + if($max < $dp[$i]) + $max = $dp[$i]; + } + + return $max; +} + +// Sample test case +$arr = array(3, 10, 2, 1, 20, 40, 60, 7); +$n = sizeof($arr); + +echo "Length of LIS is " , lisLen($arr, $n); + +/* +Sample Input as specified in the code: +3, 10, 2, 1, 20, 40, 60, 7 + +Sample Output: +Length of LIS is 5 +*/ + +?> diff --git a/Longest_Increasing_Subsequence/Longest_Increasing_Subsequence.kt b/Longest_Increasing_Subsequence/Longest_Increasing_Subsequence.kt new file mode 100644 index 000000000..c10c8c24f --- /dev/null +++ b/Longest_Increasing_Subsequence/Longest_Increasing_Subsequence.kt @@ -0,0 +1,52 @@ +//Kotlin code for Longest increasing subsequence + +class LIS +{ + fun lis(int:arr[], int:n):int + { + int lis[] = new int[n]; + int result = Integer.MIN_VALUE; + + for (i in 0 until n) + { + lis[i] = 1; + } + + for (i in 1 until n) + { + for (j in 0 until i) + { + if (arr[i] > arr[j] && lis[i] < lis[j] + 1) + { + lis[i] = lis[j] + 1; + } + } + result = Math.max(result, lis[i]); + } + return result; + } + + fun main() + { + var read = Scanner(System.`in`) + println("Enter the size of the Array:") + val arrSize = read.nextLine().toInt() + var arr = IntArray(arrSize) + println("Enter elements") + + for(i in 0 until arrSize) + { + arr[i] = read.nextLine().toInt() + } + + int n = arrSize; + println("\nLength of the Longest Increasing Subsequence:" + lis(arr, n)) + } +} + +/* +Enter the size of the array : 8 +Enter elements : 15 26 13 38 26 52 43 62 +Length of the Longest Increasing Subsequence : 5 +*/ + diff --git a/Longest_Increasing_Subsequence/README.md b/Longest_Increasing_Subsequence/README.md new file mode 100644 index 000000000..3d1c08af7 --- /dev/null +++ b/Longest_Increasing_Subsequence/README.md @@ -0,0 +1,73 @@ +# Longest Increasing Subsequence + +The Longest Increasing Subsequence (LIS) problem is to find the length of the longest subsequence of a given sequence such that all elements of the subsequence are sorted in increasing order. For example, the length of LIS for `{10, 22, 9, 33, 21, 50, 41, 60, 80}` is `6` and LIS is `{10, 22, 33, 50, 60, 80}`. + +![longest-increasing-subsequence](https://media.geeksforgeeks.org/wp-content/cdn-uploads/Longest-Increasing-Subsequence.png) + +## Examples + +``` +Input : arr[] = {3, 10, 2, 1, 20} +Output : Length of LIS = 3 +The longest increasing subsequence is 3, 10, 20 + +Input : arr[] = {3, 2} +Output : Length of LIS = 1 +The longest increasing subsequences are {3} and {2} + +Input : arr[] = {50, 3, 10, 7, 40, 80} +Output : Length of LIS = 4 +The longest increasing subsequence is {3, 7, 40, 80} +``` + +## Recursive Approach + +``` +Let arr[0..n-1] be the input array and L(i) be the length of the LIS ending at index i such that arr[i] is the last element of the LIS. + +Then, L(i) can be recursively written as: + +L(i) = 1 + max( L(j) ) where 0 < j < i and arr[j] < arr[i]; or +L(i) = 1, if no such j exists. + +To find the LIS for a given array, we need to return max(L(i)) where 0 < i < n. + +Thus, we see the LIS problem satisfies the optimal substructure property as the main problem can be solved using solutions to subproblems. +``` + +## Pseudo Code + +``` +LIS(A[1..n]): + Array L[1..n] + (* L[i] = value of LIS ending(A[1..i]) *) + for i = 1 to n do + L[i] = 1 + for j = 1 to i − 1 do + if (A[j] < A[i]) do + L[i] = max(L[i], 1 + L[j]) + return L + +MAIN(A[1..n]): + L = LIS(A[1..n]) + return the maximum value in L +``` + +## Overlapping Subproblems: + +Considering the above implementation, following is recursion tree for an array of size 4. lis(n) gives us the length of LIS for arr[]. + +``` + lis(4) + / | \ + lis(3) lis(2) lis(1) + / \ | + lis(2) lis(1) lis(1) + / +lis(1) +``` + + +# Time Complexity + +O ( n 2 ) \ No newline at end of file diff --git a/Machine_Learning/K_Nearest_Neighbours/K_Nearest_Neighbors.cpp b/Machine_Learning/K_Nearest_Neighbours/K_Nearest_Neighbors.cpp new file mode 100644 index 000000000..296a0ed85 --- /dev/null +++ b/Machine_Learning/K_Nearest_Neighbours/K_Nearest_Neighbors.cpp @@ -0,0 +1,111 @@ +#include +using namespace std; + +struct point { + float w, x, y, z; // w, x, y and z are the values of the dataset + float distance; // distance will store the distance of dataset point from the unknown test point + int op; // op will store the class of the point +}; + +int main() { + int i, j, n, k; + struct point p; + struct point temp; + cout << "Number of data points: "; + cin >> n; + struct point arr[n]; + cout << "\nEnter the dataset values: \n"; + cout << "w\tx\ty\tz\top\n"; + + // Taking dataset + for (i = 0; i < n; i++) { + cin >> arr[i].w >> arr[i].x >> arr[i].y >> arr[i].z >> arr[i].op; + } + + cout << "\nw\tx\ty\tz\top\n"; + + for (i = 0; i < n; i++) { + cout << fixed << setprecision(2) << arr[i].w << '\t' << arr[i].x << '\t' << arr[i].y << '\t' << arr[i].z << '\t' << arr[i].op << '\n'; + } + + cout << "\nEnter the feature values of the unknown point: \nw\tx\ty\tz\n"; + cin >> p.w >> p.x >> p.y >> p.z; + + // Measuring the Euclidean distance + for (i = 0; i < n; i++) { + arr[i].distance = sqrt(((arr[i].w - p.w) * (arr[i].w - p.w)) + ((arr[i].x - p.x) * (arr[i].x - p.x)) + ((arr[i].y - p.y) * (arr[i].y - p.y)) + ((arr[i].z - p.z) * (arr[i].z - p.z))); + } + + // Sorting the training data with respect to distance + for (i = 1; i < n; i++) { + for (j = 0; j < n - i; j++) { + if (arr[j].distance > arr[j + 1].distance) { + temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + } + } + + cout << "\nw\tx\ty\tz\top\tdistance\n"; + for (i = 0; i < n; i++) { + cout << fixed << setprecision(2) << arr[i].w << '\t' << arr[i].x << '\t' << arr[i].y << '\t' << arr[i].z << '\t' << arr[i].op << '\t' << arr[i].distance << '\n'; + } + + // Taking the K nearest neighbors + cout << "\nNumber of nearest neighbors(k): "; + cin >> k; + + int freq[1000] = {0}; + int index = 0, maxfreq = 0; + + // Creating frequency array of the class of k nearest neighbors + for (int i = 0; i < k; i++) { + freq[arr[i].op]++; + } + + // Finding the most frequent occurring class + for (int i = 0; i < 1000; i++) { + if(freq[i] > maxfreq) { + maxfreq = freq[i]; + index = i; + } + } + + cout << "The class of unknown point is " << index; + return 0; +} + +// Sample Output +/* +Number of data points: 5 + +Enter the dataset values: +w x y z op +1 2 3 4 5 +10 20 30 40 50 +5 2 40 7 10 +40 30 100 28 3 +20 57 98 46 8 + +w x y z op +1.00 2.00 3.00 4.00 5 +10.00 20.00 30.00 40.00 50 +5.00 2.00 40.00 7.00 10 +40.00 30.00 100.00 28.00 3 +20.00 57.00 98.00 46.00 8 + +Enter the feature values of the unknown point: +w x y z +40 30 80 30 + +w x y z op distance +40.00 30.00 100.00 28.00 3 20.10 +20.00 57.00 98.00 46.00 8 41.34 +10.00 20.00 30.00 40.00 50 60.00 +5.00 2.00 40.00 7.00 10 64.33 +1.00 2.00 3.00 4.00 5 94.39 + +Number of nearest neighbors(k): 3 +The class of unknown point is 3 +*/ diff --git a/Machine_Learning/K_Nearest_Neighbours/K_Nearest_Neighbours.c b/Machine_Learning/K_Nearest_Neighbours/K_Nearest_Neighbours.c new file mode 100644 index 000000000..ce0f639d3 --- /dev/null +++ b/Machine_Learning/K_Nearest_Neighbours/K_Nearest_Neighbours.c @@ -0,0 +1,117 @@ +#include +#include +#include + +typedef struct point{ + float w, x, y, z; // features or co-ordinates of the point + float distance; // Distance from test point + int op; // label of the point +}point; + +int main() { + int i, j, n, k; + point p; + point temp; + printf("Number of data points: "); + scanf("%d", &n); + point arr[n]; + printf("\nEnter the dataset values: \n"); + printf("w\tx\ty\tz\top\n"); + + // Taking input data + for (i = 0; i < n; i++) { + scanf("%f%f%f%f%d", &arr[i].w, &arr[i].x, &arr[i].y, &arr[i].z, &arr[i].op); + } + printf("w\tx\ty\tz\top\n"); + for (i = 0; i < n; i++) { + printf("%.2f\t%.2f\t%.2f\t%.2f\t%d\n", arr[i].w, arr[i].x, arr[i].y, arr[i].z, arr[i].op); + } + + // Taking the feature values or co-ordinates of the unknown data point + printf("\nEnter the feature values of the unkown point: \nw\tx\ty\tz\n"); + scanf("%f%f%f%f", &p.w, &p.x, &p.y, &p.z); + + // Measuring the Euclidean distances + for (i = 0; i < n; i++) { + arr[i].distance = sqrt((arr[i].w - p.w) * (arr[i].w - p.w) + (arr[i].x - p.x) * (arr[i].x - p.x) + (arr[i].y - p.y) * (arr[i].y - p.y) + (arr[i].z - p.z) * (arr[i].z - p.z)); + } + + //Sorintg the training data with resptect to the Euclidean distances + for (i = 1; i < n; i++) { + for (j = 0; j < n - i; j++) { + if (arr[j].distance > arr[j + 1].distance) { + temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + } + } + printf("w\tx\ty\tz\top\tdistance\n"); + for (i = 0; i < n; i++) { + printf("%.2f\t%.2f\t%.2f\t%.2f\t%d\t%.2f\n", arr[i].w, arr[i].x, arr[i].y, arr[i].z, arr[i].op, arr[i].distance); + } + + // Taking the K -nearest neighbors + printf("\nNumber of nearest neighbors(k): "); // Value of K + scanf("%d", &k); + + // Measuring the frequencies of each label in K nearest neighbors' data + int freq1 = 0; // for label 1 + int freq2 = 0; // for label 2 + int freq3 = 0; // for label 3 + int none = 0; + for (i = 0; i < k; i++) { + if (arr[i].op == 1) + freq1++; + else if (arr[i].op == 2) + freq2++; + else if(arr[i].op == 3) + freq3++; + else + none++; + } + + // Printing the label of the unknown data + if(freq1 >= freq2 && freq1 >= freq3) { + printf("\nThe class of unknown point is: 1"); + } + else if(freq2 >= freq1 && freq2 >= freq3 ) { + printf("\nThe class of unknown point is: 2"); + } + else { + printf("\nThe class of unknown point is: 3"); + } +} + +/*Sample Input and Output: +------------------------ +Number of data points: 5 + +Enter the dataset values: +w x y z op +1 2 4 3 1 +1 3 2 1 1 +8 7 6 9 2 +7 8 6 9 2 +6 9 7 5 2 +w x y z op +1.00 2.00 4.00 3.00 1 +1.00 3.00 2.00 1.00 1 +8.00 7.00 6.00 9.00 2 +7.00 8.00 6.00 9.00 2 +6.00 9.00 7.00 5.00 2 + +Enter the feature values of the unkown point: +w x y z +8 7 5 9 +w x y z op distance +8.00 7.00 6.00 9.00 2 1.00 +7.00 8.00 6.00 9.00 2 1.73 +6.00 9.00 7.00 5.00 2 5.29 +1.00 2.00 4.00 3.00 1 10.54 +1.00 3.00 2.00 1.00 1 11.75 + +Number of nearest neighbors(k): 2 + +The class of unknown point is: 2 +*/ diff --git a/Machine_Learning/Logistic_Regression/Logistic_Regression.ipynb b/Machine_Learning/Logistic_Regression/Logistic_Regression.ipynb new file mode 100644 index 000000000..669cfdb7f --- /dev/null +++ b/Machine_Learning/Logistic_Regression/Logistic_Regression.ipynb @@ -0,0 +1,418 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import pandas as pd\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "plt.style.use('seaborn')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(500, 2)\n", + "(500, 2)\n" + ] + } + ], + "source": [ + "mean_01 = np.array([1,0.5])\n", + "cov_01 = np.array([[1,0.1],[0.1,1.2]])\n", + "\n", + "mean_02 = np.array([4,5])\n", + "cov_02 = np.array([[1.21,0.1],[0.1,1.3]])\n", + "\n", + "\n", + "# Normal Distribution\n", + "dist_01 = np.random.multivariate_normal(mean_01,cov_01,500)\n", + "dist_02 = np.random.multivariate_normal(mean_02,cov_02,500)\n", + "\n", + "print(dist_01.shape)\n", + "print(dist_02.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(0)\n", + "\n", + "plt.scatter(dist_01[:,0],dist_01[:,1],label='Class 0')\n", + "plt.scatter(dist_02[:,0],dist_02[:,1],color='r',marker='^',label='Class 1')\n", + "plt.xlim(-5,10)\n", + "plt.ylim(-5,10)\n", + "plt.xlabel('x1')\n", + "plt.ylabel('x2')\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(500, 1)\n", + "(500, 1)\n", + "(1000, 3)\n" + ] + } + ], + "source": [ + "y1 = np.zeros((500,1))\n", + "print(y1.shape)\n", + "\n", + "y2 = np.ones((500,1))\n", + "print(y2.shape)\n", + "\n", + "data1 = np.hstack((dist_01,y1))\n", + "data2 = np.hstack((dist_02,y2))\n", + "data = np.vstack((data1,data2))\n", + "\n", + "print(data.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 4.61546313 2.66193635 1. ]\n", + " [ 4.14312954 4.21854945 1. ]\n", + " [ 3.5360558 5.44785463 1. ]\n", + " [-0.30283189 1.49333376 0. ]\n", + " [ 3.78745303 6.42600424 1. ]\n", + " [ 1.88347777 4.75120101 1. ]\n", + " [ 4.62331128 4.57041199 1. ]\n", + " [ 3.25889833 6.95708425 1. ]\n", + " [ 0.8891156 -1.34359916 0. ]\n", + " [ 3.17329477 3.51864788 1. ]]\n" + ] + } + ], + "source": [ + "np.random.shuffle(data)\n", + "print(data[:10])" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "split = int(0.8*data.shape[0])" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(800, 2) (200, 2)\n", + "(800,) (200,)\n" + ] + } + ], + "source": [ + "X_train = data[:split,:-1]\n", + "X_test = data[split:,:-1]\n", + "\n", + "Y_train = data[:split,-1]\n", + "Y_test = data[split:,-1]\n", + "\n", + "print(X_train.shape,X_test.shape)\n", + "print(Y_train.shape,Y_test.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "def hypothesis(x,w,b):\n", + " '''accepts input vector x, input weight vector w and bias b'''\n", + " \n", + " h = np.dot(x,w) + b\n", + " return sigmoid(h)\n", + "\n", + "def sigmoid(z):\n", + " return 1.0/(1.0 + np.exp(-1.0*z))\n", + "\n", + "def error(y_true,x,w,b):\n", + " \n", + " m = x.shape[0]\n", + " \n", + " err = 0.0\n", + " \n", + " for i in range(m):\n", + " hx = hypothesis(x[i],w,b) \n", + " err += y_true[i]*np.log2(hx) + (1-y_true[i])*np.log2(1-hx)\n", + " \n", + " \n", + " return -err/m\n", + "\n", + "\n", + "def get_grads(y_true,x,w,b):\n", + " \n", + " grad_w = np.zeros(w.shape)\n", + " grad_b = 0.0\n", + " \n", + " m = x.shape[0]\n", + " \n", + " for i in range(m):\n", + " hx = hypothesis(x[i],w,b)\n", + " \n", + " grad_w += -1*(y_true[i] - hx)*x[i]\n", + " grad_b += -1*(y_true[i]-hx)\n", + " \n", + " \n", + " grad_w /= m\n", + " grad_b /= m\n", + " \n", + " return [grad_w,grad_b] #returning python list\n", + "\n", + "\n", + "# One Iteration of Gradient Descent\n", + "def grad_descent(x,y_true,w,b,learning_rate=0.1):\n", + " \n", + " err = error(y_true,x,w,b)\n", + " [grad_w,grad_b] = get_grads(y_true,x,w,b)\n", + " \n", + " w = w - learning_rate*grad_w\n", + " b = b - learning_rate*grad_b\n", + " \n", + " return err,w,b\n", + " \n", + "def predict(x,w,b):\n", + " \n", + " confidence = hypothesis(x,w,b)\n", + " if confidence<0.5:\n", + " return 0\n", + " else:\n", + " return 1\n", + " \n", + "def accuracy(x_tst,y_tst,w,b):\n", + " \n", + " y_pred = []\n", + " \n", + " for i in range(y_tst.shape[0]):\n", + " p = predict(x_tst[i],w,b)\n", + " y_pred.append(p)\n", + " \n", + " y_pred = np.array(y_pred)\n", + " \n", + " return float((y_pred==y_tst).sum())/y_tst.shape[0]\n", + " \n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "loss = []\n", + "acc = []\n", + "\n", + "W = 2*np.random.random((X_train.shape[1],))\n", + "b = 5*np.random.random()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "for i in range(300):\n", + " l,W,b = grad_descent(X_train,Y_train,W,b,learning_rate=0.5)\n", + " acc.append(accuracy(X_test,Y_test,W,b))\n", + " loss.append(l)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(loss)\n", + "plt.ylabel(\"negative of log likelihood\")\n", + "plt.xlabel(\"epoch\")\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.98\n" + ] + } + ], + "source": [ + "plt.plot(acc)\n", + "plt.ylabel(\"accuracy\")\n", + "plt.xlabel(\"epoch\")\n", + "plt.show()\n", + "print(acc[-1])" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(0)\n", + "\n", + "plt.scatter(dist_01[:,0],dist_01[:,1],label='Class 0')\n", + "plt.scatter(dist_02[:,0],dist_02[:,1],color='r',marker='^',label='Class 1')\n", + "plt.xlim(-5,10)\n", + "plt.ylim(-5,10)\n", + "plt.xlabel('x1')\n", + "plt.ylabel('x2')\n", + "\n", + "x = np.linspace(-4,8,10)\n", + "y = -(W[0]*x + b)/W[1]\n", + "plt.plot(x,y,color='k')\n", + "\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0.76604691 1.49267387]\n", + "-5.424920453033558\n" + ] + } + ], + "source": [ + "print(W)\n", + "print(b)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Matrix_Operations/Java/Matrix_Addition.java b/Matrix_Operations/Java/Matrix_Addition.java new file mode 100644 index 000000000..63c9d71ed --- /dev/null +++ b/Matrix_Operations/Java/Matrix_Addition.java @@ -0,0 +1,108 @@ +// Java Program to calculation sum of 2 matrices (2D Array) +import java.util.*; + +public class Matrix_Addition { + // Find sum of 2 Matrices and store it in matrix3 + public static void add_matrices(int[][] matrix1, int[][] matrix2) { + + int index1, index2 = 0; + int[][] matrix3 = new int[matrix1.length][matrix1[0].length]; + + for ( index1 = 0; index1 < matrix1.length ; index1 ++) { + for ( index2 = 0; index2 < matrix1[0].length; index2++ ) { + matrix3[index1][index2] = matrix1[index1][index2] + matrix2[index1][index2]; + } + } + + // Print the calculated matrix + for ( index1 = 0; index1 < matrix3.length ; index1 ++) { + for ( index2 = 0; index2 < matrix3[0].length; index2++ ) { + System.out.print( matrix3[index1][index2] + " "); + } + System.out.println(); + } + } + + public static void main(String args[]) { + Scanner s = new Scanner(System.in); + + System.out.println("Of First Matrix"); + System.out.println(" Enter number of rows "); + int rows_first = s.nextInt(); + + System.out.println(" Enter number of columns "); + int columns_first = s.nextInt(); + int[][] matrix1 = new int[rows_first][columns_first]; + + System.out.println("Of Second Matrix"); + System.out.println(" Enter number of rows "); + int rows_second = s.nextInt(); + + System.out.println(" Enter number of columns "); + int columns_second = s.nextInt(); + int[][] matrix2 = new int[rows_second][columns_second]; + + if (columns_first != columns_second || rows_first != rows_second) { + System.out.println(" Addition of matrix is not possible "); + } + else { + + System.out.println(" Enter elements of 1st matrix "); + for (int i = 0 ; i < rows_first; i++) { + for (int j = 0 ; j< columns_first; j++) { + matrix1[i][j] = s.nextInt(); + } + } + + System.out.println(" Enter elements of 2nd matrix "); + for (int i = 0 ; i < rows_first; i++) { + for (int j = 0 ; j< columns_first; j++) { + matrix2[i][j] = s.nextInt(); + } + } + add_matrices(matrix1, matrix2); + } + } +} + +/* +TEST CASES +INPUT +Of First Matrix +Enter number of rows +2 +Enter number of columns +3 +Of Second Matrix +Enter number of rows +2 +Enter number of columns +4 +OUTPUT +Addition of matrix is not possible +INPUT +Of First Matrix +Enter number of rows +2 +Enter number of columns +2 +Of Second Matrix +Enter number of rows +2 +Enter number of columns +2 +Enter elements of 1st matrix +1 +2 +3 +4 +Enter elements of 2nd matrix +1 +1 +1 +1 +OUTPUT +2 3 +4 5 +*/ + diff --git a/Matrix_Operations/Java/Matrix_Subtraction.java b/Matrix_Operations/Java/Matrix_Subtraction.java new file mode 100644 index 000000000..ab1419281 --- /dev/null +++ b/Matrix_Operations/Java/Matrix_Subtraction.java @@ -0,0 +1,90 @@ +// Java Program to calculation subtraction of 2 matrices (2D Array) +import java.util.*; + +public class Matrix_Subtraction { + + // Find subtraction of 2 Matrices and store it in matrix3 + public static void subtract_matrices(int[][] matrix1, int[][] matrix2){ + int index1, index2 = 0; + int[][] matrix3 = new int[matrix1.length][matrix1[0].length]; + for ( index1 = 0; index1 < matrix1.length; index1++ ){ + for ( index2 = 0; index2 < matrix1[0].length; index2++ ){ + matrix3[index1][index2] = matrix1[index1][index2] - matrix2[index1][index2]; + } + } + + // Print the calculated matrix + for ( index1 = 0; index1 < matrix3.length; index1++ ){ + for ( index2 = 0; index2 < matrix3[0].length; index2++ ){ + System.out.print( matrix3[index1][index2] + " "); + } + System.out.println(); + } + } + + public static void main(String args[]){ + Scanner s = new Scanner(System.in); + + System.out.println("Of First Matrix"); + System.out.println(" Enter number of rows "); + int rows_first = s.nextInt(); + + System.out.println(" Enter number of columns "); + int columns_first = s.nextInt(); + int[][] matrix1 = new int[rows_first][columns_first]; + + System.out.println("Of Second Matrix"); + System.out.println(" Enter number of rows "); + int rows_second = s.nextInt(); + + System.out.println(" Enter number of columns "); + int columns_second = s.nextInt(); + int[][] matrix2 = new int[rows_second][columns_second]; + + if (columns_first != columns_second || rows_first != rows_second) { + System.out.println(" Subtraction of matrix is not possible "); + } + else { + + System.out.println(" Enter elements of 1st matrix "); + for (int i = 0 ; i < rows_first; i++) { + for (int j = 0 ; j < columns_first; j++) { + matrix1[i][j] = s.nextInt(); + } + } + + System.out.println(" Enter elements of 2nd matrix "); + for (int i = 0 ; i < rows_first; i++) { + for (int j = 0 ; j < columns_first; j++) { + matrix2[i][j] = s.nextInt(); + } + } + subtract_matrices(matrix1, matrix2); + } + } +} + +/* +TEST CASES + +INPUT +Of First Matrix + Enter number of rows +1 + Enter number of columns +2 +Of Second Matrix + Enter number of rows +1 + Enter number of columns +2 + Enter elements of 1st matrix +3 +4 + Enter elements of 2nd matrix +1 +3 + +OUTPUT +2 1 +*/ diff --git a/Matrix_Operations/Java/Matrix_identical.java b/Matrix_Operations/Java/Matrix_identical.java new file mode 100644 index 000000000..03028e617 --- /dev/null +++ b/Matrix_Operations/Java/Matrix_identical.java @@ -0,0 +1,104 @@ +// Java Program to check and find if two matrices are identical or not +import java.util.Scanner; + +public class Matrix_identical { + + // This function return true if the matrices are identical otherwise false + public static boolean check_identical(int[][] matrix1, int[][] matrix2){ + int index1, index2 = 0; + for ( index1 = 0; index1 < matrix1.length; index1++ ){ + for ( index2 = 0; index2 < matrix1[0].length; index2++ ){ + if (matrix1[index1][index2] != matrix2[index1][index2]) { + return false; + } + } + } + return true; + } + + public static void main(String args[]){ + Scanner s = new Scanner(System.in); + + System.out.println("Of First Matrix"); + System.out.println(" Enter number of rows "); + int rows_first = s.nextInt(); + + System.out.println(" Enter number of columns "); + int columns_first = s.nextInt(); + int[][] matrix1 = new int[rows_first][columns_first]; + + System.out.println("Of Second Matrix"); + System.out.println(" Enter number of rows "); + int rows_second = s.nextInt(); + + System.out.println(" Enter number of columns "); + int columns_second = s.nextInt(); + int[][] matrix2 = new int[rows_second][columns_second]; + + if (columns_first != columns_second || rows_first != rows_second) { + System.out.println(" Matrices's order is not identical "); + } + else { + + System.out.println(" Enter elements of 1st matrix "); + for (int i = 0; i < rows_first; i++) { + for (int j = 0; j < columns_first; j++) { + matrix1[i][j] = s.nextInt(); + } + } + + System.out.println(" Enter elements of 2nd matrix "); + for (int i = 0; i < rows_first; i++) { + for (int j = 0; j < columns_first; j++) { + matrix2[i][j] = s.nextInt(); + } + } + boolean b = check_identical(matrix1, matrix2); + if (b) System.out.println("Matrices are identical"); + else System.out.println(" Matrices are not identical"); + } + } +} +/* +TEST CASES +INPUT +Of First Matrix + Enter number of rows +2 + Enter number of columns +2 +Of Second Matrix + Enter number of rows +2 + Enter number of columns +2 + Enter elements of 1st matrix +1 2 +0 4 + Enter elements of 2nd matrix +1 2 +7 6 +OUTPUT + Matrices are not identical + +INPUT +Of First Matrix + Enter number of rows +2 + Enter number of columns +2 +Of Second Matrix + Enter number of rows +2 + Enter number of columns +2 + Enter elements of 1st matrix +1 2 +0 4 + Enter elements of 2nd matrix +1 2 +0 4 +OUTPUT + Matrices are identical +*/ + diff --git a/Matrix_Operations/Java/Matrix_intersection.java b/Matrix_Operations/Java/Matrix_intersection.java new file mode 100644 index 000000000..d4d077c79 --- /dev/null +++ b/Matrix_Operations/Java/Matrix_intersection.java @@ -0,0 +1,90 @@ +// Java Program to check where the elements of matrix are different and replacing them with a character +import java.util.Scanner; + +public class Matrix_intersection { + + //Finding the elements which are different in both the matrices and replacing it with a char + public static void check_intersection(int[][] matrix1, int[][] matrix2, String character){ + int index1, index2 = 0; + for ( index1 = 0; index1 < matrix1.length; index1++) { + for ( index2 = 0; index2 < matrix1[0].length; index2++) { + if (matrix1[index1][index2] != matrix2[index1][index2]) { + System.out.print(character + " "); + } + else{ + System.out.print(matrix1[index1][index2] + " "); + } + } + System.out.println(); + } + } + + public static void main(String args[]){ + Scanner s = new Scanner(System.in); + + System.out.println("Of First Matrix"); + System.out.println(" Enter number of rows "); + int rows_first = s.nextInt(); + + System.out.println(" Enter number of columns "); + int columns_first = s.nextInt(); + int[][] matrix1 = new int[rows_first][columns_first]; + + System.out.println("Of Second Matrix"); + System.out.println(" Enter number of rows "); + int rows_second = s.nextInt(); + + System.out.println(" Enter number of columns "); + int columns_second = s.nextInt(); + int[][] matrix2 = new int[rows_second][columns_second]; + + if (columns_first != columns_second || rows_first != rows_second) { + System.out.println(" Matrices's order is not same "); + } + else { + + System.out.println(" Enter elements of 1st matrix "); + for (int i = 0; i < rows_first; i++) { + for (int j = 0; j < columns_first; j++) { + matrix1[i][j] = s.nextInt(); + } + } + + System.out.println(" Enter elements of 2nd matrix "); + for (int i = 0; i < rows_first; i++) { + for (int j = 0; j < columns_first; j++) { + matrix2[i][j] = s.nextInt(); + } + } + System.out.println("Enter character to replace"); + String character = s.next(); + check_intersection(matrix1, matrix2, character); + } + } +} +/* +TEST CASES +INPUT +OOf First Matrix + Enter number of rows +2 + Enter number of columns +2 +Of Second Matrix + Enter number of rows +2 + Enter number of columns +2 + Enter elements of 1st matrix +4 0 +1 2 + Enter elements of 2nd matrix +4 9 +3 2 +Enter character to replace +% +OUTPUT +4 % +% 2 +*/ + diff --git a/Matrix_Operations/Java/Matrix_multiply.java b/Matrix_Operations/Java/Matrix_multiply.java new file mode 100644 index 000000000..94260cbd6 --- /dev/null +++ b/Matrix_Operations/Java/Matrix_multiply.java @@ -0,0 +1,109 @@ +// Java Program to calculation multiplication of 2 matrices (2D Array) +import java.util.*; + +public class Matrix_Multiplication { + // Find multiplication of 2 Matrices and store it in matrix3 + public static void multiply_matrices(int[][] matrix1, int[][] matrix2) { + + int index1, index2, index3; + int[][] matrix3 = new int[matrix1.length][matrix1[0].length]; + + for ( index1 = 0; index1 < matrix1.length; index1++) { + for ( index2 = 0; index2 < matrix2[0].length; index2++) { + matrix3[index1][index2] = 0; + for ( index3 = 0; index3 < matrix1.length; index3++){ + matrix3[index1][index2] += matrix1[index1][index3] * matrix2[index3][index2]; + } + } + } + // Print the calculated matrix + for ( index1 = 0; index1 < matrix3.length; index1++) { + for ( index2 = 0; index2 < matrix3[0].length; index2++) { + System.out.print( matrix3[index1][index2] + " "); + } + System.out.println(); + } + } + + public static void main(String args[]) { + Scanner s = new Scanner(System.in); + + System.out.println("Of First Matrix"); + System.out.println(" Enter number of rows "); + int rows_first = s.nextInt(); + + System.out.println(" Enter number of columns "); + int columns_first = s.nextInt(); + int[][] matrix1 = new int[rows_first][columns_first]; + + System.out.println("Of Second Matrix"); + System.out.println(" Enter number of rows "); + int rows_second = s.nextInt(); + + System.out.println(" Enter number of columns "); + int columns_second = s.nextInt(); + int[][] matrix2 = new int[rows_second][columns_second]; + + if (columns_first != rows_second) { + System.out.println(" Multiplication of matrix is not possible "); + } + else { + + System.out.println(" Enter elements of 1st matrix "); + for (int i = 0; i < rows_first; i++) { + for (int j = 0; j < columns_first; j++) { + matrix1[i][j] = s.nextInt(); + } + } + + System.out.println(" Enter elements of 2nd matrix "); + for (int i = 0; i < rows_first; i++) { + for (int j = 0; j < columns_first; j++) { + matrix2[i][j] = s.nextInt(); + } + } + multiply_matrices(matrix1, matrix2); + } + } +} +/* +TEST CASE + +INPUT +Of First Matrix + Enter number of rows +1 + Enter number of columns +2 +Of Second Matrix + Enter number of rows +1 + Enter number of columns +3 + +OUTPUT + Multiplication of matrix is not possible + +INPUT +Of First Matrix + Enter number of rows +2 + Enter number of columns +2 +Of Second Matrix + Enter number of rows +2 + Enter number of columns +2 + Enter elements of 1st matrix +1 2 +3 4 + Enter elements of 2nd matrix +1 1 +1 1 + +OUTPUT +3 3 +7 7 +*/ + diff --git a/Matrix_Operations/Java/Matrix_transpose.java b/Matrix_Operations/Java/Matrix_transpose.java new file mode 100644 index 000000000..f24dacd1d --- /dev/null +++ b/Matrix_Operations/Java/Matrix_transpose.java @@ -0,0 +1,63 @@ +// Java Program to calculation transpose of a matrix (2D Array) +import java.util.Scanner; + +public class Matrix_transpose { + + // Find transpose of matrix + public static void transpose_matrices(int[][] matrix) { + + int index1, index2; + int[][] matrix_ans = new int[matrix.length][matrix[0].length]; + for ( index1 = 0; index1 < matrix.length; index1 ++) { + for ( index2 = 0; index2 < matrix[0].length; index2++ ) { + matrix_ans[index2][index1] = matrix[index1][index2]; + } + } + + // Print the calculated matrix + for ( index1 = 0; index1 < matrix_ans.length; index1 ++) { + for ( index2 = 0; index2 < matrix_ans[0].length; index2++ ) { + System.out.print( matrix_ans[index1][index2] + " "); + } + System.out.println(); + } + } + + public static void main(String args[]) { + Scanner s = new Scanner(System.in); + + System.out.println(" Enter number of rows "); + int rows = s.nextInt(); + + System.out.println(" Enter number of columns "); + int columns = s.nextInt(); + int[][] matrix = new int[rows][columns]; + + + System.out.println(" Enter elements of matrix "); + for (int i = 0; i < rows; i++) { + for (int j = 0 ; j < columns; j++) { + matrix[i][j] = s.nextInt(); + } + } + transpose_matrices(matrix); + } +} +/* +TEST CASES + +INPUT + Enter number of rows +2 + Enter number of columns +2 + Enter elements of matrix +2 3 +4 5 + +OUTPUT +2 4 +3 5 + +*/ + diff --git a/Max_Circular_SubArray_Sum/max_circular_subArray_sum.c b/Max_Circular_SubArray_Sum/max_circular_subArray_sum.c new file mode 100644 index 000000000..fde1120d3 --- /dev/null +++ b/Max_Circular_SubArray_Sum/max_circular_subArray_sum.c @@ -0,0 +1,77 @@ +/* +Question- Given n numbers (both +ve and -ve), arranged in a circle, find the maximum sum of consecutive number. +Solution- There are two cases for this problem +Case-1 The elements that contribute to the maximum sum are arranged such that no wrapping is there.Kadane will simply work. +Case-2 The elements which contribute to the maximum sum are arranged such that wrapping is there. +*/ + +#include + +//Returns maximum of two numbers. +int max(int num1, int num2) +{ + return (num1 > num2 ) ? num1 : num2; +} + +/*Function to find contiguous sub-array with the largest sum +in given set of integers*/ +int kadaneAlgo(int a[], int n) +{ + int max_so_far = 0, max_ending_here = 0; + + for(int i = 0; i < n ; i++) + { + max_ending_here += a[i]; + + if(max_ending_here < 0) + { + max_ending_here = 0; + } + + max_so_far = max(max_ending_here, max_so_far); + } + + return max_so_far; +} + +int circular_subarray_sum(int a[], int n) +{ + //answer for case 1 + int kadane_max = kadaneAlgo(a, n); + + //find total sum and negate all elements of the array + int total_sum = 0; + for(int i = 0; i < n ; i++) + { + total_sum + = a[i]; + a[i] = -a[i]; + + } + +/*find out the sum of non contributing elements and subtract this sum from the +total sum.*/ +total_sum = total_sum + kadaneAlgo(a, n); +return max(kadane_max, total_sum); +} + +int main() +{ + int n; + scanf("%d", &n); + int a[n]; + + for(int i = 0; i < n ; i++) + { + scanf("%d", &a[i]); + } + printf("The sum of subarray with the largest sum is: %d", circular_subarray_sum(a, n)); + return 0; +} + +/* +Input- +9 +2 1 -8 4 -5 1 -7 4 -1 +Output- +The sum of subarray with the largest sum is 6 +*/ \ No newline at end of file diff --git a/Max_Circular_SubArray_Sum/max_circular_subarray_sum.cpp b/Max_Circular_SubArray_Sum/max_circular_subarray_sum.cpp new file mode 100644 index 000000000..3e82c555b --- /dev/null +++ b/Max_Circular_SubArray_Sum/max_circular_subarray_sum.cpp @@ -0,0 +1,70 @@ +/* +Question- Given n numbers (both +ve and -ve), arranged in a circle, find the maximum sum of consecutive number. +Solution- There are two cases for this problem. +Case-1 The elements that contribute to the maximum sum are arranged such that no wrapping is there.Kadane will simply work. +Case-2 The elements which contribute to the maximum sum are arranged such that wrapping is there. +*/ + +#include +using namespace std; + +/* Function to find contiguous sub-array with the largest sum +in given set of integers*/ +int kadaneAlgo(int a[], int n) +{ + int max_so_far=0, max_ending_here = 0; + + for(int i = 0; i < n; i++) + { + max_ending_here += a[i]; + if(max_ending_here < 0) + { + max_ending_here = 0; + } + + max_so_far = max(max_ending_here, max_so_far); + } + return max_so_far; +} + +int circular_subarray_sum(int a[], int n) +{ + //answer for case 1. + int kadane_max = kadaneAlgo(a, n); + + //Find total sum and negate all elements of the array. + int total_sum = 0; + for(int i = 0; i < n; i++) + { + total_sum += a[i]; + a[i] = -a[i]; + + } + /*Ans for test case 2. + Find out the sum of non contributing elements and subtract this sum from the Total sum.*/ + total_sum = total_sum + kadaneAlgo(a, n); + return max(kadane_max, total_sum); +} + +int main() +{ + int n; + cin >> n; + int a[n]; + + for(int i = 0; i < n; i++) + { + cin >> a[i]; + } + + cout << "The sum of subarray with the largest sum is: " << circular_subarray_sum(a, n) << endl; + return 0; +} + +/* +Input- +9 +2 1 -8 4 -5 1 -7 4 -1 +Output- +The sum of subarray with the largest sum is 6 +*/ \ No newline at end of file diff --git a/Median_Sorted_Arrays/Median_Sorted_Arrays.cpp b/Median_Sorted_Arrays/Median_Sorted_Arrays.cpp new file mode 100644 index 000000000..d4b121bfb --- /dev/null +++ b/Median_Sorted_Arrays/Median_Sorted_Arrays.cpp @@ -0,0 +1,74 @@ +//median of two sorted arrays - +#include +#include +using namespace std; + +float median(int *arr1, int * arr2, int n, int m) +{ + int low1 = 0, + hi1 = n - 1, + low2 = 0, + hi2 = m - 1; + while (true) + { + int m1 = (hi1 - low1) / 2, + m2 = (hi2 - low2) / 2, + median1 = arr1[m1], + median2 = arr2[m2]; + if (hi1 - low1 <= 1 || hi2 - low1 <= 1) + { + //calculate the median + float leftVal = max(arr1[low1], arr2[low2]); + float rightVal = min(arr1[hi1], arr2[low2]); + float ans = (abs(n-m) >= 1) ? ceil((leftVal + rightVal)/2) : (leftVal + rightVal)/2; + return (float) ans; + } + if (median1 == median2) + { + return median1; + } + else if (median2 > median1) + { //Shift the lower pointer of array 1 to median 1 + low1 = m1; + //Shift the Higher pointer of array 2 to median 2 + hi2 = m2; + } + else { + //Shift the Higher pointer of array 1 to median 1 + hi1 = m1; + //Shift the Lower pointer of array 2 to median 2 + low2 = m2; + } + + } +} + +int main() +{ + int n, m, arr1[100005], arr2[100005]; + cout << "Enter size of Array 1 \n"; + cin >> n; + cout << "Enter size of Array 2 \n"; + cin >> m; + cout << "Enter Elements of Array 1 \n"; + for (int i = 0; i < n; i++) cin >> arr1[i]; + cout << "Enter Elements of Array 2 \n"; + for (int i = 0; i < m; i++) cin >> arr2[i]; + cout << "Median of Combined Sorted Array is " << median(arr1, arr2, n, m); + cout << endl; + return 0; +} + +/* Sample Input + Enter size of Array 1 + 3 + Enter size of Array 2 + 3 +Enter Elements of Array 1 + 1 2 3 +Enter Elements of Array 1 + 4 5 6 + +Sample Output +Median of Combined Sorted Array is - 3.5 + */ \ No newline at end of file diff --git a/Merge_Sort/Merge_Sort.php b/Merge_Sort/Merge_Sort.php new file mode 100644 index 000000000..5fada8473 --- /dev/null +++ b/Merge_Sort/Merge_Sort.php @@ -0,0 +1,44 @@ + 0 && count($right) > 0) { + if($left[0] > $right[0]) { + $res[] = $right[0]; + $right = array_slice($right , 1); + } + else{ + $res[] = $left[0]; + $left = array_slice($left, 1); + } + } + while (count($left) > 0) { + $res[] = $left[0]; + $left = array_slice($left, 1); + } + while (count($right) > 0) { + $res[] = $right[0]; + $right = array_slice($right, 1); + } + return $res; +} + +$test_array = array(100, 54, 7, 2, 5, 4, 1); +echo implode(' ', merge_sort($test_array)); + +/* +Output : +1 2 4 5 7 54 100 +*/ +?> diff --git a/Merge_Sort/Merge_Sort.rs b/Merge_Sort/Merge_Sort.rs new file mode 100644 index 000000000..4ee67d93f --- /dev/null +++ b/Merge_Sort/Merge_Sort.rs @@ -0,0 +1,97 @@ +/* + Rust Program to implement Merge Sort + -------------------------------------------------------- + Merge Sort + -------------------------------------------------------- +Merge sort is a divide-conquer-combine algorithm based on the idea of breaking down a list into several sub-lists . +The list is broken into sublists until each sublist consists of a single element and merging those sublists in a +manner that results into a sorted list. + +The idea is : + -> Divide the unsorted list into N sublists, each containing 1 element. + -> Take adjacent pairs of two singleton lists and merge them to form a list of 2 elements.N will now convert + into N/2 lists of size 2. + -> Repeat the process till a single sorted list of size N is obtained. + +Complexity Analysis : + +The list of size N is divided into a max of logN parts, and the merging of all sublists into a single list takes O(N) time. +The worst case run time of this algorithm is O(NlogN) . +The average and best case run time of this algorithm is N(logN) . +The space complexity of this algorithm is N . +*/ + + +use std::io; +use std::str::FromStr; + +fn main() { + println!("Enter the numbers to be sorted (separated by space) : "); + let mut i = read_values::().unwrap(); + merge_sort(&mut i); + println!("Sorted array: {:?}", i) + } + +fn merge_sort(a: &mut Vec) { + let size = a.len(); + let mut buffer = vec![0; size]; + merge_split(a, 0, size, &mut buffer); +} + +fn merge_split(a: &mut Vec, start: usize, end: usize, buffer: &mut Vec) { + if end - start > 1 { + // Determine the split index + let split = (start + end) / 2; + + // Split and merge sort + merge_split(a, start, split, buffer); + merge_split(a, split, end, buffer); + merge(a, buffer, start, split, end); + merge_copy(buffer, a, start, end); + } +} + +fn merge(src: &Vec, dest: &mut Vec, start: usize, split: usize, end: usize) { + // Define cursor indices for the left and right part that will be merged + let mut left = start; + let mut right = split; + + // Merge the parts into the destination in the correct order + for i in start..end { + if left < split && (right >= end || src[left] <= src[right]) { + dest[i] = src[left]; + left += 1; + } else { + dest[i] = src[right]; + right += 1; + } + } +} + +fn merge_copy(src: &Vec, dest: &mut Vec, start: usize, end: usize) { + (start..end).for_each(|i| dest[i] = src[i]); +} + +fn read_values() -> Result, T::Err> { + let mut s = String::new(); + io::stdin() + .read_line(&mut s) + .expect("could not read from stdin"); + s.trim() + .split_whitespace() + .map(|word| word.parse()) + .collect() +} + +/* + + Sample Input : + + Enter the numbers to be sorted (separated by space) : + 76 56 45 3 1 4 + + Sample Output : + + Sorted array: [1, 3, 4, 45, 56, 76] +*/ + diff --git a/Merge_Sort/Merge_Sort.ts b/Merge_Sort/Merge_Sort.ts new file mode 100644 index 000000000..4ba47def7 --- /dev/null +++ b/Merge_Sort/Merge_Sort.ts @@ -0,0 +1,46 @@ +export function mergeSort(array: number[]): number[] { + if (array.length <= 1) { + return array; + } + const middle = Math.floor(array.length / 2); + const left = array.slice(0, middle); + const right = array.slice(middle); + return merge(mergeSort(left), mergeSort(right)); +} + +function merge(left: number[], right: number[]): number[] { + const array: number[] = []; + let lIndex = 0; + let rIndex = 0; + while (lIndex + rIndex < left.length + right.length) { + const lItem = left[lIndex]; + const rItem = right[rIndex]; + if (lItem == null) { + array.push(rItem); + rIndex++; + } + else if (rItem == null) { + array.push(lItem); + lIndex++; + } + else if (lItem < rItem) { + array.push(lItem); + lIndex++; + } + else { + array.push(rItem); + rIndex++; + } + } + return array; +} +console.log(mergeSort([8, 7, 4, 30, 21, 12])); + + +/* + + Input : [8, 7, 4, 30, 21, 12] + Output : [ 4, 7, 8, 12, 21, 30 ] + +*/ + diff --git a/Merge_Sort_3_Way/Merge_Sort_3_Way.cpp b/Merge_Sort_3_Way/Merge_Sort_3_Way.cpp new file mode 100644 index 000000000..b1092a74e --- /dev/null +++ b/Merge_Sort_3_Way/Merge_Sort_3_Way.cpp @@ -0,0 +1,204 @@ +#include "iostream" +#include +using namespace std; + +//function for storing elements from three vectors(left,mid,right) in sorted manner in vector named sorted +// sorted vector must be passed by reference to see the effect of changes made by the function +// other vectors are passed as reference to avoid copying of elements repeatedly + +void mergeVersion3(vector &sorted,vector &left,vector &mid,vector &right) +{ + int i = 0; //index pointer variable for left vector + int j = 0; //index pointer variable for mid vector + int k = 0; //index pointer variable for right vector + int l = 0; //index pointer variable for sorted vector + // selecting the minimum element of from the three vectors when all are non-empty + while( (i < left.size()) && (j mergeSort3ways(vector &input) +{ + if( input.size() == 1 ) + { + return input; + } + else if( input.size() == 2 ) + { + + //two different vectors (element1 and element2) of size 1 to store one element each and no_element vector of size 0 + + vectorelement1,element2,no_element(0); + element1.emplace_back(input.at(0)); + element2.emplace_back(input.at(1)); + + //call merging of three vectors and then return sorted vector + + mergeVersion3(input,element1,element2,no_element); + return input; + } + else + { int left_size {0}, right_size {0}, mid_size {0}; + if( input.size() % 3 == 0 ) + { + left_size = int(input.size() / 3); + mid_size = int(input.size() / 3); + right_size = int(input.size() / 3); + } + else if( input.size() % 3 == 1 ) + { + left_size = int(input.size() / 3) + 1; + mid_size = int(input.size() / 3); + right_size = int(input.size() / 3); + } + else if( input.size() % 3 == 2 ) + { + left_size = int(input.size() / 3) + 1; + mid_size = int(input.size() / 3); + right_size = int(input.size() / 3) + 1; + } + + // dividing original vector into three vectors left_vec,mid_vec,right_vec + + vector left_vec,right_vec,mid_vec; + for (int i = 0; i < left_size ; ++i) + { + left_vec.emplace_back(input[i]); + } + for (int i = 0; i < mid_size ; ++i) + { + mid_vec.emplace_back(input[i + left_size]); + } + for (int i = 0; i < right_size ; ++i) + { + right_vec.emplace_back(input[i + left_size + mid_size]); + } + + //dividing the three vectors recursively + + mergeSort3ways(left_vec); + mergeSort3ways(mid_vec); + mergeSort3ways(right_vec); + + // sorting the vector + + mergeVersion3(input,left_vec,mid_vec,right_vec); + return input; + } + +} + +// Driver Code + +int main() +{ + int n {0} , temp {0}; //initializes the variables n and temp to zero just after creation , it is not assignment + cin >> n; //input for number of elements in input array/vector + vector input , result; //vector to take input of all elements + + // taking input of n elements in a vector + + for (int i = 0; i < n ; ++i) { + cin >> temp; + input.emplace_back(temp); //emplace_back is more efficient than push_back + } + + // sorted vector is returned to result vector + + result = mergeSort3ways(input); + + // Displaying the sorted Vector + + for(auto c : result) + { + cout << c << " "; + } + return 0; +} +// Sample Test Cases +// Input +// 5 +// 78 8 6 5 7 +// Output +// 5 6 7 8 78 +// input +// 10 +// -8 45 -9 47 34 2 5 21 987 -3 +// Output +// -9 -8 -3 2 5 21 34 45 47 987 diff --git a/Minesweeper/minesweeper.cpp b/Minesweeper/minesweeper.cpp new file mode 100644 index 000000000..5f4265333 --- /dev/null +++ b/Minesweeper/minesweeper.cpp @@ -0,0 +1,399 @@ +#include +using namespace std; + +#define max_mine 99 +#define max_side 25 +#define max_move 526 // 25*25-99 +int SIDE; +int MINES; + +void clrscr() +{ + std::cout << "\33[2J\33[1;1H" << std::flush; +} + +bool isvalid(int row, int col) +{ + return (row >= 0) && (row < SIDE) && (col >= 0) && (col < SIDE); +} + +bool ismine(int row, int col, char board[][max_side]) +{ + if(board[row][col] == 'B') + return (true); + else + return (false); +} + +void move(int *x, int *y) +{ + printf("\nEnter your move as (row col) -> "); + scanf("%d %d", x, y); + return; +} + +void board(char myboard[][max_side]) +{ + clrscr(); + printf("\n\n\t\t\t "); + for(int i = 0; i < SIDE; i++) + { + if (i > 9) + printf(" %d ", i / 10); + else + printf(" "); + } + printf("\n\t\t\t "); + for(int i = 0; i < SIDE; i++) + printf(" %d ", i % 10); + printf("\n\n"); + for(int i = 0; i < SIDE; i++) + { + printf("\t\t\t "); + for(int j = 0; j < SIDE; j++) + { + printf("%c ", myboard[i][j]); + } + printf(" %2d", i); + printf("\n"); + } + return; +} + +int countadjacent(int row, int col, int mines[][2], char realboard[][max_side]) +{ + int count = 0; + if(isvalid(row - 1, col) == true) + { + if(ismine(row - 1, col, realboard) == true) + count++; + } + if(isvalid(row + 1, col) == true) + { + if(ismine(row + 1, col, realboard) == true) + count++; + } + if(isvalid(row, col + 1) == true) + { + if(ismine(row, col + 1, realboard) == true) + count++; + } + if(isvalid(row, col - 1) == true) + { + if(ismine(row, col - 1, realboard) == true) + count++; + } + if(isvalid(row - 1, col - 1) == true) + { + if(ismine(row - 1, col - 1, realboard) == true) + count++; + } + if(isvalid(row - 1, col + 1) == true) + { + if(ismine(row - 1, col + 1, realboard) == true) + count++; + } + if(isvalid(row + 1, col - 1) == true) + { + if(ismine(row + 1, col - 1, realboard) == true) + count++; + } + if(isvalid(row + 1, col + 1) == true) + { + if(ismine(row + 1, col + 1, realboard) == true) + count++; + } + return (count); +} + +bool playuntil(char myboard[][max_side], char realboard[][max_side], int mines[][2], int row, int col, int *moves_left) +{ + if(myboard[row][col] != '-') + return false; + int i, j; + if(realboard[row][col] == 'B') + { + myboard[row][col] = 'B'; + for(i = 0; i < MINES; i++) + myboard[mines[i][0]][mines[i][1]] = 'B'; + board(myboard); + printf ("\nYou lost!\n"); + return (true); + } + else + { + int count = countadjacent(row, col, mines, realboard); + (*moves_left)--; + myboard[row][col] = count + '0'; + if(!count) + { + if(isvalid(row - 1, col) == true) + { + if(ismine(row - 1, col, realboard) == false) + playuntil(myboard, realboard, mines, row - 1, col, moves_left); + } + if (isvalid (row + 1, col) == true) + { + if (ismine (row + 1, col, realboard) == false) + playuntil(myboard, realboard, mines, row + 1, col, moves_left); + } + if (isvalid (row, col + 1) == true) + { + if (ismine (row, col + 1, realboard) == false) + playuntil(myboard, realboard, mines, row, col + 1, moves_left); + } + if (isvalid (row, col - 1) == true) + { + if (ismine (row, col - 1, realboard) == false) + playuntil(myboard, realboard, mines, row, col - 1, moves_left); + } + if (isvalid (row - 1, col + 1) == true) + { + if (ismine (row - 1, col + 1, realboard) == false) + playuntil(myboard, realboard, mines, row - 1, col + 1, moves_left); + } + if (isvalid (row - 1, col - 1) == true) + { + if (ismine (row - 1, col - 1, realboard) == false) + playuntil(myboard, realboard, mines, row - 1, col - 1, moves_left); + } + if (isvalid (row + 1, col + 1) == true) + { + if (ismine (row + 1, col + 1, realboard) == false) + playuntil(myboard, realboard, mines, row + 1, col + 1, moves_left); + } + if (isvalid (row + 1, col - 1) == true) + { + if (ismine (row + 1, col - 1, realboard) == false) + playuntil(myboard, realboard, mines, row + 1, col - 1, moves_left); + } + } + return (false); + } +} + +void placemines(int mines[][2],char realboard[][max_side]) +{ + bool mark[max_side*max_side]; + memset(mark, false, sizeof(mark)); + for(int i = 0; i < MINES;) + { + int random = rand() % (SIDE * SIDE); + int x = random / SIDE; + int y = random % SIDE; + if(mark[random] == false) //add mine if not present at position random + { + mines[i][0] = x; + mines[i][1] = y; + realboard[mines[i][0]][mines[i][1]] = 'B'; + mark[random] = true; + i++; + } + } +} + +void initialise(char realboard[][max_side], char myboard[][max_side]) +{ + srand(time(NULL)); //initalising random so that same config doesn't arise + int i, j; + for(i = 0; i < SIDE; i++) + for(j = 0; j < SIDE; j++) + { + myboard[i][j] = realboard[i][j] = '-'; + } + return; +} + +void cheatmines (char realboard[][max_side]) +{ + printf ("The mines locations are-\n"); + board (realboard); + return; +} + +void replacemine(int row, int col, char board[][max_side]) +{ + for(int i = 0; i < SIDE; i++) + { + for(int j = 0; j < SIDE; j++) + { + if(board[i][j] != 'B') + { + board[i][j] = 'B'; + board[row][col] = '-'; + return; + } + } + } +} + +void play() +{ + bool gameover = false; + char realboard[max_side][max_side],myboard[max_side][max_side]; + int moves_left = SIDE*SIDE-MINES; + int x,y; + int mines[max_mine][2]; //stores (x,y) of all mines + initialise(realboard, myboard); + placemines(mines, realboard); + //if you want cheat and win + //cheatmines(realboard); + int currentmoveindex = 0; + while(gameover == false) + { + printf ("Current Status of Board : \n"); + board(myboard); + move(&x, &y); + //if first move is mine + if(currentmoveindex == 0) + { + if(ismine(x, y, realboard) == true) //first attempt is a mine + replacemine(x, y, realboard); //replace the mine at that location + } + currentmoveindex++; + gameover = playuntil(myboard, realboard, mines, x, y, &moves_left); + if((gameover == false) && (moves_left == 0)) + { + printf ("\nYou won !\n"); + gameover = true; + } + } +} + +void chdiff() +{ + clrscr(); + cout << "\nMINESWEEPER GAME"; + cout << "\n\nCHOOSE YOUR DIFFICULTY LEVEL : "; + cout << "\n\n0.BEGINNER\n1.MEDIUM\n2.HARD"; + cout << "\n\nENTER YOUR LEVEL (0-2) : "; + int ch; + cin >> ch; + if(ch == 0) + { + SIDE = 9; + MINES = 10; + } + else if(ch == 1) + { + SIDE = 16; + MINES = 40; + } + else if(ch == 2) + { + SIDE = 24; + MINES = 99; + } + else + exit(0); +} + +int main() +{ + chdiff(); + play(); + return 0; +} + +/* + Input: + MINESWEEPER GAME +CHOOSE YOUR DIFFICULTY LEVEL : +0.BEGINNER +1.MEDIUM +2.HARD +ENTER YOUR LEVEL (0-2) :0 +Output: + 0 1 2 3 4 5 6 7 8 + + - - - - - - - - - 0 + - - - - - - - - - 1 + - - - - - - - - - 2 + - - - - - - - - - 3 + - - - - - - - - - 4 + - - - - - - - - - 5 + - - - - - - - - - 6 + - - - - - - - - - 7 + - - - - - - - - - 8 + +EnteEnter your move as (row col) -> 4 6 + 0 1 2 3 4 5 6 7 8 + + - - - - 1 0 0 0 0 0 + - - 1 1 2 1 1 0 0 1 + - - 1 0 1 - 1 0 0 2 + - - 1 0 1 1 1 0 0 3 + - - 2 1 0 0 0 1 1 4 + - - - 2 1 1 0 1 - 5 + - - - - - 1 0 1 - 6 + - - - - - 1 1 2 - 7 + - - - - - - - - - 8 + +Enter your move as (row col) -> 7 3 + 0 1 2 3 4 5 6 7 8 + + - - - - 1 0 0 0 0 0 + - - 1 1 2 1 1 0 0 1 + - - 1 0 1 - 1 0 0 2 + - - 1 0 1 1 1 0 0 3 + - - 2 1 0 0 0 1 1 4 + - - - 2 1 1 0 1 - 5 + - - - - - 1 0 1 - 6 + - - - 1 - 1 1 2 - 7 + - - - - - - - - - 8 +Enter your move as (row col) -> 8 6 + 0 1 2 3 4 5 6 7 8 + + - - - - 1 0 0 0 0 0 + - - 1 1 2 1 1 0 0 1 + - - 1 0 1 - 1 0 0 2 + - - 1 0 1 1 1 0 0 3 + - - 2 1 0 0 0 1 1 4 + - - - 2 1 1 0 1 - 5 + - - - - - 1 0 1 - 6 + - - - 1 - 1 1 2 - 7 + - - - - - - 1 - - 8 + +Enter your move as (row col) -> 6 1 + + 0 1 2 3 4 5 6 7 8 + + - - - - 1 0 0 0 0 0 + - - 1 1 2 1 1 0 0 1 + - - 1 0 1 - 1 0 0 2 + - - 1 0 1 1 1 0 0 3 + - - 2 1 0 0 0 1 1 4 + - - - 2 1 1 0 1 - 5 + - 1 - - - 1 0 1 - 6 + - - - 1 - 1 1 2 - 7 + - - - - - - 1 - - 8 + Enter your move as (row col) -> 8 3 + 0 1 2 3 4 5 6 7 8 + + - - - - 1 0 0 0 0 0 + - - 1 1 2 1 1 0 0 1 + - - 1 0 1 - 1 0 0 2 + - - 1 0 1 1 1 0 0 3 + 2 3 2 1 0 0 0 1 1 4 + 0 1 - 2 1 1 0 1 - 5 + 0 1 1 2 - 1 0 1 - 6 + 0 0 0 1 1 1 1 2 - 7 + 0 0 0 0 0 0 1 - - 8 + + + Enter your move as (row col) -> 8 8 + + 0 1 2 3 4 5 6 7 8 + + - - - B 1 0 0 0 0 0 + - - 1 1 2 1 1 0 0 1 + B - 1 0 1 B 1 0 0 2 + B B 1 0 1 1 1 0 0 3 + 2 3 2 1 0 0 0 1 1 4 + 0 1 B 2 1 1 0 1 B 5 + 0 1 1 2 B 1 0 1 - 6 + 0 0 0 1 1 1 1 2 - 7 + 0 0 0 0 0 0 1 B B 8 + +You lost! +*/ diff --git a/Minimum_Absolute_Difference_In_Array/Minimum_Absolute_Difference_In_Array.c b/Minimum_Absolute_Difference_In_Array/Minimum_Absolute_Difference_In_Array.c new file mode 100644 index 000000000..8739a9751 --- /dev/null +++ b/Minimum_Absolute_Difference_In_Array/Minimum_Absolute_Difference_In_Array.c @@ -0,0 +1,42 @@ +/*Given an integer array A of size N, find and return +the minimum absolute difference between any two elements in the array. +The absolute difference between two elements ai, and aj (where i != j ) is |ai - aj|*/ + +#include +#include +#include + +int cmpfunc (const void * a, const void * b) +{ + return (*(int*)a - *(int*)b); +} + +int minAbsoluteDiff(int arr[], int n) +{ + qsort(arr, n, sizeof(int), cmpfunc); + int mindiff = INT_MAX; + for(int i = 0; i < n - 1; i++) + { + if(abs(arr[i] - arr[i + 1]) < mindiff) + mindiff = abs(arr[i] - arr[i + 1]); + } + return mindiff; +} + +int main() +{ + int size, i; + scanf("%d", &size); + int input[size]; + for(i = 0; i < size; i++) + scanf("%d", &input[i]); + + printf("%d", minAbsoluteDiff(input,size)); + return 0; +} + +/* Input : 12 + 922 192 651 200 865 174 798 481 510 863 150 520 + + Output : 2 +*/ diff --git a/Minimum_Absolute_Difference_In_Array/Minimum_Absolute_Difference_In_Array.cpp b/Minimum_Absolute_Difference_In_Array/Minimum_Absolute_Difference_In_Array.cpp new file mode 100644 index 000000000..ab13f120d --- /dev/null +++ b/Minimum_Absolute_Difference_In_Array/Minimum_Absolute_Difference_In_Array.cpp @@ -0,0 +1,38 @@ +/*Given an integer array A of size N,find and return +the minimum absolute difference between any two elements in the array. +The absolute difference between two elements ai, and aj (where i != j ) is |ai - aj|*/ + +#include +#include +#include +using namespace std; + +int minAbsoluteDiff(int arr[], int n) +{ + std::sort(arr, arr + n); + int mindiff = INT_MAX; + for(int i = 0; i < n - 1; i++) + { + if(abs(arr[i] - arr[i + 1] ) < mindiff) + mindiff = abs(arr[i] - arr[i + 1]); + } + return mindiff; +} + +int main() +{ + int size; + cin >> size; + int *input = new int[1 + size]; + + for(int i = 0; i < size; i++) + cin >> input[i]; + cout << minAbsoluteDiff(input, size) << endl; + return 0; +} + +/* Input : 5 + 2 9 0 4 5 + + Output : 1 +*/ diff --git a/Number_Conversion/C++/Decimal_to_Binary.cpp b/Number_Conversion/C++/Decimal_to_Binary.cpp new file mode 100644 index 000000000..219352146 --- /dev/null +++ b/Number_Conversion/C++/Decimal_to_Binary.cpp @@ -0,0 +1,41 @@ + +// C++ program to convert numbers from decimal to binary form + +#include +#include +using namespace std; + +// Function to convert the number from decimal to binary form +void printBinary(int n){ + + // command to find out number of bits in the given number + // which decides the size of the array + int size = log2(n) + 1; + + // Array to store the binary number + int b[size], j = 0; + while(n != 0){ + b[j] = n % 2; + n = n / 2; + j++; + } + + cout << "The binary form is : "; + for(j = size - 1; j >= 0; j--) + cout << b[j]; +} + + +int main() +{ + cout << "Enter the number you wish to convert:" << endl; + int n; + cin >> n; + printBinary(n); // Calling function printBinary to convert the number to binary form + cout << "\n"; + return 0; +} +/* +Input : 25 +Output : 11001 +*/ diff --git a/Number_Conversion/Java/Binary_To_Octal.java b/Number_Conversion/Java/Binary_To_Octal.java new file mode 100644 index 000000000..edea549b6 --- /dev/null +++ b/Number_Conversion/Java/Binary_To_Octal.java @@ -0,0 +1,46 @@ +import java.io.*; +import java.util.Scanner; + +public class Binary_To_Octal +{ + public static void binToOctal(long num) + { + int n = 0, decimal = 0; + //converting binary to decimal + while(num > 0) + { + long temp = num % 10; + decimal += temp * Math.pow(2, n); + num = num / 10; + n++; + } + int octal[] = new int[20]; + int i = 0; + while(decimal > 0) + { + int t = decimal % 8; + octal[i++] = t; + decimal = decimal / 8; + } + System.out.print("Octal representation"); + for(int j = i-1 ; j >= 0 ; j--) + System.out.print(octal[j]); + } + public static void main(String[] args) + { + long num; + Scanner sc = new Scanner(System.in); + System.out.println("Enter a Binary number"); + num = sc.nextLong(); + binToOctal(num); + sc.close(); + } +} +/* +Input: +Enter a Binary number +1011001010 +Output: +Octal representation +2625 +*/ diff --git a/Number_Conversion/Java/Decimal_to_binary.java b/Number_Conversion/Java/Decimal_to_binary.java new file mode 100644 index 000000000..24a179f0b --- /dev/null +++ b/Number_Conversion/Java/Decimal_to_binary.java @@ -0,0 +1,30 @@ +//JAVA program to convert Decimal integer to it's Binary form + +import java.util.Scanner; + +public class Decimal_to_binary { + + //Driver Code + public static void main(String[] args){ + int n, rem; + String Bin = ""; //String to store the binary number + Scanner sc = new Scanner(System.in); + System.out.println("Enter any decimal number:"); + n = sc.nextInt(); //Taking the decimal input + + if (n == 0){ + Bin = "0"; + } + + //Simultaneously storing the remainder when number divided by 2 in the string in reverse order + while (n > 0){ + rem = n % 2; + Bin = rem + Bin; + n = n / 2; + } + System.out.println("Binary number:"+Bin); //output + } +} +//Input : 10 +//Output : 1010 + diff --git a/Palindrome/palindrome_no.java b/Palindrome/palindrome_no.java new file mode 100644 index 000000000..b3b5e0e06 --- /dev/null +++ b/Palindrome/palindrome_no.java @@ -0,0 +1,47 @@ +// Java program to check if a number entered is a palindrome + +import java.util.*; + +public class palindrome_no { + + // Find reverse of a number + public static int reverse(int number) { + int reverseno = 0 ; + + while (number > 0) { + reverseno = (int) (reverseno * Math.pow(10, 1) + number % Math.pow(10, 1)); + number = (int) (number / Math.pow(10, 1)); + } + return reverseno; + } + + public static void main(String[] args) { + Scanner s = new Scanner(System.in); + System.out.println(" Hey, Enter any number "); + int enter_number = s.nextInt(); + int reverseno = reverse(enter_number); + + // Check whether the number entered is equal to reversed number or not + if (reverseno == enter_number) { + System.out.println("Number is a PALINDROME"); + return ; + } + System.out.println("Number is not a PALINDROME"); + return; + } +} + +/* +Test cases +INPUT + Hey, Enter any number +1223 +OUTPUT +Number is not a PALINDROME + +INPUT + Hey, Enter any number +1223221 +OUTPUT +Number is a PALINDROME +*/ diff --git a/Palindrome/palindrome_no.py b/Palindrome/palindrome_no.py new file mode 100644 index 000000000..0f341d47c --- /dev/null +++ b/Palindrome/palindrome_no.py @@ -0,0 +1,34 @@ +# Python program to find whether a number is a palindrome or not + +# Function to reverse a number +def reverse(num): + # Initialize variable + rev = 0 + + while ( num > 0 ) : + dig = num % 10 + rev = rev * 10 + dig + num = num // 10 + # Returning reversed number + return rev + +# --- main --- +num = int(input("Enter a number:")) +a = reverse(num) + +# Comparing the reversed number with original number +if(a == num): + print("Number entered is palindrome!") +else: + print("Number entered is not a palindrome!") + +''' +TEST CASES +INPUT +Enter a number:3445443 +Number entered is palindrome! + +OUTPUT +Enter a number:234 +Number entered is not a palindrome! +''' diff --git a/Palindrome/palindrome_string.java b/Palindrome/palindrome_string.java new file mode 100644 index 000000000..175e380e1 --- /dev/null +++ b/Palindrome/palindrome_string.java @@ -0,0 +1,50 @@ +//Java program to check if a string is a Palindrome + +import java.util.*; + +public class reverse_string { + + // Reverse a given string + public static String palindrome(String string_entered) { + String str_reversed = ""; + int length_of_String = string_entered.length()-1; + int len = 0; + + for (len = length_of_String; len >= 0 ; len --) + str_reversed = str_reversed + string_entered.charAt(len); + return str_reversed; + } + + public static void main(String[] args) { + + Scanner s = new Scanner(System.in); + System.out.println(" Hey,Enter any string "); + String string_entered = s.nextLine(); + String str_reversed = palindrome(string_entered); + + // Comparing 2 strings to find if input string is palindrome or not + if(string_entered.equals(str_reversed)) { + System.out.println(" String is a PALINDROME "); + } + else { + System.out.println(" String is not a PALINDROME "); + } + } +} + +/* +Test cases + +INPUT + Hey,Enter any string +hello +OUTPUT + String is not a PALINDROME + +INPUT + Hey,Enter any string +metem +OUTPUT + String is a PALINDROME +*/ + diff --git a/Palindrome/palindrome_string.py b/Palindrome/palindrome_string.py new file mode 100644 index 000000000..3aa4aac24 --- /dev/null +++ b/Palindrome/palindrome_string.py @@ -0,0 +1,32 @@ +# Python program to find whether a string is a palindrome or not + +# Function to reverse a String +def reverse(str): + + # Initialize variable + rev = "" + + for i in range (len(str)-1, -1, -1): + rev = rev + str[i] + return rev + + +# --- main --- +string = raw_input(("Enter a string: ")) #User Input + +a = reverse(string) #Function call + +if(a == string): #Comparing the reversed String with original String + print("String entered is palindrome!") +else: + print("String entered is not a palindrome!") + +''' +TEST CASES + +Enter a string: affcffa +String entered is palindrome! + +Enter a string: abbcd +String entered is not a palindrome! +''' diff --git a/Pancake_Sort/Pancake_Sort.cs b/Pancake_Sort/Pancake_Sort.cs new file mode 100644 index 000000000..14fcf9212 --- /dev/null +++ b/Pancake_Sort/Pancake_Sort.cs @@ -0,0 +1,78 @@ +using System; + +class pancakeSortProgram { + // function swapping adjacent integer in array till from index 0 toindex i + static void flip(int []arr, int i) + { + int temp, start = 0; + while (start < i) + { + temp = arr[start]; + arr[start] = arr[i]; + arr[i] = temp; + start++; + i--; + } + } + // function returning index of max value till index curr_size + static int findMax(int []arr, int n) + { + int mi, i; + for (mi = 0, i = 0; i < n; ++i) + if (arr[i] > arr[mi]) + mi = i; + return mi; + } + + static int pancakeSort(int []arr, int n) + { + for (int curr_size = n; curr_size > 1; --curr_size) + { + // function calling for finding index of max integer + // till the index curr_size + int mi = findMax(arr, curr_size); + // call function flip for swapping if index of max integer + // till the index curr_size is not equal to curr_size-1 + if (mi != curr_size - 1) + { + flip(arr, mi); + flip(arr, curr_size - 1); + } + } + return 0; + } + // function for printing sorted array + static void printArray(int []arr, int arr_size) + { + for (int i = 0; i < arr_size; i++) + Console.Write(arr[i] + " "); + Console.Write(""); + } + + public static void Main (string [] args) + { + int n = Convert.ToInt32(Console.ReadLine());//input size of array + int []arr = new int[n];//initializing array of size n + + for(int i = 0; i < n; i++) + arr[i] = Convert.ToInt32(Console.ReadLine());//input value in array + + pancakeSort(arr, n);// call function which is sorting the input array + Console.Write("Sorted Array: "); + printArray(arr, n);// call fubction which print the sorted array + } +} +/* +Input: +6 +23 +10 +20 +11 +12 +6 +7 + +Output: +Sorted Array: 6 7 10 11 12 20 23 +*/ diff --git a/Pancake_Sort/Pancake_Sort.dart b/Pancake_Sort/Pancake_Sort.dart new file mode 100644 index 000000000..b9b5147a6 --- /dev/null +++ b/Pancake_Sort/Pancake_Sort.dart @@ -0,0 +1,70 @@ +/** + * Pancake Sort + * -------------------------- + * It is a sorting algorithm of O(n^2) algorithm which sorts like selection sort + * by moving the minimum to the front by reversing the array till its index. + */ + +// Importing required libraries +import 'dart:io'; + +// Utility function to find maximum of the array +int findMax(List array, int n){ + int max_value = array[0]; + int max_index = 0; + for (int i = 0; i < n; i ++){ + if (max_value < array[i]){ + max_value = array[i]; + max_index = i; + } + } + return max_index; +} + +// Utility function to flip an array from an index +void flip(List array, int i){ + int start = 0, temp; + while (start < i){ + temp = array[start]; + array[start] = array[i]; + array[i] = temp; + start ++; + i --; + } +} + +// Function to sort a list using pancake sort +void pancakeSort(List array, int n){ + for (int i = n; i > 1; i --){ + int max_index = findMax(array, i); + if (max_index != i - 1){ + flip(array, max_index); + flip(array, i - 1); + } + } +} +// Driver method of the program +void main(){ + print("Enter number of elements of the array:"); + var input = stdin.readLineSync(); + int n = int.parse(input); + + print("Enter array elements:"); + input = stdin.readLineSync(); + var lis = input.split(" "); + List array = lis.map(int.parse).toList(); + + pancakeSort(array, n); + + print(array.join(" ")); +} + +/** + * Sample Input and Output + * ------------------------------------ + * Enter number of elements of the array: + * 10 + * Enter array elements: + * 10 9 8 7 6 5 4 3 2 1 + * 1 2 3 4 5 6 7 8 9 10 + */ diff --git a/Pancake_Sort/Pancake_Sort.go b/Pancake_Sort/Pancake_Sort.go new file mode 100644 index 000000000..0feb1e14f --- /dev/null +++ b/Pancake_Sort/Pancake_Sort.go @@ -0,0 +1,85 @@ +// Program in Go language that implements Pancake Sort + +package main + +import "fmt" + +//Reverses array +func flip(array []int, index int) { + var start int + start = 0 + for start < index { + array[start], array[index] = array[index], array[start] + start++ + index-- + } +} + +// Returns index of element with maximum value in the array +func maxIndex(array []int, n int) int { + var index int + index = 0 + for i := 0; i < n; i++ { + if array[i] > array[index] { + index = i + } + } + return index +} + +// Function to sort the array using pancake sort + +func pancakeSort(array []int, n int) { + // Reducing the size of the array one at a time + for size := n; size > 1; size-- { + max := maxIndex(array, size) + // If the max element is not in the end of the array, move it there + if max != size-1 { + // We move the maximum element to the beginning and then flip the array to move the element to the end + flip(array, max) + flip(array, size-1) + } + } +} + +func main() { + + // Declare the array size + var arraySize int + + fmt.Print("Enter number of elements in your array: ") + + fmt.Scan(&arraySize) + + fmt.Print("Enter your array: ") + + // Creating the array + array := make([]int, arraySize) + + for i := 0; i < arraySize; i++ { + fmt.Scan(&array[i]) + } + + fmt.Printf("Unsorted Array: ") + for i := 0; i < arraySize; i++ { + fmt.Printf("%d ", array[i]) + } + + pancakeSort(array, arraySize) + + fmt.Printf("\nSorted Array: ") + for i := 0; i < arraySize; i++ { + fmt.Printf("%d ", array[i]) + } + +} + +/* +Output after Execution: + +Enter number of elements in your array: 6 +Enter your array: 2 1 5 4 9 8 +Unsorted Array: 2 1 5 4 9 8 +Sorted Array: 1 2 4 5 8 9 + +*/ diff --git a/Pancake_Sort/Pancake_Sort.java b/Pancake_Sort/Pancake_Sort.java new file mode 100644 index 000000000..c26136fe0 --- /dev/null +++ b/Pancake_Sort/Pancake_Sort.java @@ -0,0 +1,73 @@ +/* Pancake Sorting is a Sorting Technique in which the array of length n can be sorted only by reversing the array upto an index i where i is in range of 0 to n - 1 */ + +import java.util.* ; +class PancakeSorting +{ + + static void reverseArray ( int a [] , int n ) // This functions reverses the array upto index n + { + int temp[] = new int [ n + 1 ] ; // temp is the temporary array + for ( int i = 0 ; i <= n ; i ++ ) + { + temp [ i ] = a [ n - i ] ; + } + for ( int i = 0 ; i <= n ; i ++ ) + a [ i ] = temp [ i ] ; + } + + + static int findMax ( int a [] , int n ) // Function to find index of max element upto index n + { + int max = a [ 0 ] ; int j = 0 ; // j stores the index of max element + for ( int i = 1 ; i <= n ; i ++ ) + { + if ( a [ i ] > max ) + { + max = a [ i ] ; + j = i ; + } + } + + return j ; + + } + + + static void pancakeSort ( int a [ ] , int n ) + { + int currentLength ; + for ( currentLength = n ; currentLength > 0 ; -- currentLength ) + { + int j = findmax ( a , currentLength - 1 ) ; + if ( j != currentLength ) + { + reverseArray ( a , j ) ; + reverseArray ( a , currentLength-1 ) ; + } + } + } + + + public static void main ( String [] args ) + { + Scanner sc = new Scanner ( System.in ) ; + int i , j , k , l , m , n ; + n = sc.nextInt () ; + int array [ ] = new int [ n ] ; + for ( i = 0 ; i < n ;i ++) + array [ i ] = sc.nextInt () ; + pancakesort ( array , n ) ; + for ( i = 0 ; i < n ; i ++) + System.out.print ( array [ i ] + " " ) ; + System.out.println ( ) ; + } + + +} + + +/* Input +n = 5 array = { 5 , 4 , 3 , 2 , 1 } + + Output +1 2 3 4 5 */ diff --git a/Pancake_Sort/Pancake_Sort.kt b/Pancake_Sort/Pancake_Sort.kt new file mode 100644 index 000000000..d24e22b8a --- /dev/null +++ b/Pancake_Sort/Pancake_Sort.kt @@ -0,0 +1,71 @@ +// Kotlin Code for Pancake Sort + +class PancakeSorting +{ + // This functions reverses the array upto index n + fun reverseArray (int:a[], int:n):void + { + int temp[] = new int [n+1]; + for (i in 0 until n) + { + temp[i] = a[n-i]; + } + for (i in 0 until n) + { + a[i] = temp[i]; + } + } + + // Function to find index of max element upto index n + fun findMax (int:a[], int:n ):int + { + int max = a[0]; int j = 0; + for (i in 1 until n) + { + if (a[i] > max) + { + max = a[i]; + j = i; + } + } + return j; + } + + fun pancakeSort (int:a [], int:n):void + { + int currentLength; + for (currentLength in n until 0) + { + int j = findmax (a,currentLength-1); + if (j != currentLength) + { + reverseArray (a,j); + reverseArray (a,currentLength-1); + } + } + } + + fun main () + { + var read = Scanner(System.`in`) + int i , j , k , l , m , n; + val n = read.nextLine().toInt() + int array [] = new int [n]; + for(i in 0 until n) + { + array[i] = read.nextLine().toInt() + } + pancakesort (array, n); + for (i in 0 until n) + { + println(array[i] + " "); + } + } +} + +/* +Input +5 4 3 2 1 +Output +1 2 3 4 5 +*/ diff --git a/Pancake_Sort/Pancake_Sort.php b/Pancake_Sort/Pancake_Sort.php new file mode 100644 index 000000000..798cb6877 --- /dev/null +++ b/Pancake_Sort/Pancake_Sort.php @@ -0,0 +1,75 @@ + 1; $currentSize--) + { + //finds the index of the maximum element in the array + $maxIndex = findMaxIndex($arr, $currentSize); + //if the maximum index is not at the end of the current array then move the element to the end + if ($maxIndex != $currentSize-1) + { + //moves maximum number to the beginning + reverseArray($arr, $maxIndex); + //moves maximum number to the end by reversing the array + reverseArray($arr, $currentSize-1); + } + } +} + +//reverses the array from index 0 to index +function reverseArray(&$arr, $index) +{ + $startIndex = 0; + //reverses till the startindex is not greater than index provided + while ($startIndex < $index) + { + //swapping of elements + $temp = $arr[$startIndex]; + $arr[$startIndex] = $arr[$index]; + $arr[$index] = $temp; + //increasing starting Index of an array + $startIndex++; + //decreasing ending index of an array + $index--; + } +} + +//Find the index of the maximum element in an array +function findMaxIndex($arr, $num) +{ + $maxIndex = 0; + for ($i = 0; $i < $num; $i++) + { + if ($arr[$i] > $arr[$maxIndex]) + { + $maxIndex = $i; + } + } + return $maxIndex; +} + +$arr = array(112,65,12,56,100,93,20); +//Counts the number of elements in the array +$num = count($arr); + +pancakeSort($arr, $num); + +echo("Sorted Array is:\n"); +//Prints the sorted array +for($i = 0;$i < $num; $i++) +{ + print($arr[$i]." "); +} + +return 0; + +/* +Input: + 112,65,12,56,100,93,20 + +Output: + 12,20,56,65,93,100,112 +*/ +?> diff --git a/Pancake_sort/pancakesort.js b/Pancake_sort/pancakesort.js new file mode 100644 index 000000000..3caa25c4f --- /dev/null +++ b/Pancake_sort/pancakesort.js @@ -0,0 +1,46 @@ +//implementation of pancake sorting in JS +var n = prompt("enter the size of an array required"); +var arr = new Array(); +//taking input for array +for (let i = 0; i < n; i++) { + arr[i] = prompt("element" + (i + 1) + ":"); + arr[i] = parseInt(arr[i]); +} +var count = 0; +for (let i = 0; i < n - 1; i++) { + let max = arr[0]; + let m = 0, + t = m; + //finding maximum element from unsorted array + for (let j = 1; j < n - count; j++) { + if (arr[j] > max) { + max = arr[j]; + t = j; + } + } + if (t != m) { + let newarr; + //reversing the array until the maximum element position + newarr = arr.slice(0, t + 1).reverse(); + for (let i = 0; i < t + 1; i++) { + arr[i] = newarr[i]; + } + } + let neww; + //reversing the whole unsorted array + neww = arr.slice(0, n - count).reverse(); + for (let i = 0; i < n - count; i++) { + arr[i] = neww[i]; + } + count++; +} +console.log("the sorted array is " + arr); + +/* sample input-output +enter the size of an array required: 5 +element 1:56 +element 2:23 +element 3:78 +element 4:18 +element 5:9 +the sorted array is 9,18,23,56,78 */ diff --git a/Pascal_Triangle/Pascal_Triangle.java b/Pascal_Triangle/Pascal_Triangle.java new file mode 100644 index 000000000..3a0fda487 --- /dev/null +++ b/Pascal_Triangle/Pascal_Triangle.java @@ -0,0 +1,51 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.*; + +class Pascal_Triangle { + public static void main (String[] args) throws IOException{ + // Taking The Input from User + System.out.print("Enter the number of rows to be printed: "); + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + // Converting String Into Integer + int rows = Integer.parseInt(br.readLine()); + // Calling the Pascal Class + new Pascal(rows); + } +} + +class Pascal { + Pascal(int n) + { + for(int row = 1; row <= n; row++) + { + // Initializing the Initial Value of Pascal Value as 1 + int pascal_value = 1; + // For Pring Blank Space + for(int i = 1; i < n - row + 1; i++){ + System.out.print(" "); + } + System.out.print(" "); + // For calculating the Pascal Value + for(int i = 1; i <= row; i++) + { + // Assigning the Printable string to string s and printing the s + String s = " " + pascal_value + " "; + System.out.print(s); + // Calculating the New Pascal Value + pascal_value = pascal_value * (row - i) / i; + } + System.out.println(); + } + } +} + +//Input: +//Enter the number of rows to be printed: 5 + +//Output: +// 1 +// 1 1 +// 1 2 1 +// 1 3 3 1 +// 1 4 6 4 1 diff --git a/Pascal_Triangle/Pascal_Triangle.py b/Pascal_Triangle/Pascal_Triangle.py new file mode 100644 index 000000000..532b64c48 --- /dev/null +++ b/Pascal_Triangle/Pascal_Triangle.py @@ -0,0 +1,30 @@ +def Pascal_Triangle(n): + for row in range(1, n + 1): + # Initializing the Initial Value of Pascal Value as 1 + pascal_value = 1 + # For printing blank spaces + for i in range(1, n - row + 1): + print(' ', end=' ') + # For calculating the pascal value + for i in range(1, row + 1): + # Creating the printable string and printing the string + s = ' ' + str(pascal_value) + ' ' + print(s, end = " ") + # Calculating the new Pascal Value + pascal_value = int(pascal_value * (row - i) / i) + print(end = '\n') + +# Taking the Input from the user +rows = int(input("Enter the number of rows to be printed: ")) +# Calling the Function +Pascal_Triangle(rows) + +# Input: +# Enter the number of rows to be printed: 5 + +# Output: +# 1 +# 1 1 +# 1 2 1 +# 1 3 3 1 +# 1 4 6 4 1 diff --git a/Pigeonhole_Sort/Pigeonhole_Sort.go b/Pigeonhole_Sort/Pigeonhole_Sort.go new file mode 100644 index 000000000..ee636d4b0 --- /dev/null +++ b/Pigeonhole_Sort/Pigeonhole_Sort.go @@ -0,0 +1,65 @@ +package main +import ( + "fmt" +) + +func PigeonholeSort(a []int) { + arrayLength := len(a) + if arrayLength == 0 { // this is used to handle for the edge case when there is nothing to sort + return + } + min := a[0] + max := a[0] + for _, value := range a { // get the min and max values of the array + if value < min { + min = value + } + if value > max { + max = value + } + } + size := max - min + 1 + holes := make(map[int][]int, size) // create the pigeon holes with the initial values + for i := 0; i < size; i++ { + holes[i] = []int{} + } + for _, value := range a { // for every value in the array, put it in the corresponding pigeonhole + holes[value - min] = append(holes[value-min], value) + } + + // finally, replace the values in the array with the values from each pigeonhole in order + j := 0 + for i := 0; i < size; i++ { + for _, value := range holes[i] { + a[j] = value + j++ + } + } +} + +func main() { + var x int + fmt.Printf("Enter the size of the array : ") + fmt.Scan(&x) + fmt.Printf("Enter the elements of the array : ") + a := make([]int, x) + for i := 0; i < x; i++ { + fmt.Scan(&a[i]) + } + randomSlice := a // A copy of the array 'a' is assigned to 'randomSlice' + PigeonholeSort(randomSlice) + fmt.Println("Sorted Slice: ", randomSlice) +} + + +/* + +Sample Input : + Enter the size of the array : 5 + Enter the elements of the array : 67 23 90 12 7 + +Sample Output : + The sorted array is : [7 12 23 67 90] + +*/ + diff --git a/Pigeonhole_Sort/Pigeonhole_Sort.kt b/Pigeonhole_Sort/Pigeonhole_Sort.kt new file mode 100644 index 000000000..7462ac862 --- /dev/null +++ b/Pigeonhole_Sort/Pigeonhole_Sort.kt @@ -0,0 +1,57 @@ +import java.util.* + +fun main(args: Array) { + + var n: Int = Integer.valueOf(readLine()) + var arr = arrayOfNulls(n) + var read = Scanner(System.`in`) + for(i in 0..(n-1)){ + arr[i] = read.nextInt() + } + var min = arr[0] + var max = arr[0] + //finding the minimum and maximum elements in the array + for(i in 0..(n-1)){ + if(arr[i]!! < min!!) + min = arr[i] + if(arr[i]!! > max!!) + max = arr[i] + } + + var noOfPigeonHoles = max!! - min!! + 1 //size of the pigeonhole array + var pigeonHoles = IntArray(noOfPigeonHoles) //pigeonhole array + Arrays.fill(pigeonHoles,0) //initializing all the elements to 0 + + //pigeonhole sort algorithm + for(i in 0..(n-1)){ + var x = arr[i]!! - min + pigeonHoles[x]++ + } + var index = 0 + + for(i in 0..(noOfPigeonHoles-1)){ + while(pigeonHoles[i] > 0){ + arr[index++] = i + min + pigeonHoles[i]-- + } + } + + //printing the array + println("Sorted Array") + for(i in 0..(n-1)){ + println(arr[i]) + } +} + +/* +Sample Input +5 +1 5 4 2 0 +Sample Output +Sorted Array +0 +1 +2 +4 +5 +*/ diff --git a/Postfix_Evaluation/Postfix _Evaluation.c b/Postfix_Evaluation/Postfix _Evaluation.c new file mode 100644 index 000000000..c64c510b9 --- /dev/null +++ b/Postfix_Evaluation/Postfix _Evaluation.c @@ -0,0 +1,86 @@ +//Postfix Evaluation +#include +#include +#include + +struct stack +{ + char A[100]; + int Top; +}; + +void push(struct stack *ps, char x) +{ + if(ps -> Top == 99) + printf("\nStack is Full\n"); + else + { + ps -> Top = ps -> Top + 1; + ps -> A[ps -> Top] = x; + } +} + +int evaluate(int op1, int op2, char c) +{ + if(c == '+') + return op1 + op2; + else if(c == '-') + return op1 - op2; + else if(c == '*') + return op1 * op2; + else if(c == '/') + return op1 / op2; +} + +void print(struct stack s) +{ + int i; + for(i = 0 ; i <= s.Top ; i++) + printf("%d\t", s.A[i]); +} + +int pop(struct stack *ps) +{ + int x; + if(ps -> Top == -1) + printf("Stack is empty!Element cant be deleted\n"); + else + { + x = ps -> A[ps -> Top]; + ps -> Top = ps -> Top - 1; + return x; + } +} + +int main() +{ + int op1, op2, x, i; + char optr; + struct stack s; + s.Top = -1; + printf("Enter the postfix exp to be evaluated \n"); + gets(s.A); + for(i = 0; i < strlen(s.A); i++) + { + if(isdigit(s.A[i])) + push(&s, s.A[i] - '0'); + else if(s.A[i] == '+' || s.A[i] == '-' || s.A[i] == '*' || s.A[i] == '/') + { + op1 = pop(&s); + op2 = pop(&s); + optr = s.A[i]; + x = evaluate(op2, op1, optr); + push(&s, x); + } + } + + printf("The result is : "); + print(s); + printf("\n"); +} + +/*Input - Output Sample +Enter the postfix exp to be evaluated +2 3 1 * + 9 - +The result is : -4 +*/ diff --git a/Postman_Sort/Postman_Sort.cpp b/Postman_Sort/Postman_Sort.cpp new file mode 100644 index 000000000..f25c4b651 --- /dev/null +++ b/Postman_Sort/Postman_Sort.cpp @@ -0,0 +1,98 @@ +/* +* C++ Implementation for Postman Sort Algorithm. +* This is the algorithm used by letter-sorting machines in the post office: +* first states, then post offices, then routes, etc. +* Since keys are not compared against each other, sorting time is O(cn), +* where c depends on the size of the key and number of buckets. +*/ + +#include +using namespace std; + +void arrange(int p, int s); +int temp, maxdigits = 0, c = 0; +int t1, t2, k, t, n = 1, i, j; +int arr[100], arr1[100]; +int main(){ + int count, max; + cout << "The size of the Array : " ; + cin >> count; + int arr[count]; + for(i = 0; i < count; i++) + cin >> arr[i]; + + cout << "\nThe Unsorted Array is : \n" ; + for(i = 0; i < count; i++) + cout << arr[i] << " "; + + for(i = 0; i < count; i++) { + // first element in t + t = arr[i]; + // Calculating the Number of digits using logarithmic + c = log10(arr[i]); + // number of digits in a each number + if(maxdigits < c) + maxdigits = c; + } + + while(--maxdigits) + n = n * 10; + + for(i = 0; i < count; i++) { + // MSB - Dividing by particular base + max = arr[i] / n; + t = i; + for(j = i + 1; j < count; j++) { + if(max > arr[j] / n) { + max = arr[j] / n; + t = j; + } + } + swap(arr1[t], arr1[i]); + swap(arr[t], arr[i]); + } + + while (n >= 1) { + for(i = 0; i < count;) { + t1 = arr[i] / n; + for(j = i + 1; t1 == (arr[j] / n); j++); + arrange(i, j); + i = j; + } + n = n / 10; + } + + cout << "\nThe Sorted Array is : \n"; + for(int i = 0; i < count; i++) + cout << arr[i] << " "; + cout << "\n"; + return 0; +} + +// Function to arrange the of sequence having same base +void arrange(int p, int s) { + for(int i = p; i < s - 1; i++) { + for(int j = i + 1; j < s; j++) { + if(arr1[i] > arr1[j]) { + // swap arr1[i] and arr1[j] + swap(arr1[i], arr1[j]); + + temp = arr[i] % 10; + arr[i] = arr[j] % 10; + arr[j] = temp; + } + } + } +} + +/* +INPUT : +The size of the Array : 10 +70, 80, 20, 50, 10, 60, 40, 100, 90, 30 + +OUTPUT : +The Unsorted Array is : +70 80 20 50 10 60 40 100 90 30 +The Sorted Array is : +10 20 30 40 50 60 70 80 90 100 +*/ diff --git a/Postman_Sort/Postman_Sort.cs b/Postman_Sort/Postman_Sort.cs new file mode 100644 index 000000000..e44363c54 --- /dev/null +++ b/Postman_Sort/Postman_Sort.cs @@ -0,0 +1,112 @@ +//Program to Sort the array using Postman Sort + +using System; +namespace Declaring_Method +{ + public class Postman_Sort + { + public static int[] arr = new int[100]; + public static int[] arr1 = new int[100]; + public int temp, max, count, maxdigits = 0, c = 0; + public static void Main(string[] args) + { + + Postman_Sort p = new Postman_Sort(); + int t1, t, n = 1, i, j; + Console.WriteLine("Enter the Size of the array "); + p.count = Convert.ToInt32(Console.ReadLine()); + Console.WriteLine("Enter the elements of the array :-"); + for (i = 0; i < p.count; i++) + { + Console.Write("Element - {0} : ", i); + arr[i] = Convert.ToInt32(Console.ReadLine()); + arr1[i] = arr[i]; + } + + //Finding the longest digits in the array and no of elements in that digit + for (i = 0; i < p.count; i++) + { + t = arr[i]; + while (t > 0) + { + p.c++; //Counting the no of elements of a digit + t = t / 10; + } + if (p.maxdigits < p.c) + p.maxdigits = p.c; //Storing the length of longest digit + p.c = 0; + } + for (i = 1; i < p.maxdigits; i++) + { + n = n * 10; + } + + for (i = 0; i < p.count; i++) + { + p.max = arr[i] / n; //Dividing by a particular base + t = i; + for (j = i + 1; j < p.count; j++) + { + if (p.max > (arr[j] / n)) + { + p.max = arr[j] / n; + t = j; + } + } + p.temp = arr1[t]; + arr1[t] = arr1[i]; + arr1[i] = p.temp; + p.temp = arr[t]; + arr[t] = arr[i]; + arr[i] = p.temp; + } + while (n >= 1) + { + for (i = 0; i < p.count;) + { + t1 = arr[i] / n; + for (j = i + 1; t1 == (arr[j] / n); j++); + arrange(i, j); + i = j; + } + n = n / 10; + } + Console.WriteLine("Sorted Array"); + for (i = 0; i < p.count; i++) + Console.Write("{0} ", arr1[i]); //Displaying the Sorted array + } + + //Arranging the elements + public static void arrange(int k, int n) + { + Postman_Sort p = new Postman_Sort(); + int i, j; + for (i = k; i < (n - 1); i++) + { + for (j = i + 1; j < n; j++) + { + if (arr1[i] > arr1[j]) + { + p.temp = arr1[i]; + arr1[i] = arr1[j]; + arr1[j] = p.temp; + p.temp = (arr[i] % 10); + arr[i] = (arr[j] % 10); + arr[j] = p.temp; + } + } + } + } + } +} +/* Enter the Size of the array +6 +Enter the elements of the array :- +Element - 0 : 43 +Element - 1 : 35 +Element - 2 : 75 +Element - 3 : 1 +Element - 4 : 68 +Element - 5 : 453 +Sorted Array +1 35 43 68 75 453 */ diff --git a/Postman_Sort/Postman_Sort.dart b/Postman_Sort/Postman_Sort.dart new file mode 100644 index 000000000..999841484 --- /dev/null +++ b/Postman_Sort/Postman_Sort.dart @@ -0,0 +1,99 @@ +// Importing required libraries +import 'dart:io'; +import 'dart:math'; + +// Declaring required variables +int temp, max, count, maxdigits = 0, c = 0; +int t1, t, i, j; +List array, array1; +int n = 1; + +// Method to arrange numbers that have same base +void arrange(int k, int n){ + for(int i = k; i < n - 1; i ++){ + for(int j = i + 1; j < n; j ++){ + if(array1[i] > array1[j]){ + temp = array1[i]; + array1[i] = array1[j]; + array1[j] = temp; + temp = array[i]%10; + array[i] = array[j]%10; + array[j] = temp; + } + } + } +} + + +void main(){ + + // Input of the size of the array + print("Enter the number of elements in the array:"); + var input = stdin.readLineSync(); + count = int.parse(input); + + // Input of array elements + print("Enter the array elements:"); + input = stdin.readLineSync(); + var lis = input.split(' '); + array = lis.map(int.parse).toList(); + array1 = lis.map(int.parse).toList(); + + // Finding the maximum possible length of the numbers in the array + for(i = 0; i < count; i ++){ + t = array[i]; + c = (log(array[i])/log(10)).floor(); + if(c > maxdigits){ + maxdigits = c; + } + } + + for(i = 0; i < maxdigits - 1; i ++){ + n = n * 10; + } + + for(i = 0; i < count; i ++){ + max = (array[i]/n).floor(); + t = i; + for(j = i + 1; j < count; j ++){ + if(max > (array[j]/n).floor()){ + max = (array[j]/n).floor(); + t = j; + } + } + + // Swapping + temp = array1[t]; + array1[t] = array1[i]; + array1[i] = temp; + temp = array[t]; + array[t] = array[i]; + array[i] = temp; + } + + while(n >= 1){ + for(i = 0; i < count;){ + t1 = (array[i]/n).floor(); + for(j = i + 1; j < count && t1 == (array[j]/n).floor(); j ++){ + arrange(i, j); + } + i = j; + } + n = (n / 10).floor(); + } + + print("The sorted array is:"); + print(array.join(" ")); +} + +/** + * Sample Input and Output + * ---------------------------- + * Enter the number of elements in the array: + * 10 + * Enter the array elements: + * 10 9 8 7 6 5 4 3 2 1 + * The sorted array is: + * 1 2 3 4 5 6 7 8 9 10 + * + */ diff --git a/Postman_Sort/Postman_Sort.js b/Postman_Sort/Postman_Sort.js new file mode 100644 index 000000000..01c6ecc65 --- /dev/null +++ b/Postman_Sort/Postman_Sort.js @@ -0,0 +1,88 @@ +/* +* JavaScript Implementation for Postman Sort Algorithm +*/ + +let temp, max, count, maxdigits = 0, c = 0; +let t1, t2, k, t, n = 1, p, s; + +/* Function to arrange the of sequence having same base */ +function arrange(p, s) { + for(var i = p; i < s - 1; i++) { + for(var j = i + 1; j < s; j++) { + if(arr1[i] > arr1[j]) { + // swap array1[i] and array1[j] + swap (arr1[i], arr1[j]); + + temp = arr[i] % 10; + arr[i] = arr[j] % 10; + arr[j] = temp; + } + } + } +} + +count = 10; +console.log("The size of the Array : " + count); +let arr = [70, 80, 20, 50, 10, 60, 40, 100, 90, 30]; +console.log("The Unsorted Array is : "); +console.log(arr); + +let arr1 = new Array(); +for(let i = 0; i < count; i++) { + // first element in t + t = arr[i]; + // Calculating the Number of digits using logarithmic + c = Math.trunc(Math.log(arr[i] / Math.log(10))); + // number of digits in a each number + if(maxdigits < c) + maxdigits = c; +} + +while(--maxdigits) + n = n * 10; + +for(var i = 0; i < count; i++) { + // MSB - Dividing by particular base + max = arr[i] / n; + t = i; + for(var j = i + 1; j < count; j++) { + if(max > arr[j] / n) { + max = arr[j] / n; + t = j; + } + } + temp = arr1[t]; + arr1[t] = arr1[i]; + arr1[i] = temp; + temp = arr[t]; + arr[t] = arr[i]; + arr[i] = temp; +} + +function swap(x, y) { + var t = x; + x = y; + y = t; +} + +while (n >= 1) { + for(var i = 0; i < count;) { + t1 = arr[i] / n; + for(j = i + 1; t1 == (arr[j] / n); j++); + arrange(i, j); + i = j; + } + n = n / 10; +} + +console.log("Sorted Array is : "); +console.log(arr); + +/* +INPUT : +The size of the Array : 10 +The Unsorted Array is : [70, 80, 20, 50, 10, 60, 40, 100, 90, 30] + +OUTPUT : +Sorted Array is : [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] +*/ diff --git a/Postman_Sort/readme.md b/Postman_Sort/readme.md new file mode 100644 index 000000000..fc4ef136d --- /dev/null +++ b/Postman_Sort/readme.md @@ -0,0 +1,104 @@ +# Postman Sort + +Postman sort works by sorting the integers of an array from their most significant digits to their least +significant digits. In the Postman sort the integer having most significant digits and the number of +elements in that integer is determined, the length of the longest integer is stored. All the elements in the +array are divided by a particular base. The elements of the array are sorted on the basis of the most significant +digit to the least significant digit i.e. from leftmost to rightmost digit. + +## Example + +Let's arrange the numbers in ascending order using postman sort. + +- Unsorted List + +The input array contains 7 elements which are {25, 432, 788, 130, 23, 121, 564} + +- Iteration 1 + +The elements of the array being sorted on the basis of the most significant digit, *it becomes {25, 23, 130, 121, 432, 564, 788}* + +- Iteration 2 + +The elements of the array being sorted on the basis of the second most significant digit, *it becomes {25, 23, 121, 130, 432, 564, 788}* + +- Iteration 3 + +At last those elements of the array are compared which have same value of significant digit and if they are not in correct +order, the elements gets swapped and are arranged in desired order. The array after getting sorted *becomes +{23, 25, 121, 130, 432, 564, 788}* + +*In this way the elements of the array are sorted on the basis of their significant digits.* + +## Algorithm + +1.Compare the leftmost digit of the elements of the array then the next to it and so on.
+ +2.If the elements are not in correct order swap them according to their significant digit.
+ +3.The function recurses which compares the elements having same value of significant digit and arranges the elements in correct order.
+ +## Pseudocode +``` +declare temp, max, count, maxdigits = 0, c = 0 +declare t1, t ,i, j +Initialise n = 1 +Input the number of elements in the array and store their values in arr[], arr1[] +for(i = 0; i < count; i++) + t = arr[i] + while(t > 0) + c++ + t = t/10 + if(maxdigits < c) + maxdigits = c + c = 0 + +for(i = 0; i < maxdigits; i++) + n = n * 10 +for(i = 0; i < count; i++) + max = arr[i] / n + t = i + for(j = i + 1; j < count; j++) + if(max > (arr[j] / n)) + max = arr[j] / n + t = j + temp = arr1[t] + arr1[t] = arr1[i] + arr1[i] = temp + temp = arr[t] + arr[t] = arr[i] + arr[i] = temp +while(n >= 1) + for(i = 0; i < count;) + t1 = arr[i] / n + for(j = i + 1; t1 == (arr[j]/n); j++); + arrange(i, j) + i = j + n = n / 10 + +void arrange(int k, int n) + for(i = k; i < n - 1; i++) + for(j = i + 1; j < n; j++) + if(arr1[i] > arr[j]) + temp = arr1[i] + arr1[i] = arr1[j] + arr1[j] = temp + temp = arr[i] % 10 + arr[i] = arr[j] % 10 + arr[j] = temp + +``` + +## Complexity + + Time Complexity = d * (n + k) + Space Complexity = n + 2^d + +where +>d = number of digits
+>n = number of keys
+>k = size of bucket + +## Implementation +* [C# Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Postman_Sort/Postman_Sort.cs) + diff --git a/Power_Of_Two/Power_Of_Two.js b/Power_Of_Two/Power_Of_Two.js new file mode 100644 index 000000000..e74f9922c --- /dev/null +++ b/Power_Of_Two/Power_Of_Two.js @@ -0,0 +1,33 @@ +/* +To check whether a number is a power of two or not, +we do bitwise "and" of number and number - 1, if the +result is zero the number is a power of two. +Example: number = 4, then 4 & 3 i.e 100 && 011 is 0 +16 & 15 i.e 10000 & 01111 = 0 +This is true for all powers of two. +*/ + +function isPowerofTwo(n){ + return n && ( ! ( n & (n - 1) )); +} + +var num = parseInt(prompt("Enter a number to check:")); + +if(isPowerofTwo(num)){ + console.log("The number is a power of two"); +} +else{ + console.log("The number is not a power of two"); +} + + +/* +Input: +64 +Output: +The number is a power of two +Input: +5 +Output: +The number is not a power of two +*/ diff --git a/Preemptive.cpp b/Preemptive.cpp new file mode 100644 index 000000000..4f02f38ed --- /dev/null +++ b/Preemptive.cpp @@ -0,0 +1,231 @@ +About:In priority scheduling, a number is assigned to each process that indicates its priority level. +Lower the number, higher is the priority. In this type of scheduling algorithm, if a newer process arrives, that is having a higher +priority than the currently running process, then the currently running process is preempted. + +Program for preemptive priority +#include +using namespace std; + +struct Process { + int processID; + int burstTime; + int tempburstTime; + int responsetime; + int arrivalTime; + int priority; + int outtime; + int intime; +}; + +// It is used to include all the valid and eligible +// processes in the heap for execution. heapsize defines +// the number of processes in execution depending on +// the current time currentTime keeps a record of +// the current CPU time. +void insert(Process Heap[], Process value, int* heapsize,int* currentTime) +{ + int start = *heapsize, i; + Heap[*heapsize] = value; + if (Heap[*heapsize].intime == -1) + Heap[*heapsize].intime = *currentTime; + ++(*heapsize); + + // Ordering the Heap + while (start != 0 && Heap[(start - 1) / 2].priority > Heap[start].priority) { + Process temp = Heap[(start - 1) / 2]; + Heap[(start - 1) / 2] = Heap[start]; + Heap[start] = temp; + start = (start - 1) / 2; + } +} + +// It is used to reorder the heap according to +// priority if the processes after insertion +// of new process. +void order(Process Heap[], int* heapsize, int start) +{ + int smallest = start; + int left = 2 * start + 1; + int right = 2 * start + 2; + if (left < *heapsize && Heap[left].priority = 1) { + Heap[0] = Heap[*heapsize]; + order(Heap, heapsize, 0); + } + return min; +} + +// Compares two intervals according to staring times. +int compare(Process p1, Process p2) +{ + if (p1.arrivalTime < p2.arrivalTime) + return 1; + else + return 0; +} + +// This function is responsible for executing +// the highest priority extracted from Heap[]. +void scheduling(Process Heap[], Process array[], int n,int* heapsize, int* currentTime) +{ + if (heapsize == 0) + return; + + Process min = extractminimum(Heap, heapsize, currentTime); + min.outtime = *currentTime + 1; + --min.burstTime; + printf("process id = %d\tcurrent_time = %d\n",min.processID, *currentTime); + + // If the process is not yet finished + // insert it back into the Heap*/ + if (min.burstTime > 0) { + insert(Heap, min, heapsize, currentTime); + return; + } + + for (int i = 0; i < n; i++) + if (array[i].processID == min.processID) { + array[i] = min; + break; + } +} + +// This function is responsible for +// managing the entire execution of the +// processes as they arrive in the CPU +// according to their arrival time. +void priority(Process array[], int n) +{ + sort(array, array + n, compare); + + int totalwaitingtime = 0, totalbursttime = 0, + totalturnaroundtime = 0, i, insertedprocess = 0, + heapsize = 0, currentTime = array[0].arrivalTime, + totalresponsetime = 0; + + Process Heap[4 * n]; + + // Calculating the total burst time + // of the processes + for (int i = 0; i < n; i++) { + totalbursttime += array[i].burstTime; + array[i].tempburstTime = array[i].burstTime; + } + + // Inserting the processes in Heap + // according to arrival time + do { + if (insertedprocess != n) { + for (i = 0; i < n; i++) { + if (array[i].arrivalTime == currentTime) { + ++insertedprocess; + array[i].intime = -1; + array[i].responsetime = -1; + insert(Heap, array[i], &heapsize, ¤tTime); + } + } + } + scheduling(Heap, array, n, &heapsize, ¤tTime); + ++currentTime; + if (heapsize == 0 && insertedprocess == n) + break; + } while (1); + + for (int i = 0; i < n; i++) { + totalresponsetime += array[i].responsetime; + totalwaitingtime += (array[i].outtime - array[i].intime - + array[i].tempburstTime); + totalbursttime += array[i].burstTime; + } + printf("\n\nAverage waiting time = %f\n",((float)totalwaitingtime / (float)n)); + printf("\nAverage response time =%f\n",((float)totalresponsetime / (float)n)); + printf("\nAverage turn around time = %f\n",((float)(totalwaitingtime + totalbursttime) / (float)n)); +} + +// Driver code +int main() +{ + int n, i; + Process a[5]; + printf("Enter the no.of Process:-"); + cin>>n; + printf("Arival_Time Burst_Time Priority\n"); + for(int i=0;i>a[i].arrivalTime; + cin>>a[i].burstTime; + cin>>a[i].priority; + } + priority(a, n); + return 0; +} + + + +Output:- +Enter the no.of Process:-5 +Arival_Time Burst_Time Priority + 1 4 3 + 3 7 2 + 0 9 5 + 4 3 4 + 2 5 1 +process id = 3 current_time = 0 +process id = 1 current_time = 1 +process id = 5 current_time = 2 +process id = 5 current_time = 3 +process id = 5 current_time = 4 +process id = 5 current_time = 5 +process id = 5 current_time = 6 +process id = 2 current_time = 7 +process id = 2 current_time = 8 +process id = 2 current_time = 9 +process id = 2 current_time = 10 +process id = 2 current_time = 11 +process id = 2 current_time = 12 +process id = 2 current_time = 13 +process id = 1 current_time = 14 +process id = 1 current_time = 15 +process id = 1 current_time = 16 +process id = 4 current_time = 17 +process id = 4 current_time = 18 +process id = 4 current_time = 19 +process id = 3 current_time = 20 +process id = 3 current_time = 21 +process id = 3 current_time = 22 +process id = 3 current_time = 23 +process id = 3 current_time = 24 +process id = 3 current_time = 25 +process id = 3 current_time = 26 +process id = 3 current_time = 27 + + +Average waiting time = 9.600000 + +Average response time =3.400000 + +Average turn around time = 15.200000 + diff --git a/Prims_Algorithm/Prims_Algorithm.cs b/Prims_Algorithm/Prims_Algorithm.cs new file mode 100644 index 000000000..76e955f74 --- /dev/null +++ b/Prims_Algorithm/Prims_Algorithm.cs @@ -0,0 +1,77 @@ +using System; + +namespace Declaring_Method +{ + public class Prim_Algorithm + { + public static void Main(string[] args) + { + int a = 0, b = 0, u = 0, v = 0, n, i, j, edge_no = 1; + int min, mincost = 0; + int[] visited = new int[100]; + int[, ] cost = new int[10, 10]; + + Console.WriteLine("Enter the number of Nodes"); + n = Convert.ToInt32(Console.ReadLine()); + Console.WriteLine("Enter the adjency matrix"); + + //Intilize all visited elements to 0 + for (i = 0; i < 100; i++) + { + visited[i] = 0; + } + + //Taking Matrix Input from the User + for (i = 1; i <= n; i++) + { + for (j = 1; j <= n; j++) + { + cost[i, j] = Convert.ToInt32(Console.ReadLine()); + //Initialize Cost Matrix to Infintiy if user input is 0 + if (cost[i, j] == 0) + cost[i, j] = 999; + } + } + visited[1] = 1; + Console.WriteLine(" "); + + while (edge_no < n) + { + for (i = 1, min = 999; i <= n; i++) + for (j = 1; j <= n; j++) + if (cost[i, j] < min) + if (visited[i] != 0) + { + min = cost[i, j]; + //Storing Position + a = u = i; + b = v = j; + } + // Print the Edge Number with its Cost + if (visited[u] == 0 || visited[v] == 0) + { + Console.WriteLine("Edge {0} : ({1} {2}) cost:{3} ", edge_no++, a, b, min); + mincost += min; // Calculating minimum Cost + visited[b] = 1; + } + cost[a, b] = cost[b, a] = 999; + } + Console.WriteLine("Minimum Cost : {0}", mincost); + } + } +} + +/*Enter the number of Nodes +5 +Enter the adjency matrix +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 + +Edge 1 : (1 2) cost:2 +Edge 2 : (2 3) cost:3 +Edge 3 : (2 5) cost:5 +Edge 4 : (1 4) cost:6 +Minimum Cost : 16 */ diff --git a/Prims_Algorithm/Prims_Algorithm.dart b/Prims_Algorithm/Prims_Algorithm.dart new file mode 100644 index 000000000..695b5929b --- /dev/null +++ b/Prims_Algorithm/Prims_Algorithm.dart @@ -0,0 +1,166 @@ +/* +Prim's algorithm is to find minimum cost spanning tree (as Kruskal's algorithm) +uses the greedy approach. Prim's algorithm shares a similarity with the +shortest path first algorithms. + +Prim's algorithm, in contrast with Kruskal's algorithm, treats the nodes as a +single tree and keeps on adding new nodes to the spanning tree from the +given graph. + */ + +import 'dart:io'; +import 'dart:svg'; + +var INT_MAX = 9223372036854775807; + +int minnode(dist, fingraph, V) +{ + var min = INT_MAX; + var min_index = 0; + + for (var v = 0; v < V; v++) { + if (fingraph[v] == false && dist[v] < min) { + min = dist[v]; + min_index = v; + } + } + + return min_index; +} + +void printMST(parent, graph, V) +{ + print("Edge \tWeight\n"); + for (var i = 1; i < V; i++) { + print('${parent[i]} - ${i} \t ${graph[i][parent[i]]} \n'); + } +} + +void prim_mst(graph, V) +{ + var parent = new List(V); + var dist = new List(V); + var fingraph = new List(V); + + for (var i = 0; i < V; i++) + { + dist[i] = INT_MAX; + fingraph[i] = false; + } + + dist[0] = 0; + parent[0] = -1; + + for (var count = 0; count < V - 1; count++) + { + var u = minnode(dist, fingraph, V); + fingraph[u] = true; + + for (var v = 0; v < V; v++) + { + if (graph[u][v] > 0 && fingraph[v] == false && graph[u][v] < dist[v]) + { + parent[v] = u; + dist[v] = graph[u][v]; + } + } + } + + printMST(parent, graph, V); +} + +int main() +{ + print('Enter number of nodes 0 to ?'); + + var n = int.parse(stdin.readLineSync()); + var max_edges = (n + 1) * (n); + var adjmat = new List.generate(n + 1, (_) => new List(n + 1)); + + for(var i = 0; i <= n; i++) + { + for(var j = 0; j <= n; j++) + { + adjmat[i][j] = 0; + } + } + + print('Enter in the following format\nsrc\ndest\nweight\n'); + for(var i = 0; i < max_edges; i++) + { + var src = int.parse(stdin.readLineSync()); + var dest = int.parse(stdin.readLineSync()); + var weight = int.parse(stdin.readLineSync()); + + print('*' * 20); + + if((src == -1) && (dest == -1)) + { + break; + } + + if(src > n || dest > n || src < 0 || dest < 0) + { + print('Invalid edge!\n'); + i--; + } + + else + { + adjmat[src][dest] = weight; + } + } + + prim_mst(adjmat, n + 1); + return 0; +} + +/* +Input: +Enter number of nodes 0 to ? +4 +Enter in the following format +Source +Destination +Weight + +Let us create the following graph + + (1)____1___(2) + / \ / \ + 3 4 4 6 + / \ / \ + / \ / \ +(0)___5___(5)____5___(3) + \ | / + \ | / + \ | / + \ 2 / + 6 | 8 + \ | / + \ | / + \ | / + \ | / + (4) + + adjmat = [ + [ 0, 3, 0, 0, 6, 5 ], + [ 3, 0, 1, 0, 0, 4 ], + [ 0, 1, 0, 6, 0, 4 ], + [ 0, 0, 6, 0, 8, 5 ], + [ 6, 0, 0, 8, 0, 2 ], + [ 5, 4, 4, 5, 2, 0 ] + ]; + +Output: + +Edge Weight + +0 - 1 3 +1 - 2 1 +1 - 5 4 +5 - 4 2 +5 - 3 5 +Minimum Weight is 15 + */ + diff --git a/Prims_Algorithm/Prims_Algorithm.js b/Prims_Algorithm/Prims_Algorithm.js new file mode 100644 index 000000000..cf2d2d18b --- /dev/null +++ b/Prims_Algorithm/Prims_Algorithm.js @@ -0,0 +1,81 @@ +/* Prim's algorithm is used to find minimum cost spanning tree (MST). It uses the greedy approach. */ + +// Represents a weighted edge from first to second +var Edge = function(first, second, weight) { + this.first = first; + this.second = second; + this.weight = weight; +}; + +// To create graph +var Graph = function() { + this.vertices = []; + this.edges = {}; + + // Add a node to the graph + this.addVertex = function(vertex) { + this.vertices.push(vertex); + this.edges[vertex] = []; + }; + + // Add a weighted edge from first to second + this.addEdge = function(first, second, weight) { + this.edges[first].push(new Edge(first, second, weight)); + this.edges[second].push(new Edge(second, first, weight)); + }; +}; + +// To get nearest vertex to visited vertices +function getMinVertex(g, result, visitedVertices) { + var min = [Infinity , null]; + for(var i = 0; i < result.length; i++) + for(var j = 0; j < g.edges[result[i]].length; j++) + if(g.edges[result[i]][j].weight < min[0] && visitedVertices[g.edges[result[i]][j].second] === undefined) + min = [g.edges[result[i]][j].weight, g.edges[result[i]][j].second]; + return min[1]; +} + +// To perform Prim's algorithm +function Prims(g) { + var result = []; + var visitedVertices = {}; + + // Start from node 0 + var start = g.vertices[0]; + result.push(start); + visitedVertices[start] = true; + + var min = getMinVertex(g, result, visitedVertices); + while(min != null) { + result.push(min); + visitedVertices[min] = true; + min = getMinVertex(g, result, visitedVertices); + } + + return result; +}; + +var g = new Graph(); + +// Vertices for the graph - Sample Input +g.addVertex(0); +g.addVertex(1); +g.addVertex(2); +g.addVertex(3); + +// Weighted edges for the graph - Sample Input +g.addEdge(0, 1, 3); +g.addEdge(1, 3, 1); +g.addEdge(1, 2, 5); +g.addEdge(2, 3, 8); + +var result = Prims(g); +console.log("Order in which vertices are visited during the implementation of Prim's Algorithm: ") +console.log(result); + +/* + Sample Input is as taken in the code. + Sample Output: + Order in which vertices are visited during the implementation of Prim's Algorithm: + 0,1,3,2 +*/ diff --git a/Prims_Algorithm/Prims_Algorithm.kt b/Prims_Algorithm/Prims_Algorithm.kt new file mode 100644 index 000000000..cda2a7905 --- /dev/null +++ b/Prims_Algorithm/Prims_Algorithm.kt @@ -0,0 +1,127 @@ +import java.util.* +internal class Edge(var from: Int, var to: Int, var weight: Int) + +internal object Prims { + /** + * Function to compute MST + * + * @param graph + * @return mst + */ + private fun prims(graph: ArrayList>): ArrayList { // ArrayList to store obtained MST + val mst = ArrayList() + // Priority Queue which gives minimum weight edge + val pq = PriorityQueue(Comparator { edge1: Edge?, edge2: Edge? -> + if (edge1!!.weight < edge2!!.weight) + return@Comparator -1 + else if (edge1.weight > edge2.weight) + return@Comparator 1 + else return@Comparator 0 }) + + // add the source vertex in Priority queue + pq.addAll(graph[0]) + var cost = 0.0 + val size = graph.size + val visited = BooleanArray(size) + // mark source vertex as visited + visited[0] = true + + // Keep extracting edges till priority is not empty + while (!pq.isEmpty()) { // extract edge with minimum weight from priority queue + val edge = pq.peek() + // pop the edge from priority queue + pq.poll() + if (visited[edge!!.to] && visited[edge.from]) continue + // mark the from vertex as visited + visited[edge.from] = true + // if the adjacent vertex to source is unvisited, add the edge to the priority queue + for (edge1 in graph[edge.to]) { + if (!visited[edge1!!.to]) pq.add(edge1) + } + // mark the adjacent vertex as visited + visited[edge.to] = true + // add the edge in minimum spanning tree + cost += edge.weight + mst.add(edge) + } + println("Total cost of MST: $cost") + return mst + } + + /** + * Function to create adjacency list representation of graph + * @param edges + * @param nodes + * @return graph + */ + private fun createGraph(edges: Array, nodes: Int): ArrayList> { // initialise graph as Adjacency List + val graph = ArrayList>() + // for adding Arraylist to Arraylist + for (i in 0 until nodes) graph.add(ArrayList()) + // Create adjacency list from the edge connectivity information + for (source in edges) { + val destination = Edge(source!!.from, source.to, source.weight) + graph[source.from].add(source) + graph[source.to].add(destination) + } + // Return constructed graph + return graph + } + + /** + * Main Function + * @param args + */ + @JvmStatic + fun main(args: Array) { // initialise number of nodes and edges + val nodes = 7 + val countEdges = 10 + /* Input Graph is: + 0 + / \ + / \ + 1 ------ 2 + / \ / \ + 3 -- 4 -- 5 -- 6 + */ + val edges = arrayOfNulls(countEdges) + // initialising edges with from, to and weight value + edges[0] = Edge(0, 1, 10) + edges[1] = Edge(0, 2, 15) + edges[2] = Edge(1, 2, 7) + edges[3] = Edge(2, 5, 6) + edges[4] = Edge(1, 3, 12) + edges[5] = Edge(1, 4, 9) + edges[6] = Edge(4, 5, 14) + edges[7] = Edge(3, 4, 13) + edges[8] = Edge(5, 6, 8) + edges[9] = Edge(2, 6, 12) + // Adjacency List representation of graph + val graph = createGraph(edges, nodes) + // ArrayList to store final MST obtained + val mst = prims(graph) + println("Minimum Spanning Tree:") + for (edge in mst) println(edge!!.from.toString() + " - " + edge.to + " : " + edge.weight) + } +} + +/** + * Input Graph is: + * 0 + * / \ + * / \ + * 1-----2 + * / \ / \ + * 3---4-5---6 + * + * Output: + * Total cost: 52.0 + * Minimum Spanning Tree: + * 0 - 1 : 10.0 + * 1 - 2 : 7.0 + * 2 - 5 : 6.0 + * 5 - 6 : 8.0 + * 1 - 4 : 9.0 + * 1 - 3 : 12.0 + * + */ diff --git a/Priority_Queue/Priority_Queue.py b/Priority_Queue/Priority_Queue.py new file mode 100644 index 000000000..eff1b80fd --- /dev/null +++ b/Priority_Queue/Priority_Queue.py @@ -0,0 +1,65 @@ +queue = [] + +def insert(data): # To insert values into the Queue + queue.append(data) + +def delete(): # TO remove value from the Priority Queue + try: # Here highest value will be deleted first + max = 0 + for i in range(len(queue)): + if queue[i] > queue[max]: + max = i + + item = queue[max] + del queue[max] + + return item + + except IndexError: # Instead of giving error for empty queue + print("Queue is empty!!") # Displays that 'Queue is empty' + +while 1: + + print("\t1. Insert value in queue\n\t2. Delete value in queue\n\t3. Print Queue\n\t4. Exit") + + opt = int(input("Enter your option:")) + + if opt == 1: + value = int(input("Enter the value:")) + insert(value) + + elif opt == 2: + del_value = delete() + print("\n" + str(del_value) + " is deleted") + + elif opt == 3: + print(queue) + + elif opt == 4: + break + + else: + print("\tInvalid option!\n\tTry Again!!") + +# The program is made of user choice +''' +Example: + 1. Insert value in queue + 2. Delete value in queue + 3. Print Queue + 4. Exit +Enter your option: 1 # Here you have to give value to be inserted in the queue +Enter the value: 12 + 1. Insert value in queue + 2. Delete value in queue + 3. Print Queue + 4. Exit +Enter your option:2 # To delete the value of highest priority(here highest value) +14 is deleted +Enter your option:3 # display the queue +[12, 1, 7] +Enter your option:4 #to exit +If you enter any other value other than (1,2,3,4), You will be shown: + Invalid option! + Try Again!! +''' diff --git a/Python implementation for the Rabin Karp algorithm b/Python implementation for the Rabin Karp algorithm new file mode 100644 index 000000000..270594dca --- /dev/null +++ b/Python implementation for the Rabin Karp algorithm @@ -0,0 +1,40 @@ + +# Extended Euclidean Algorithm +The Euclidean algorithm is based on the principle that the greatest common divisor of two numbers does not change if the larger number is replaced by its difference with the smaller number. + + +For example, 21 is the GCD of 252 and 105 (as 252 = 21 × 12 and 105 = 21 × 5), and the same number 21 is also the GCD of 105 and 252 − 105 = 147. Since this replacement reduces the larger of the two numbers, repeating this process gives successively smaller pairs of numbers until the two numbers become equal. When that occurs, they are the GCD of the original two numbers. + +By reversing the steps, the GCD can be expressed as a sum of the two original numbers each multiplied by a positive or negative integer, e.g., 21 = 5 × 105 + (−2) × 252. The fact that the GCD can always be expressed in this way is known as Bézout's identity. +# Example: + **Input:** a = 30, b = 20 + + **Output:** gcd = 10 + + x = 1, y = -1 (Note that 30*(1) + 20*(-1) = 10) + + +# Extended Euclidean Algorithm implementation in Python + + def gcdFunction(a, b, x, y): + if a == 0: + x = 0 + y = 1 + return b + x1 = 0; y1 = 0 + gcd = gcdFunction(b % a, a, x1, y1) + x = y1 - int(b / a) * x1 + y = x1 + return gcd + + a = 98; b = 21 + x = 0; y = 0 + print("GCD of numbers " + str(a) + " and " + str(b) + " is " + str(gcdFunction(a, b, x, y))) + + ''' Output + GCD of numbers 98 and 21 is 7 + ''' + +[Reference: Wikipedia](https://en.wikipedia.org/wiki/Euclidean_algorithm) + +[Reference: Geeksforgeeks](https://www.geeksforgeeks.org/euclidean-algorithms-basic-and-extended/) diff --git a/Quick_Sort/Quick_Sort.kt b/Quick_Sort/Quick_Sort.kt new file mode 100644 index 000000000..509722dd1 --- /dev/null +++ b/Quick_Sort/Quick_Sort.kt @@ -0,0 +1,63 @@ +/* QuickSort is a Divide and Conquer algorithm. It picks an element as pivot and partitions the given array +around the picked pivot.It's Best case complexity is n*log(n) & Worst case complexity is n^2. */ + +//partition array +fun quick_sort(A: Array, p: Int, r: Int) { + if (p < r) { + var q: Int = partition(A, p, r) + quick_sort(A, p, q - 1) + quick_sort(A, q + 1, r) + + } +} + +//assign last value as pivot +fun partition(A: Array, p: Int, r: Int): Int { + var x = A[r] + var i = p - 1 + for (j in p until r) { + if (A[j] <= x) { + i++ + exchange(A, i, j) + } + } + exchange(A, i + 1, r) + return i + 1 +} + +//swap +fun exchange(A: Array, i: Int, j: Int) { + var temp = A[i] + A[i] = A[j] + A[j] = temp +} + +fun main(arg: Array) { + print("Enter no. of elements :") + var n = readLine()!!.toInt() + + println("Enter elements : ") + var A = Array(n, { 0 }) + for (i in 0 until n) + A[i] = readLine()!!.toInt() + + quick_sort(A, 0, A.size - 1) + + println("Sorted array is : ") + for (i in 0 until n) + print("${A[i]} ") +} + +/*-------OUTPUT-------------- +Enter no. of elements :6 +Enter elements : +4 +8 +5 +9 +2 +6 +Sorted array is : +2 4 5 6 8 9 +*/ + diff --git a/Quick_Sort/Quick_Sort.rs b/Quick_Sort/Quick_Sort.rs new file mode 100644 index 000000000..abfed919c --- /dev/null +++ b/Quick_Sort/Quick_Sort.rs @@ -0,0 +1,66 @@ +use std::io; +use std::str::FromStr; + +fn main() { + println!("Enter the numbers to be sorted (separated by space) : "); + let mut array: Vec = read_values :: ().unwrap(); + quicksort(&mut array, 0, array.len() - 1); + println!("The sorted array is : {:?}", array); +} + +fn quicksort(array: &mut[isize], first: usize, last: usize) { + if first < last { + let midpoint = partition(array, first, last); + quicksort(array, first, midpoint - 1); + quicksort(array, midpoint + 1, last); + } +} + +fn partition(array: &mut[isize], first: usize, last: usize) -> usize { + let pivot = array[last]; + let i: isize = first as isize; + let mut i: isize = i - 1; + let mut j = first; + while j < last - 1 { + if array[j] < pivot { + i = i + 1; + let k: usize = i as usize; + swap(array, k, j); + } + j = j + 1; + } + let k: isize = i + 1; + let k: usize = k as usize; + if array[last] < array[k] { + swap(array, k, last); + } + return k; +} + +fn swap(array: &mut[isize], a: usize, b: usize) { + let temp = array[a]; + array[a] = array[b]; + array[b] = temp; +} + +fn read_values() -> Result, T::Err> { + let mut s = String::new(); + io::stdin() + .read_line(&mut s) + .expect("could not read from stdin"); + s.trim() + .split_whitespace() + .map(|word| word.parse()) + .collect() +} + +/* +Sample Input : + Sample Input : + Enter the numbers to be sorted (separated by space) : + 45 23 15 80 5 + +Sample Output : + The sorted array is : [5, 15, 23, 45, 80] +*/ + diff --git a/Quick_Sort/Quick_Sort.ts b/Quick_Sort/Quick_Sort.ts new file mode 100644 index 000000000..8a5a65165 --- /dev/null +++ b/Quick_Sort/Quick_Sort.ts @@ -0,0 +1,67 @@ +// Description: Function to perform the Quick Sort algorithm on an array of numbers +// Expected Output: returns the sorted array + +// Helper function to get the Pivoting Element Index +function partition(array: number[], left: number = 0, right: number = array.length - 1) +{ + const pivot = array[Math.floor((right + left) / 2)]; + let i = left; + let j = right; + + while (i <= j) + { + while (array[i] < pivot) + { + i++; + } + + while (array[j] > pivot) + { + j--; + } + + // Swap values based on indices + if (i <= j) + { + [array[i], array[j]] = [array[j], array[i]]; + i++; + j--; + } + } + + return i; +} + + +// Function that uses recursive definition for quick sort implementation +function quickSort(array: number[], left: number = 0, right: number = array.length - 1) +{ + let index; + + if (array.length > 1) + { + index = partition(array, left, right); + + if (left < index - 1) + { + quickSort(array, left, index - 1); + } + + if (index < right) + { + quickSort(array, index, right); + } + } + + return array; +} + +// I/P +var arr = [6, 5, 4, 3, 2, 1]; + +console.log("Before sorting ",arr) +var res = quickSort(arr) + +console.log("After sorting ",res) +// O/P +// 1,2,3,4,5,6 diff --git a/Quicksort_3_way/Quicksort_3_way.dart b/Quicksort_3_way/Quicksort_3_way.dart new file mode 100644 index 000000000..285bcdd7d --- /dev/null +++ b/Quicksort_3_way/Quicksort_3_way.dart @@ -0,0 +1,97 @@ +/** + * 3 way Quick sort + * --------------------------------- + * In three way quick sort, we partition the list into three divisions where + * division1 is less than pivot, division2 is equal to pivot and division3 is greater than + * pivot. The sorting is implemented using Dutch National Flag algorithm. + */ + +// Importing required libraries +import 'dart:io'; + +// Method to swap two integers in a list +void swap(List array, int i, int j){ + int temp = array[i]; + array[i] = array[j]; + array[j] = temp; +} + +// Method to partition the array based on 3 way partition +List partition(List array, int low, int high){ + int i, j; + if(high - low <= 1){ + if(array[high] < array[low]){ + swap(array, high, low); + } + i = low; + j = high; + // Returning the partitioning indices as list. + return [i, j]; + } + + int mid = low; + int pivot = array[high]; + while(mid <= high){ + if(array[mid] < pivot){ + swap(array, low++, mid++); + } + else if(array[mid] == pivot){ + mid++; + } + else if(array[mid] > pivot){ + swap(array, mid, high--); + } + } + i = low - 1; + j = mid; + + // Returning the partitioning indices as list + return [i, j]; +} + +// Method to sort a list using 3 way partition quick sort. +void quicksort_3_way(List array, int low, int high){ + + // Base case + if(low >= high){ + return; + } + + // Partitioning indices + List indices = partition(array, low, high); + + // Recursion + quicksort_3_way(array, low, indices[0]); + quicksort_3_way(array, indices[1], high); + +} + +// Driver method of the program +void main(){ + + // Input of number of elements of the array + print("Enter number of elements of the array:"); + var input = stdin.readLineSync(); + int n = int.parse(input); + + // Input of array elements + print("Enter array elements:"); + input = stdin.readLineSync(); + var lis = input.split(" "); + List array = lis.map(int.parse).toList(); + + // Finding the sorted array using quick sort 3 way partition + quicksort_3_way(array, 0, n - 1); + + // Printing the output to stdout. + print(array.join(" ")); +} +/** + * Sample Input and Output + * ------------------------------- + * Enter number of elements of the array: + * 13 + * Enter array elements: + * 4 9 4 4 1 9 4 4 9 4 4 1 4 + * 1 1 4 4 4 4 4 4 4 4 9 9 9 + */ diff --git a/Quicksort_3_way/quick_sort_3_way.rb b/Quicksort_3_way/quick_sort_3_way.rb new file mode 100644 index 000000000..ce52deb6f --- /dev/null +++ b/Quicksort_3_way/quick_sort_3_way.rb @@ -0,0 +1,71 @@ +#3 way Quick Sort in Ruby + +def quick_sort(a, lo, hi) + if lo < hi + temp = partition(a, lo, hi) + l = temp[0] + r = temp[1] + quick_sort(a, lo, l - 1) + quick_sort(a, r + 1, hi) + end +end + +def partition(a, lo, hi) + pivot = a[lo] + i = lo + 1 + lt = lo + gt = hi + + while(i <= gt) + + if a[i] < pivot + temp = a[lt] + a[lt] = a[i] + a[i] = temp + lt += 1 + i += 1 + elsif a[i] > pivot + temp = a[i] + a[i] = a[gt] + a[gt] = temp + gt -= 1 + else + i += 1 + end + end + return lt, gt +end + +puts "Enter the size of array : " +n = gets +puts "Enter the values for the array : " +$i = 0 +$num = Integer(n) +arr = Array.new + +while $i < $num do + + arr[$i] = gets + $i +=1 +end +$num2 = Integer(n) - 1 +puts quick_sort(arr, 0, $num2) +puts "After sorting : " +puts arr + +=begin +Sample Input-Output +Enter the size of array : +4 +Enter the values for the array : +10 +14 +12 +13 + +After sorting : +10 +12 +13 +14 +=end diff --git a/README.md b/README.md index d669ff797..570c8931a 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ $ git clone https://github.com/Your_Username/Algo_Ds_Notes.git > This makes a local copy of repository in your machine. -Once you have cloned the `Algo_Ds_Notes` repository in Github, move to that folder first using change directory command on linux and Mac. +Once you have cloned the `Algo_Ds_Notes` repository in Github, move to that folder first using change directory command on Linux/Mac/Windows. ```sh # This will change directory to a folder Algo_Ds_Notes diff --git a/RSA_Algorithm/README.md b/RSA_Algorithm/README.md new file mode 100644 index 000000000..0d60440d1 --- /dev/null +++ b/RSA_Algorithm/README.md @@ -0,0 +1,85 @@ +# RSA Algorithm +--- +RSA (Rivest-Shamir-Adleman) is an algorithm used by modern computers to encrypt and decrypt messages. It is an asymmetric cryptographic algorithm. Asymmetric means that there are two different keys. This is also called public key cryptoraphy, because one of the keys can be given to anyone. The other key must be kept private. The algorithm is based on the fact that finding the factors of large composite number is difficult: when the factors are prime numbers, the problem is called prime factorization. It is also a key pair (public and private key) generator. +![rsa algorithm](https://www.educative.io/api/edpresso/shot/5284561120395264/image/5318859621924864) + +## Algorithm +--- +- Generating the keys + 1. Generate two large random primes, p and q, of approximately equal size such that their product n=pq is of the required bit length. + 2. Compute n=pq and ϕ=(p−1)(q−1). + 3. Choose an integer e, 1 1 and is a co-prime of phi. + +// e = 17 satisfies the current values. + +// Using the extended euclidean algorithm, find 'd' which satisfies + +// this equation: + +d = (1 mod (phi))/e; + +// d = 2753 for the example values. + +public_key = (e=17, n=3233); + +private_key = (d=2753, n=3233); + +// Given the plaintext P=123, the ciphertext C is : + +C = (123^17) % 3233 = 855; + +// To decrypt the cypher text C: + +P = (855^2753) % 3233 = 123; +``` +## Complexity +--- + Three major components of the RSA algorithm are exponentiation, inversion and modular operation. Time complexity of the algorithm heavily depends on the complexity of the sub modules used. We can take the liberty to perform modular addition in cryptography in O(logn) where n is the number of digits in any number in Z. + + Now modular multiplication using squaring and multiply technique to get memodNcan be shown as multiplying the digits of m log e times. Considering the complexity of multiplication O({logn}2) i.e. repeated addition of two number of logn bits each, the complexity of the modular exponentiation is about O({logn}3) + + Using Euclidean extended GCD, inverse of a number can be calculated in O({logn}2) + + Thus overall time complexity of the key generation algorithm will be O(N2) encryption and decryption algorithm using squaring and multiply technique will be O(N3):For N digit number space. + +## Implementation +--- +- [C Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/RSA_Algorithm/RSA_Algorithm.c) + +- [C++ Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/RSA_Algorithm/RSA_Algorithm.cpp) + +- [JAVA Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/RSA_Algorithm/RSA_Algorithm.java) + +- [PYTHON Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/RSA_Algorithm/RSA_Algorithm.py) diff --git a/RSA_CRT/RSA_CRT.cpp b/RSA_CRT/RSA_CRT.cpp new file mode 100644 index 000000000..7518643d4 --- /dev/null +++ b/RSA_CRT/RSA_CRT.cpp @@ -0,0 +1,90 @@ +#include +using namespace std; + +// gcd function +long long int egcd (long long int a, long long int b) { + int rem; + + while (b != 0) { + rem = a % b; + a = b; + b = rem; + } + return a; +} + +// modular inversion function +long long int findInv (long long int x, long long int y, long long int n) { + long long int d = 2, temp; + + while (d < n) { + temp = ((d * x) - 1) % y; + if (temp == 0) + break; + d ++; + } + return d; +} + +// m is message to be encrypted, 1 < m < n +int main() { + long long int m, p, q, n, e, c, m1 = 1, m2 = 1, c11; + long long int phi, dP, dQ, qInv, h, message; + + cout << "Enter the message \n"; + cin >> m; + + // p and q are two random prime numbers + cout << "Enter two prime numbers"; + cin >> p; + cin >> q; + n = p * q; + + // eulers toitent function + phi = (p - 1) * (q - 1); + + // (n, e) forms our public key , 1 < e < phi + e = 2; + while ( e < phi) { + if (egcd (e, phi) == 1) + break; + e ++; + } + + //calculating CRT exponents dP, dQ and qInv to make calculations shorter and faster + dP = findInv (e , p - 1, n); + dQ = findInv (e , q - 1 , n); + qInv = findInv (q, p, n); + + //printing ciper text + c11 = pow (m, e); + c = c11 % n; + cout << "Cipher = " << c << "\n"; + + //printing original message + for (int i = 1; i <= dP; i++) { + m1 = ( m1 * c) % p; + } + + for(int i = 1; i <= dQ; i++) { + m2 = (m2 * c) % q; + } + h = (qInv * (m1 + p - m2)) % p; + message = m2 + (h * q); + cout << "Orignal message = " << message << "\n"; + + return 0; +} + +/* +Input : +Enter the message +1331 +Enter two prime numbers +131 +137 +Output : +Cipher = 16990 +Orignal Message = 1331 +*/ + diff --git a/Rabin_Karp/Rabin_Karp.c b/Rabin_Karp/Rabin_Karp.c new file mode 100644 index 000000000..f2df21efd --- /dev/null +++ b/Rabin_Karp/Rabin_Karp.c @@ -0,0 +1,77 @@ +/*Rabin Karp algorithm is a string matching algorithm which matches the hash value of the pattern with the hash +value of current substring of text and if the hash values match then only it starts matching individual characters*/ + +#include +#include + +void Rabin_Karp (char *text, char *pattern) +{ + int text_len = strlen (text); + int pattern_len = strlen (pattern); + int hash = 1; + int asciichars = 256; + int prime = 149; + + for (int i = 0; i < pattern_len - 1; i++) + { + hash = (hash * asciichars) % prime; + // there are 256 total characters in Ascii table & 149 is a prime number chosen randomly + } + int hash_txt = 0, hash_pat = 0; + + for (int i = 0; i < pattern_len; i++) + { + hash_txt = (hash_txt * asciichars + text [i]) % prime; // hash value for text + hash_pat = (hash_pat * asciichars + pattern [i]) % prime; // hash value for pattern + } + + for(int i = 0; i <= text_len - pattern_len; i++) + { + int j; + + if (hash_txt == hash_pat) + { + // checking if all the chars are equal in text portion & pattern + for (j = 0; j < pattern_len; j++) + { + if (text [i+j] != pattern [j]) + break; + } + if (j == pattern_len) + { + printf ("\n\nPattern searched is found at position %d\n\n", i+1); + } + } + // finding the pattern in remaining portion of the text + if (i < text_len-pattern_len) + { + hash_txt = ((hash_txt - text [i] * hash) * asciichars + text [i + pattern_len]) % prime; + if (hash_txt < 0) + { + hash_txt = hash_txt + prime; + } + } + } +} + +int main() +{ + char text [30]; + char pattern [15]; + printf ("Enter Text:\n"); + scanf ("%s", text); + printf ("Enter Pattern to be searched:\n"); + scanf ("%s", pattern); + Rabin_Karp (text, pattern); + return 0; +} + +/* Input/Output Demo: +Enter Text: +bbaavcaavaavifjkdfkfaav +Enter Pattern to be searched: +aav +Pattern searched is found at position 3 +Pattern searched is found at position 7 +Pattern searched is found at position 10 +Pattern searched is found at position 21 */ diff --git a/Rabin_Karp/Rabin_Karp.dart b/Rabin_Karp/Rabin_Karp.dart new file mode 100644 index 000000000..00a32483d --- /dev/null +++ b/Rabin_Karp/Rabin_Karp.dart @@ -0,0 +1,74 @@ +/** + * Rabin Karp algorithm + * --------------------------------- + * This is a pattern matching algorithm. It has O(n + m) in best + * and average case and O(n * m) in worst case. + * + */ + +// Importing required libraries +import 'dart:io'; + +// Function to search for the pattern in the text +void search(String pattern, String text, int prime){ + // Initializations + const int d = 256; + int m = pattern.length; + int n = text.length; + int p = 0, t = 0, h = 1; + // Hash value calculation for pattern + for(int i = 0; i < m - 1; i ++){ + h = (h * d) % prime; + } + // Hash value calculation for first substring in the text + for(int i = 0; i < m; i ++){ + p = (d * p + pattern.codeUnitAt(i)) % prime; + t = (d * t + text.codeUnitAt(i)) % prime; + } + + int j; + // Checking for matches in the text + for(int i = 0; i <= n - m; i ++){ + if(p == t){ + for(j = 0; j < m; j ++){ + if(text.codeUnitAt(i + j) != pattern.codeUnitAt(j)){ + break; + } + } + // Match found + if(j == m){ + print("The pattern iS found at index ${i}"); + } + } + if(i < n - m){ + t = (d * (t - text.codeUnitAt(i) * h) + text.codeUnitAt(i + m)) % prime; + if(t < 0){ + t = (t + prime); + } + } + } +} +// Driver method of the program +void main(){ + // Input of the pattern + print("Enter pattern:"); + var input = stdin.readLineSync(); + String pattern = input; + // Input of the text + print("Enter text:"); + input = stdin.readLineSync(); + String text = input; + // Chosen prime number + int q = 101; + // Calling search on pattern and text + search(pattern,text,q); +} +/** + * Sample Input and Output + * --------------------------------- + * Enter pattern: + * GIRL + * Enter text: + * GIRLSCRIPT + * The pattern is found at index 0 + */ diff --git a/Rabin_Karp/Rabin_Karp.php b/Rabin_Karp/Rabin_Karp.php new file mode 100644 index 000000000..9969fcc6b --- /dev/null +++ b/Rabin_Karp/Rabin_Karp.php @@ -0,0 +1,63 @@ +// Rabin Karp Algorithm +/* +AN : range or No of alphabets +val : AN ^ patlen-1 +patlen : pattern length +PN: any prime no given input from main +*/ + +/* Time-Complexity:- +The average case running time of the Rabin-Karp algorithm = O(n+m). +The best case running time of the Rabin-Karp algorithm = O(n+m). +The worst-case running time of the Rabin-Karp algorithm = O(nm). +*/ + + + +/* +INPUT : XWINGO XOR WINGO + WINGO + 101 +OUTPUT: Found at index starting from 1 + Found at index starting from 11 +*/ diff --git a/Rabin_Karp/Rabin_Karp.py b/Rabin_Karp/Rabin_Karp.py new file mode 100644 index 000000000..5eaa02854 --- /dev/null +++ b/Rabin_Karp/Rabin_Karp.py @@ -0,0 +1,57 @@ +# Rabin Karp Algorithm + +# AN : range or No of alphabets +# val : AN ^ patlen-1 +# patlen : pattern length +# PN: any prime no given input from main +# Time-Complexity:- +# The average case running time of the Rabin-Karp algorithm = O(n + m). +# The best case running time of the Rabin-Karp algorithm = O(n + m). +# The worst-case running time of the Rabin-Karp algorithm = O(n * m). + +AN = 256 + +def search (pattern, text, PN ) : + + patlen = len(pattern) # pattern length + txtlen = len(text) # text length + val = 1 + hpat = 0 # pattern hash value + htxt = 0 # text hash value + i = 0 + j = 0 + + for i in range (patlen - 1) : + val = (val * AN) % PN # PN is a prime number + + for i in range (patlen) : + hpat = (AN * hpat + ord(pattern[i])) % PN + htxt = (AN * htxt + ord(text[i])) % PN + + for i in range (txtlen - patlen + 1) : + if hpat == htxt : + for j in range (patlen) : + if text[i + j] != pattern[j]: + break + j += 1 + if j == patlen : + print( "Found at index starting from " + str(i)) + + # calculate the new position including i + m + if i < txtlen - patlen : + htxt = (AN * (htxt - ord(text[i]) * val) + ord(text[i + patlen])) % PN + + if htxt < 0 : + htxt = htxt + PN + +# Driver program +text = input() +pattern = input() +PN = 101 # Prime number +search (pattern, text, PN) + +# Input:-XWINGO XOR WINGO +# WINGO +# 101 +# OUTPUT:-Found at index starting from 1 +# Found at index starting from 11 diff --git a/Rabin_Karp/Rabin_Karp.rb b/Rabin_Karp/Rabin_Karp.rb new file mode 100644 index 000000000..ae392a526 --- /dev/null +++ b/Rabin_Karp/Rabin_Karp.rb @@ -0,0 +1,71 @@ +=begin +Rabin–Karp algorithm is a string-searching algorithm that uses +hashing to find any one of a set of pattern strings in a text. +=end + +PN = 101 # prime number +AN = 256 # no. of characters in alphabet + +def search(pattern, text) + patlen = pattern.length # pattern length + txtlen = text.length # text length + val = 1 + hpat = 0 # pattern hash value + htxt = 0 # text hash value + + for i in 0..(patlen - 2) + val = (val * AN) % PN # PN is a prime number + end + + for i in 0..(patlen - 1) + hpat = (AN * hpat + pattern[i].ord) % PN + htxt = (AN * htxt + text[i].ord) % PN + end + + for i in 0..(txtlen - patlen) + if (hpat == htxt) + # check for patterns + for j in 0..(patlen - 1) + if (text[i + j] != pattern[j]) + break + end + + j += 1 + + if (j == patlen) + puts "Found at index starting from #{i}" + end + end + end + + # Calculate the new pattern including i+m + if (i < txtlen - patlen) + htxt = (AN * (htxt - text[i].ord * val) + text[i + patlen].ord) % PN + + if (htxt < 0) + htxt = htxt + PN + end + end + end +end + +# Driver program +puts "Enter the text:" +text = gets.chomp + +puts "Enter the pattern:" +pattern = gets.chomp + +search(pattern, text) + +=begin +Enter the text: +XWINGO XOR WINGO + +Enter the pattern: +WINGO + +Output +Found at index starting from 1 +Found at index starting from 11 +=end diff --git a/Rabin_Karp/Rabin_karp.js b/Rabin_Karp/Rabin_karp.js new file mode 100644 index 000000000..68baac2f9 --- /dev/null +++ b/Rabin_Karp/Rabin_karp.js @@ -0,0 +1,43 @@ +const rabinKarp = (pat, str) => { + let p = 31 + let m = 1000000007 + let S = pat.length + let T = str.length + + let p_pow = [] // precomputing powers of p mod m + p_pow.push(1) // p^0 = 1 + for (let i = 1; i < Math.max(S, T); i++) { + p_pow.push((p_pow[i - 1] * p) % m); + } + + let h = [] // length-wise hash i.e h[i] = hash of the prefix with i characters + h.push(0); // h[0] = 0 + for (let i = 0; i < T; i++) { + h.push((h[i] + (str[i].charCodeAt(0) - 97 + 1) * p_pow[i]) % m); + } + + let h_s = 0; // hash value of the pattern + for (let i = 0; i < S; i++) + h_s = (h_s + (pat[i].charCodeAt(0) - 97 + 1) * p_pow[i]) % m; + + let occurs = []; // desired array storing the indices of given string where pattern occurs + for (let i = 0; i + S - 1 < T; i++) { + // slide a window of length S of the pattern + let cur_h = (h[i + S] - h[i] + m) % m; + // if current_hash matches with the hash of out pattern, then a match is found at this index + if (cur_h == h_s * p_pow[i] % m) + occurs.push(i); + } + + return occurs; +} + +// Calling the function +let str = "girlscriptsummerofcodewithgirlsandboys" +let pat = "girl" + +let ids = rabinKarp(pat, str) // desired array storing the indices of given string where pattern occurs +console.log("Pattern found at indexes: ", ids) + +// Output +// Pattern found at indexes: [ 0, 26 ] diff --git a/Radix_Sort/RadixSort.php b/Radix_Sort/RadixSort.php new file mode 100644 index 000000000..3efd23f4c --- /dev/null +++ b/Radix_Sort/RadixSort.php @@ -0,0 +1,73 @@ += 0; $i--) + { + $output[$count[ ($arr[$i] / $exp) % 10 ] - 1] = $arr[$i]; + $count[ ($arr[$i] / $exp) % 10 ]--; + } + + // Copy the output array to arr[] + for ($i = 0; $i < $n; $i++) + $arr[$i] = $output[$i]; +} + +// The main function that sorts arr[] +function radixsort(&$arr, $n) +{ + // Find the maximum number to know number of digits + $m = max($arr); + + // Do counting sort for every digit + for ($exp = 1; $m / $exp > 0; $exp *= 10) + countSort($arr, $n, $exp); +} + +// A utility function to print an array +function PrintArray(&$arr,$n) +{ + echo "sorted Array : "; + for ($i = 0; $i < $n; $i++) + echo $arr[$i] . " "; +} + +// Driver Code +$n = readline ("Enter size of an array : "); +readline ("Enter the elements : "); +for ($i = 0; $i < $n; $i++) +{ + $arr[$i] = readline(); +} + +radixsort($arr, $n); +PrintArray($arr, $n); + +/* +OUTPUT: +Enter size of an array : 7 +Enter the elements : +12 +45 +9 +85 +700 +2 +4 +Sorted Array : 2 4 9 12 45 85 700 +*/ + +?> diff --git a/Radix_Sort/Radix_Sort.dart b/Radix_Sort/Radix_Sort.dart new file mode 100644 index 000000000..48b798f55 --- /dev/null +++ b/Radix_Sort/Radix_Sort.dart @@ -0,0 +1,65 @@ +// Importing required libraries +import 'dart:io'; + +// Function to sort based on bits of integers using count sort +void countSort(List array, int n, int exp){ + List output = List(n); + List count = List(10); + for(int i = 0; i < 10; i ++){ + count[i] = 0; + } + for(int i = 0; i < n; i ++){ + count[((array[i] / exp).floor()) % 10] ++; + } + for(int i = 1; i < 10; i ++){ + count[i] += count[i - 1]; + } + for(int i = n - 1; i >= 0; i --){ + output[count[((array[i] / exp).floor()) % 10] - 1] = array[i]; + count[((array[i] / exp).floor()) % 10] --; + } + for(int i = 0; i < n; i ++){ + array[i] = output[i]; + } +} +// Function to find max of the array +int getMax(List array, int n){ + int max_value = array[0]; + for(int i = 0; i < n; i ++){ + if(max_value < array[i]){ + max_value = array[i]; + } + } + return max_value; +} +// Function to sort an array using radix sort +void radix_sort(List array, int n){ + int max_value = getMax(array, n); + for(int exp = 1; max_value / exp > 0; exp *= 10){ + countSort(array, n, exp); + } +} +// Driver method of the program. +void main(){ + print("Enter number of elements in the array:"); + var input = stdin.readLineSync(); + int n = int.parse(input); + + print("Enter array elements:"); + input = stdin.readLineSync(); + var lis = input.split(" "); + List array = lis.map(int.parse).toList(); + + radix_sort(array, n); + + print(array.join(" ")); +} +/** + * Sample Input and Output + * --------------------------------- + * Enter number of elements in the array: + * 10 + * Enter array elements: + * 10 9 8 7 6 5 4 3 2 1 + * 1 2 3 4 5 6 7 8 9 10 + */ diff --git a/Radix_Sort/Radix_Sort.rs b/Radix_Sort/Radix_Sort.rs new file mode 100644 index 000000000..506c2ef3c --- /dev/null +++ b/Radix_Sort/Radix_Sort.rs @@ -0,0 +1,68 @@ +use std::io; +use std::str::FromStr; + +fn main() { + println!("Enter the numbers to be sorted (separated by space) : "); + let mut arr: Vec = read_values::().unwrap(); + radix_sort(&mut arr); + println!("The sorted array is : {:?}", arr); +} + +fn radix_sort(input: &mut [u32]) { + if input.len() == 0 { + return; + } + + let mut buckets: Vec> = Vec::with_capacity(10); // initialize buckets + for _ in 0..10 { + buckets.push(Vec::new()); + } + + let count: usize = input.iter() // count how many digits the longest number has + .max() + .unwrap() + .to_string() + .len(); + let mut divisor: u32 = 1; + + for _ in 0..count { + for num in input.iter() { + let temp = (num / divisor) as usize; + buckets[temp % 10].push(*num); + } + + let mut j: usize = 0; + for k in 0..10 { + for x in buckets[k].iter() { + input[j] = *x; + j += 1; + } + buckets[k].clear(); + } + divisor *= 10; + } +} + +fn read_values() -> Result, T::Err> { + let mut s = String::new(); + io::stdin() + .read_line(&mut s) + .expect("could not read from stdin"); + s.trim() + .split_whitespace() + .map(|word| word.parse()) + .collect() +} + + +/* + +Sample Input : + Enter the numbers to be sorted (separated by space) : + 45 23 15 80 5 + +Sample Output : + The sorted array is : [5, 15, 23, 45, 80] + +*/ + diff --git a/Red_Black_Tree/Red_Black_Tree.cs b/Red_Black_Tree/Red_Black_Tree.cs new file mode 100644 index 000000000..da8abef36 --- /dev/null +++ b/Red_Black_Tree/Red_Black_Tree.cs @@ -0,0 +1,554 @@ +using System; + +namespace Declaring_Methods +{ + public static class Program + { + public static void Main(String[] args) + { + RedBlackTree bst = new RedBlackTree(); + bst.insert(54); + bst.insert(38); + bst.insert(62); + bst.insert(58); + bst.insert(73); + bst.insert(55); + bst.printTree(); + Console.WriteLine("\nAfter deleting:"); + bst.deleteNode(40); + bst.printTree(); + } + public class Node + { + public int data; + public Node parent; + public Node left; + public Node right; + public int color; + } + + public class RedBlackTree + { + public Node root; + public Node TNULL; + + //PreOder Traversal + public void PreOder(Node node) + { + if (node != TNULL) + { + Console.Write(node.data + " "); + PreOder(node.left); + PreOder(node.right); + } + } + + //InOder Traversal + public void InOrder(Node node) + { + if (node != TNULL) + { + InOrder(node.left); + Console.Write(node.data + " "); + InOrder(node.right); + } + } + + //PostOder Traversal + public void PostOrder(Node node) + { + if (node != TNULL) + { + PostOrder(node.left); + PostOrder(node.right); + Console.Write(node.data + " "); + } + } + + //Searching in the Tree + public Node searchTreeHelper(Node node, int key) + { + if (node == TNULL || key == node.data) + { + return node; + } + + if (key < node.data) + { + return searchTreeHelper(node.left, key); + } + return searchTreeHelper(node.right, key); + } + + // Balance the tree after deletion of a node + public void fixDelete(Node x) + { + Node s; + while (x != root && x.color == 0) + { + if (x == x.parent.left) + { + s = x.parent.right; + if (s.color == 1) + { + s.color = 0; + x.parent.color = 1; + leftRotate(x.parent); + s = x.parent.right; + } + + if (s.left.color == 0 && s.right.color == 0) + { + s.color = 1; + x = x.parent; + } + else + { + if (s.right.color == 0) + { + s.left.color = 0; + s.color = 1; + rightRotate(s); + s = x.parent.right; + } + + s.color = x.parent.color; + x.parent.color = 0; + s.right.color = 0; + leftRotate(x.parent); + x = root; + } + } + else + { + s = x.parent.left; + if (s.color == 1) + { + s.color = 0; + x.parent.color = 1; + rightRotate(x.parent); + s = x.parent.left; + } + + if (s.right.color == 0 && s.right.color == 0) + { + s.color = 1; + x = x.parent; + } + else + { + if (s.left.color == 0) + { + s.right.color = 0; + s.color = 1; + leftRotate(s); + s = x.parent.left; + } + + s.color = x.parent.color; + x.parent.color = 0; + s.left.color = 0; + rightRotate(x.parent); + x = root; + } + } + } + x.color = 0; + } + + public void rbTransplant(Node u, Node v) + { + if (u.parent == null) + { + root = v; + } + else if (u == u.parent.left) + { + u.parent.left = v; + } + else + { + u.parent.right = v; + } + v.parent = u.parent; + } + + //Deleting the Node element + public void deleteNodeHelper(Node node, int key) + { + Node z = TNULL; + Node x, y; + while (node != TNULL) + { + if (node.data == key) + { + z = node; + } + + if (node.data <= key) + { + node = node.right; + } + else + { + node = node.left; + } + } + + if (z == TNULL) + { + Console.WriteLine("Couldn't find key in the tree"); + return; + } + + y = z; + int yOriginalColor = y.color; + if (z.left == TNULL) + { + x = z.right; + rbTransplant(z, z.right); + } + else if (z.right == TNULL) + { + x = z.left; + rbTransplant(z, z.left); + } + else + { + y = minimum(z.right); + yOriginalColor = y.color; + x = y.right; + if (y.parent == z) + { + x.parent = y; + } + else + { + rbTransplant(y, y.right); + y.right = z.right; + y.right.parent = y; + } + + rbTransplant(z, y); + y.left = z.left; + y.left.parent = y; + y.color = z.color; + } + if (yOriginalColor == 0) + { + fixDelete(x); + } + } + + // Balance the node after insertion + public void fixInsert(Node k) + { + Node u; + while (k.parent.color == 1) + { + if (k.parent == k.parent.parent.right) + { + u = k.parent.parent.left; + if (u.color == 1) + { + u.color = 0; + k.parent.color = 0; + k.parent.parent.color = 1; + k = k.parent.parent; + } + else + { + if (k == k.parent.left) + { + k = k.parent; + rightRotate(k); + } + k.parent.color = 0; + k.parent.parent.color = 1; + leftRotate(k.parent.parent); + } + } + else + { + u = k.parent.parent.right; + + if (u.color == 1) + { + u.color = 0; + k.parent.color = 0; + k.parent.parent.color = 1; + k = k.parent.parent; + } + else + { + if (k == k.parent.right) + { + k = k.parent; + leftRotate(k); + } + k.parent.color = 0; + k.parent.parent.color = 1; + rightRotate(k.parent.parent); + } + } + if (k == root) + { + break; + } + } + root.color = 0; + } + + //Printing the Tree + public void printHelper(Node root, String indent, bool last) + { + if (root != TNULL) + { + Console.Write(indent); + if (last) + { + Console.Write("R----"); + indent += " "; + } + else + { + Console.Write("L----"); + indent += "| "; + } + + String sColor = root.color == 1 ? "RED" : "BLACK"; + Console.WriteLine(root.data + "(" + sColor + ")"); + printHelper(root.left, indent, false); + printHelper(root.right, indent, true); + } + } + + public RedBlackTree() + { + TNULL = new Node(); + TNULL.color = 0; + TNULL.left = null; + TNULL.right = null; + root = TNULL; + } + + // PreOder Traversal + public void preorder() + { + PreOder(this.root); + } + + //InOder Traversal + public void inorder() + { + InOrder(this.root); + } + + //Post Oder Traversal + public void postorder() + { + PostOrder(this.root); + } + + //Searching in the tree + public Node searchTree(int k) + { + return searchTreeHelper(this.root, k); + } + + //Finding the minimum Node element + public Node minimum(Node node) + { + while (node.left != TNULL) + { + node = node.left; + } + return node; + } + + //Finding the maximum Node element + public Node maximum(Node node) + { + while (node.right != TNULL) + { + node = node.right; + } + return node; + } + + //Find the Successor of the element + public Node successor(Node x) + { + if (x.right != TNULL) + { + return minimum(x.right); + } + + Node y = x.parent; + while (y != TNULL && x == y.right) + { + x = y; + y = y.parent; + } + return y; + } + + //Finding the Predecessor of the element + public Node predecessor(Node x) + { + if (x.left != TNULL) + { + return maximum(x.left); + } + + Node y = x.parent; + while (y != TNULL && x == y.left) + { + x = y; + y = y.parent; + } + + return y; + } + + //Left Rotation + public void leftRotate(Node x) + { + Node y = x.right; + x.right = y.left; + if (y.left != TNULL) + { + y.left.parent = x; + } + y.parent = x.parent; + if (x.parent == null) + { + this.root = y; + } + else if (x == x.parent.left) + { + x.parent.left = y; + } + else + { + x.parent.right = y; + } + y.left = x; + x.parent = y; + } + + //Right Rotation + public void rightRotate(Node x) + { + Node y = x.left; + x.left = y.right; + if (y.right != TNULL) + { + y.right.parent = x; + } + y.parent = x.parent; + if (x.parent == null) + { + this.root = y; + } + else if (x == x.parent.right) + { + x.parent.right = y; + } + else + { + x.parent.left = y; + } + y.right = x; + x.parent = y; + } + + //Inserting Key to Tree + public void insert(int key) + { + Node node = new Node(); + node.parent = null; + node.data = key; + node.left = TNULL; + node.right = TNULL; + node.color = 1; + + Node y = null; + Node x = this.root; + + while (x != TNULL) + { + y = x; + if (node.data < x.data) + { + x = x.left; + } + else + { + x = x.right; + } + } + + node.parent = y; + if (y == null) + { + root = node; + } + else if (node.data < y.data) + { + y.left = node; + } + else + { + y.right = node; + } + + if (node.parent == null) + { + node.color = 0; + return; + } + + if (node.parent.parent == null) + { + return; + } + + fixInsert(node); + } + + //Getting the Root element of the tree + public Node getRoot() + { + return this.root; + } + + //Delete Node + public void deleteNode(int data) + { + deleteNodeHelper(this.root, data); + } + + //Print the Tree + public void printTree() + { + printHelper(this.root, " ", true); + } + } + } +} +/*R----54(BLACK) + L----38(BLACK) + R----62(RED) + L----58(BLACK) + | L----55(RED) + R----73(BLACK) + +After deleting: +Couldn't find key in the tree + R----54(BLACK) + L----38(BLACK) + R----62(RED) + L----58(BLACK) + | L----55(RED) + R----73(BLACK)*/ diff --git a/Red_Black_Tree/Red_Black_Tree.dart b/Red_Black_Tree/Red_Black_Tree.dart new file mode 100644 index 000000000..295fe18ab --- /dev/null +++ b/Red_Black_Tree/Red_Black_Tree.dart @@ -0,0 +1,346 @@ +/** + * Red Black Tree + * ------------------------------- + * RB Tree is a self balancing tree which is of O(logn) time complexity + * for various operations. It has 4 balancing rules as follows: + * + * 1. Nodes are of either red or black color. + * 2. Root is always black. + * 3. Red node should not have red children + * 4. Every path from a node (including root) to any of its descendant + * NULL node has the same number of black nodes. + * + */ + +// Importing required libraries +import 'dart:io'; + +// Defining colors as constants to increase readability and decrease confusion +const bool BLACK = false; +const bool RED = true; + +// Class definition of a node +class Node{ + int value; + bool color; + Node parent, left, right; + + Node(int value){ + this.value = value; + this.color = RED; + } +} + +// Class definition of a RB Tree +class RBTree{ + + // Tree's root + Node root; + + // Utility function to print a RB Tree + void printRBTree(Node root){ + if(root != null){ + print(root.value); + printRBTree(root.left); + printRBTree(root.right); + } + } + + // Utility method to search in the tree + Node searchRBTree(Node root, int target){ + if(root == null){ + return null; + } + if(root.value == target){ + return root; + } + else if(root.value < target){ + return searchRBTree(root.right, target); + } + else{ + return searchRBTree(root.left, target); + } + } + + // Utility method to perform BST insertion + Node insertBST(Node root, Node node){ + if(root == null){ + root = node; + } + else{ + if(root.value < node.value){ + root.right = insertBST(root.right, node); + root.right.parent = root; + } + else if(root.value > node.value){ + root.left = insertBST(root.left, node); + root.left.parent = root; + } + } + return root; + } + + // Utility method for left rotation + Node rotateLeft(Node root, Node node){ + + Node node_right = node.right; + node.right = node_right.left; + if(node.right != null){ + node.right.parent = node; + } + node_right.parent = node.parent; + if(node.parent == null){ + root = node_right; + } + else if(node == node.parent.left){ + node.parent.left = node_right; + } + else{ + node.parent.right = node_right; + } + node_right.left = node; + node.parent = node_right; + return root; + + } + + // Utility method for right rotation + Node rotateRight(Node root,Node node){ + + Node node_left = node.left; + node.left = node_left.right; + + if(node.left != null){ + node.left.parent = node; + } + + node_left.parent = node.parent; + + if(node.parent == null){ + root = node_left; + } + else if(node == node.parent.left){ + node.parent.left = node_left; + } + else{ + node.parent.right = node_left; + } + + node_left.right = node; + node.parent = node_left; + return root; + } + + // Utility method to swap colors of two nodes + void swapColor(Node node1, Node node2){ + if(node1 == null || node2 == null){ + return; + } + bool temp; + temp = node1.color; + node1.color = node2.color; + node2.color = temp; + } + + // Utility method to fix violation of rules of RB Tree + Node fixViolation(Node root, Node node){ + Node parentnode = null; + Node grandparent = null; + while((node != root) && (node.color != BLACK) && (node.parent.color == RED)){ + parentnode = node.parent; + grandparent = node.parent.parent; + if(parentnode == grandparent.left){ + Node uncle = grandparent.right; + if(uncle != null && uncle.color == RED){ + grandparent.color = RED; + parentnode.color = BLACK; + uncle.color = BLACK; + node = grandparent; + } + else{ + if(node == parentnode.right){ + root = rotateLeft(root,parentnode); + node = parentnode; + parentnode = node.parent; + grandparent = parentnode.parent; + } + root = rotateRight(root, grandparent); + swapColor(parentnode,grandparent); + node = parentnode; + } + } + else{ + Node uncle = grandparent.left; + + if((uncle != null) && (uncle.color == RED)){ + grandparent.color = RED; + parentnode.color = BLACK; + uncle.color = BLACK; + node = grandparent; + } + else{ + if(node == parentnode.left){ + root = rotateRight(root,parentnode); + node = parentnode; + parentnode = node.parent; + grandparent = parentnode.parent; + } + root = rotateLeft(root,grandparent); + swapColor(parentnode,grandparent); + node = parentnode; + } + } + + } + root.color = BLACK; + return root; + } + + // Method to insert into RB Tree + Node insertRBT(Node root, int value){ + Node node = Node(value); + root = insertBST(root, node); + root = fixViolation(root, node); + return root; + } + +} + +// Driver method of the program +void main(){ + + // Initialization of the tree + RBTree tree = RBTree(); + int continued = 1; + + while(continued == 1){ + print("Enter 1 to insert, 2 to search and 3 to print the tree:"); + var input = stdin.readLineSync(); + int option = int.parse(input); + switch(option){ + case 1: + input = stdin.readLineSync(); + int value = int.parse(input); + tree.root = tree.insertRBT(tree.root, value); + break; + case 2: + input = stdin.readLineSync(); + int value = int.parse(input); + Node node1 = tree.searchRBTree(tree.root, value); + if(node1 == null){ + print("Value not found"); + } + else{ + print("Value found!"); + } + break; + case 3: + tree.printRBTree(tree.root); + break; + default: + break; + } + print("Enter 1 to continue:"); + input = stdin.readLineSync(); + continued = int.parse(input); + } +} + +/** + * Sample Input and Output + * ----------------------------------- + * Enter 1 to insert, 2 to search and 3 to print the tree: + * 1 + * 7 + * Enter 1 to continue: + * 1 + * Enter 1 to insert, 2 to search and 3 to print the tree: + * 1 + * 3 + * Enter 1 to continue: + * 1 + * Enter 1 to insert, 2 to search and 3 to print the tree: + * 1 + * 18 + * Enter 1 to continue: + * 1 + * Enter 1 to insert, 2 to search and 3 to print the tree: + * 1 + * 10 + * Enter 1 to continue: + * 1 + * Enter 1 to insert, 2 to search and 3 to print the tree: + * 1 + * 22 + * Enter 1 to continue: + * 1 + * Enter 1 to insert, 2 to search and 3 to print the tree: + * 1 + * 8 + * Enter 1 to continue: + * 1 + * Enter 1 to insert, 2 to search and 3 to print the tree: + * 1 + * 11 + * Enter 1 to continue: + * 1 + * Enter 1 to insert, 2 to search and 3 to print the tree: + * 1 + * 26 + * Enter 1 to continue: + * 1 + * Enter 1 to insert, 2 to search and 3 to print the tree: + * 3 + * 7 + * 3 + * 18 + * 10 + * 8 + * 11 + * 22 + * 26 + * Enter 1 to continue: + * 1 + * Enter 1 to insert, 2 to search and 3 to print the tree: + * 2 + * 18 + * Value found!! + * Enter 1 to continue: + * 1 + * Enter 1 to insert, 2 to search and 3 to print the tree: + * 2 + * 112 + * Value not found!! + * Enter 1 to continue: + * 1 + * Enter 1 to insert, 2 to search and 3 to print the tree: + * 1 + * 2 + * Enter 1 to continue: + * 1 + * Enter 1 to insert, 2 to search and 3 to print the tree: + * 1 + * 6 + * Enter 1 to continue: + * 1 + * Enter 1 to insert, 2 to search and 3 to print the tree: + * 1 + * 13 + * Enter 1 to continue: + * 1 + * Enter 1 to insert, 2 to search and 3 to print the tree: + * 3 + * 10 + * 7 + * 3 + * 2 + * 6 + * 8 + * 18 + * 11 + * 13 + * 22 + * 26 + * Enter 1 to continue: + * 2 + */ diff --git a/SRTF_Scheduling/SRTF_Scheduling.java b/SRTF_Scheduling/SRTF_Scheduling.java new file mode 100644 index 000000000..673238164 --- /dev/null +++ b/SRTF_Scheduling/SRTF_Scheduling.java @@ -0,0 +1,162 @@ +package github; + +import java.util.Scanner; +class Process +{ + static Scanner in = new Scanner(System.in);//for input + float At = 0;//parameters of process + float Bt = 0; + float Ct = 0; + float Tt = 0; + float Wt = 0; + float Timeleft ;//only used for srtf + + Process(float a, float b)// constructor + { + At = a; + Bt = b; + } + + public static float calTt(Process p[], int n)//tt = ct-at and avg tt + { + float avg = 0;//avg + for(int i = 0; i < n; i++) + { + p[i].Tt = p[i].Ct - p[i].At; + avg = avg + p[i].Tt; + } + avg = avg / n; + return avg; + } + + public static float calWt(Process p[], int n)//wt = tt-bt and avg wt + { + float avg = 0;//avg + for(int i = 0; i < n; i++) + { + p[i].Wt = p[i].Tt - p[i].Bt; + avg = avg + p[i].Wt; + } + avg = avg / n;//avg wt + return avg; + } +} + +class SRTF +{ + float Awt; + float Att; + float sumBT; + static Scanner in = new Scanner(System.in); + public SRTF() + { + sumBT = 0; + } + + public void Accept(Process p[], int n)//accept func + { + for(int i = 0; i < n; i++) + { + System.out.println("Enter arrival time for process P" + i);//at + float a = in.nextFloat(); + System.out.println("Enter burst time for process P" + i);//bt + float b = in.nextFloat(); + p[i] = new Process(a, b); + p[i].Timeleft = p[i].Bt;//used to find shortest process remaining + sumBT = sumBT + p[i].Bt;//used for cal ct in calcct function + } + } + + public void CalcCT(Process p[], int n) + { + System.out.println(); + System.out.println(); + int min = 0; + for(int i = 0; i < sumBT; i++) + { + for(int j = 0; j < n; j++) + { + if(p[j].At <= i && p[min].Timeleft > p[j].Timeleft && p[j].Timeleft != 0)//finding process with least bt + { + min = j;// process index with min bt + } + } + p[min].Timeleft--; + if(p[min].Timeleft == 0)//setting ct when execution is done + { + p[min].Ct = i + 1;// +1 because it will complete in next cycle + p[min].Timeleft = 32767; + } + System.out.print("P" + min + "| ");//gantt chart + } + Att = Process.calTt(p, n);//att + Awt = Process.calWt(p, n);//awt + } + + public void Display(Process p[], int n) + { + System.out.println(); + System.out.println("process Arrival Time Burst Time Completion Time Turnover Time Waiting Time");//table + for(int i = 0; i < n; i++) + { + System.out.println("P" + i + "\t " + p[i].At + "\t\t" + p[i].Bt + "\t\t" + p[i].Ct + "\t\t" + p[i].Tt + "\t\t" + p[i].Wt); + } + System.out.println(); + System.out.println("Average waiting time is " + Awt);//other data to be displayed + System.out.println("Average turnover time is " + Att); + System.out.println(); + } +} + + +public class MAIN { + public static void main(String[] args) + { + Scanner in = new Scanner(System.in); + System.out.println("SRTF algorithm"); + int n;//no of processes + System.out.println("Enter no of process");//ip of process + n = in.nextInt(); + Process P[] = new Process[n]; + SRTF S = new SRTF();//object of srtf + S.Accept(P, n); + S.CalcCT(P, n);//all calculations and gantt chart + System.out.println(); + S.Display(P, n);//table display + } +} + +/*sample output + * SRTF algorithm +Enter no of process +4 +Enter arrival time for process P0 +0 +Enter burst time for process P0 +7 +Enter arrival time for process P1 +2 +Enter burst time for process P1 +4 +Enter arrival time for process P2 +4 +Enter burst time for process P2 +2 +Enter arrival time for process P3 +7 +Enter burst time for process P3 +1 + + +P0| P0| P1| P1| P1| P1| P2| P2| P3| P0| P0| P0| P0| P0| + +process Arrival Time Burst Time Completion Time Turnover Time Waiting Time +P0 0.0 7.0 14.0 14.0 7.0 +P1 2.0 4.0 6.0 4.0 0.0 +P2 4.0 2.0 8.0 4.0 2.0 +P3 7.0 1.0 9.0 2.0 1.0 + +Average waiting time is 2.5 +Average turnover time is 6.0 + +*/ diff --git a/Scheduling_Algorithm/C++/Preemptive/Round_Robin_Scheduling.cpp b/Scheduling_Algorithm/C++/Preemptive/Round_Robin_Scheduling.cpp new file mode 100644 index 000000000..ae27ba4db --- /dev/null +++ b/Scheduling_Algorithm/C++/Preemptive/Round_Robin_Scheduling.cpp @@ -0,0 +1,104 @@ +/*Round Robin Scheduling is a CPU scheduling algorithm where each process is assigned a fixed time slot in a cyclic way. +It is preemtive in nature. +It is cyclic in nature so starvation doesn’t occur +It is variant of first come, first served scheduling +No priority given to any process or task +It is also known as Time slicing scheduling +-Arrival Time: Time at which the process arrives in the ready queue. +-Burst Time: Time required by a process for CPU execution. +-Turn Around Time: Time Difference between completion time and arrival time. +-Waiting Time: Time Difference between turn around time and burst time. */ + +#include +using namespace std; + +int main() +{        + int i, j, no_of_process, current_time, remaining_time; + int f = 0, time_slice, wait_time = 0, turn_time = 0; +    cout << "Enter number of processes: "; +    cin >> no_of_process; + +    int a[no_of_process]; //Arrival Time + int b[no_of_process]; //Burst Time + int r[no_of_process]; +    remaining_time = no_of_process; + +    for(i = 0; i < no_of_process; i++) +    { + cout << "\nProcess " << i << ": "; +       cout << "Enter Arrival Time: "; +       cin >> a[i]; +       cout << "Enter Burst Time: "; +       cin >> b[i]; +       r[i] = b[i]; +    } + +    cout << "Enter Time slice: "; +    cin >> time_slice; + +    cout << "\nProcess\tTurnaround time\t Waiting Time\n"; + cout << "-------------------------------------------"; +    for(current_time = 0, i = 0; remaining_time != 0;) +    { + //If burst time is less than time slice + if(r[i] <= time_slice && r[i] > 0) +       { + current_time += r[i]; //Increase current time by adding burst time +          r[i] = 0; //Make remaining time zero +            f = 1; +        } + //If required time is more than time slice +        else if(r[i] > 0) +       {        + r[i] -= time_slice; //Reduce remaining time by time slice +            current_time += time_slice; //Increase current time by adding time slice +        } + +        if(r[i] == 0 && f == 1) +        { + remaining_time--; +            cout << "\nProcess " << i << "\t" << current_time - a[i] << "\t\t" << current_time - a[i] - b[i]; +            wait_time += current_time - a[i] - b[i]; +            turn_time += current_time - a[i]; +            f = 0; +        } +        if(i >= no_of_process - 1) +            i = 0; +       else if(a[i+1] <= current_time) +            i++; +       else +            i = 0; +     } +     cout << "\nAverage Waiting Time: " << (wait_time*1.0) / no_of_process; +     cout << "\nAverage Turnaround Time: " << (turn_time*1.0) / no_of_process; +     return 0; +} + +/* +Sample Input/Output: + +Enter number of processes: 4 + +Process 0: Enter Arrival Time: 1 +Enter Burst Time: 5 + +Process 1: Enter Arrival Time: 3 +Enter Burst Time: 7 + +Process 2: Enter Arrival Time: 2 +Enter Burst Time: 5 + +Process 3: Enter Arrival Time: 5 +Enter Burst Time: 8 +Enter Time slice: 3 + +Process Turnaround time Waiting Time +------------------------------------------- +Process 0 13 8 +Process 2 17 12 +Process 1 20 13 +Process 3 20 12 +Average Waiting Time: 11.25 +Average Turnaround Time: 17.5 +*/ diff --git a/Segment_Tree_RMQ/README.md b/Segment_Tree_RMQ/README.md new file mode 100644 index 000000000..a0bc4dd71 --- /dev/null +++ b/Segment_Tree_RMQ/README.md @@ -0,0 +1,134 @@ +# Segment Tree + +Segment Tree is a basically a binary tree used for storing the intervals or segments. Each node in the Segment Tree represents an interval. + +Segment Tree is used in cases where there are multiple range queries on array and modifications of elements of the same array. For example, finding the sum of all the elements in an array from indices L to R, or finding the minimum (famously known as __Range Minumum Query__ problem) of all the elements in an array from indices L to R. + +## Explanation + +Consider an array __A__ of size __N__ and a corresponding Segment Tree __T__: + +1. The root of __T__ will represent the whole array __A[0 : N-1]__. +2. Each leaf in the Segment Tree __T__ will represent a single element __A[i]__ such that __0 <= i < N__. +3. The internal nodes in the Segment Tree __T__ represents the union of elementary intervals __A[i : j]__ where __0<=i2N__. +* There are __N__ leaves representing the elements of the array. The number of internal nodes is __N - 1__. So, a total number of nodes are __2 * N - 1__. + +The Segment Tree of array __A__ of size __7__ will look like this: + +![Pic01](https://he-s3.s3.amazonaws.com/media/uploads/a0c7f90.jpg) + +![Pic02](https://he-s3.s3.amazonaws.com/media/uploads/aad673e.jpg) + +## Algorithm + +#### Query for minimum value of given range + +Once the tree is constructed, how to do range minimum query using the constructed segment tree. Following is the algorithm to get the minimum. + +``` +// qs --> query start index, qe --> query end index +int RMQ(node, qs, qe) +{ + if range of node is within qs and qe + return value in node + else if range of node is completely outside qs and qe + return ZERO + else + return min( RMQ(node's left child, qs, qe), RMQ(node's right child, qs, qe) ) +} +``` + +## Pseudocode + +After we've built a tree, we want to be able to search the tree for its values. (Which, in this case, is the minimum value between indices L and R.) + +Similar to the technique we used before, we recursively search the tree, starting from the root, and if a node is within the range [L, R], then we check it's value as a valid minimum of the range. + +``` +function RecursivelySearchForMin(L, R, nodeIndex, nodeStartIndex, nodeEndIndex) +{ + /* + If this node's range is anywhere outside of [L, R] + then don't use it's value. Just return some + really big number (which wouldn't be taken as the minimum). + */ + if(nodeEndIndex < L || R < nodeStartIndex) + { + return reallyBigNumber; + } + + /* + If this node is completely within [L, R], + then return it as the min value. + */ + if(L <= nodeStartIndex && nodeEndIndex <= R) + { + return stArray[nodeIndex]; + } + + /* + Otherwise this node is partially within [L, R]. + (Recursively) check this node's children and return the min of those two. + */ + middleIndex = nodeStartIndex + ((nodeEndIndex - nodeStartIndex) / 2); + + leftChildNodeIndex = 2 * nodeIndex; + rightChildNodeIndex = 2 * nodeIndex + 1; + + leftChildMin = RecursivelySearchForMin(L, R, leftChildNodeIndex, nodeStartIndex, middleIndex); + rightChildMin = RecursivelySearchForMin(L, R, rightChildNodeIndex, middleIndex + 1, nodeEndIndex); + + minOfThisNode = min(leftChildMin, rightChildMin); + + return minOfThisNode; +} + +// Find the minimum value between indices L and R. +function FindMin(L, R) +{ + // Recursively search the tree, starting from the root (node 0). + min = RecursivelySearchForMin(L, R, 0, 0, origArrayLength - 1); + return min; +} +``` +## Example + +Given an array A[1 … n] of n objects taken from a well-ordered set(such as numbers), returns the position of the minimal element in the specified sub-array A[l … r], (r<=n). + +When A = [2,4,3,1,6,7,8,9,1,7], then the answer to the range minimum query for the sub-array A[2 … 7] = [3,1,6,7,8,9] is 3, as A[3] = 1. + +![Pic03](https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcRviJId20R7OU-1qdCFVqWY6jkM9lmqw2LPj_PGRqaDbW8ThaDf&usqp=CAU) + +## Time Complexity + +Time Complexity for tree construction is __O(n)__. There are total __2N - 1__ nodes, and value of every node is calculated only once in tree construction. + +Time complexity to query is __O(Log N)__. To query a range minimum, at worst, we'll have to go down the height of the tree twice, once for the left subtree, and one for the right subtree. We process at most two nodes at every level and number of levels is **O(Log N)**. + +## Implementation + +-[C Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Segment_Tree_RMQ/Segement_Tree_RMQ.c) + +-[C++ Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Segment_Tree_RMQ/Segement_Tree_RMQ.cpp) + +-[Python Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Segment_Tree_RMQ/Segement_Tree_RMQ.py) + +-[Dart Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Segment_Tree_RMQ/Segment_Tree_RMQ.dart) + +-[Java Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Segment_Tree_RMQ/Segment_Tree_RMQ.java) + +## References + +#### Images source: +1. [https://www.hackerearth.com/practice/notes/segment-tree-and-lazy-propagation/](https://www.hackerearth.com/practice/notes/segment-tree-and-lazy-propagation/) +2. [https://www.topcoder.com/community/competitive-programming/tutorials/range-minimum-query-and-lowest-common-ancestor/](https://www.topcoder.com/community/competitive-programming/tutorials/range-minimum-query-and-lowest-common-ancestor/) + +#### Websites: +1. [https://www.hackerearth.com/practice/data-structures/advanced-data-structures/segment-trees/tutorial/](https://www.hackerearth.com/practice/data-structures/advanced-data-structures/segment-trees/tutorial/) +2. [https://www.geeksforgeeks.org/segment-tree-set-1-range-minimum-query/](https://www.geeksforgeeks.org/segment-tree-set-1-range-minimum-query/) +3. [https://www.geeksforgeeks.org/segment-tree-set-1-sum-of-given-range/](https://www.geeksforgeeks.org/segment-tree-set-1-sum-of-given-range/) +4. [https://www.srcmake.com/home/segment-tree](https://www.srcmake.com/home/segment-tree) diff --git a/Segment_Tree_RMQ/Segement_Tree_RMQ.c b/Segment_Tree_RMQ/Segement_Tree_RMQ.c new file mode 100644 index 000000000..dc5609cba --- /dev/null +++ b/Segment_Tree_RMQ/Segement_Tree_RMQ.c @@ -0,0 +1,91 @@ +#include +#include +#include + +int min(int x, int y) +{ + return (x < y) ? x : y; +} + +void build(int *a, int *tree, int start, int end, int treenode) +{ + if (start == end) + { + tree[treenode] = a[start]; + return; + } + + int mid; + mid = (start + end) / 2; + + //compute the values in the left and right subtrees + build(a, tree, start, mid, 2 * treenode); + build(a, tree, mid + 1, end, 2 * treenode + 1); + + /*store the minimum value in the first and + second half of the interval*/ + tree[treenode] = min(tree[2 * treenode], tree[2 * treenode + 1]); + return; +} + +int query(int *tree, int start, int end, int l, int r, int treenode) +{ + /* if the current interval doesn’t intersect + the query interval return INT_MAX*/ + if (start > r || end < l) + { + return INT_MAX; + } + + /*if the current interval is included in + the query interval return tree[treenode]*/ + if (start >= l && end <= r) + { + return tree[treenode]; + } + + int mid; + mid = (start + end) / 2; + + //return the minimum value + int e = query(tree, start, mid, l, r, 2 * treenode); + int f = query(tree, mid + 1, end, l, r, 2 * treenode + 1); + + return min(e, f); +} + +int main() +{ + int size; + printf("Enter the size of the array: "); + scanf("%d", &size); + int array[size]; + int *segTree = (int *)malloc(sizeof(4 * size)); + + printf("Enter the elements.\n"); + for(int i = 0; i < size; i++) + { + scanf("%d", &array[i]); + } + + build(array, segTree, 0, size - 1, 1); + + int start, end; + printf("Enter the range of the query: "); + scanf("%d %d", &start, &end); + int result = query(segTree, 0, size - 1, start - 1, end - 1, 1); + + printf("Minimum value in index range %d to %d is: %d\n", start, end, result); + + return 0; +} + +/* +Input: +Enter the size of the array.: 5 +-7 3 -1 8 1 +Enter the range of the query.: 2 5 + +Output: +Minimum value in index range 2 to 5 is: -1 +*/ diff --git a/Segment_Tree_RMQ/Segment_Tree_RMQ.dart b/Segment_Tree_RMQ/Segment_Tree_RMQ.dart new file mode 100644 index 000000000..8aa67af20 --- /dev/null +++ b/Segment_Tree_RMQ/Segment_Tree_RMQ.dart @@ -0,0 +1,230 @@ +/** + * Dart implementation of Segment Tree for Range Minimum Query + * ------------------------------------------------------------------------- + * Segment Tree is a binary tree whose nodes are ranges of an interval. + * Each node has a value corresponding to it's interval. + * Construction of a Segment Tree takes O(n) time. + * Querying on the same takes O(logn) time. + * Hence, many queries can be answered efficiently in time using Segment Tree. + * + * +*/ + +// Importing required libraries +import 'dart:io'; +import 'dart:math'; + +// Maximum range of int of 64 bits. +const int int64MaxValue = 9223372036854775807; + +// Function to find logarithm to base 2. +double logtobase2(int n){ + + return log(n) / log(2); + +} + +// Function to update value at a particular position in the tree +void updateNode(List tree , int treestart , int treeend , int nodeindex , int position , int newval){ + + if (treestart == treeend){ + + tree[nodeindex] = newval; + + } + else{ + + int mid = (treestart + ((treeend - treestart) / 2)).floor(); + + if (position < mid){ + + updateNode(tree , treestart , mid , 2 * nodeindex , position , newval); + + } + else{ + + updateNode(tree , mid + 1 , treeend, 2 * nodeindex + 1 , position, newval); + + } + + tree[nodeindex] = min(tree[2 * nodeindex] , tree[2 * nodeindex + 1]); + + } + +} + +// Function to query on a Segment Tree +int queryonSegmentTree(List tree , int start , int end , int treestart , int treeend , int nodeindex){ + + if (start > end){ + + return int64MaxValue; + + } + + // Base Case + if (start == treestart && end == treeend){ + + return tree[nodeindex]; + + } + + // Finding the index of midpoint + int mid = (treestart + (treeend - treestart) / 2).floor(); + + int value1 , value2; + + + // Recursion to find the minimum. + value1 = queryonSegmentTree(tree , start , min(end,mid) , treestart , mid , 2 * nodeindex ); + + value2 = queryonSegmentTree(tree , max(start , mid + 1) , end , mid + 1 , treeend , 2 * nodeindex + 1 ); + + // Returning minimum. + return min(value1 , value2); + +} + +// Function to construct the Segment Tree. +void constructSegmentTree(List tree , List numbers , int start , int end , int nodeindex){ + + // Base Case + if (start == end){ + + tree[nodeindex] = numbers[start]; + return; + + } + + // Finding index of the midpoint. + int mid = (start + ((end - start) / 2)).floor(); + + // Recursion to find minimum. + constructSegmentTree(tree , numbers , start , mid , 2 * nodeindex); + + constructSegmentTree(tree , numbers , mid + 1 , end , 2 * nodeindex + 1); + + // Finding minimum of the parent from its children. + tree[nodeindex] = min(tree[2 * nodeindex],tree[2 * nodeindex + 1]); + +} + +// Driver function of the program. +void main(){ + + // Taking input of number of array elements. + print("Enter number of elements: "); + + var input = stdin.readLineSync(); + + int n = int.parse(input); + + // Taking input of the number array (num[i]). + print("Enter array of numbers:"); + + input = stdin.readLineSync(); + + var lis = input.split(' '); + + List numbers = lis.map(int.parse).toList(); + + // Calculating the depth of the possible binary tree. + int depth = logtobase2(n).ceil(); + // Finding the maximum number of nodes in the binary tree. + int num_nodes = 2 * pow(2 , depth) - 1; + + // Initializing the Segment tree. + List tree = List.generate(num_nodes + 1 , (i) => 0); + + // Constructing the Segment Tree. + constructSegmentTree(tree , numbers , 0 , n - 1 , 1); + + // Taking input of number of queries. + print("Enter number of queries: "); + + input = stdin.readLineSync(); + + int q = int.parse(input); + + List queries = List(2); + + int flag; + + + // Taking input of queries. + print("Enter queries: "); + + for (int i = 0 ; i < q ; i ++){ + + print("Enter 1 to retrieve minimum in a range or 2 to update a value: "); + + input = stdin.readLineSync(); + + flag = int.parse(input); + + print("Enter corresponding query: "); + + input = stdin.readLineSync(); + + lis = input.split(' '); + + queries = lis.map(int.parse).toList(); + + if (flag == 2){ + + numbers[queries[0]] = queries[1]; + updateNode(tree , 0 , n - 1 , 1 , queries[0] , queries[1]); + + } + else{ + + // Printing output of each query. + print(queryonSegmentTree(tree , queries[0] , queries[1] , 0 , n - 1 , 1)); + + } + + } + +} + +/** + * + * Sample Input & Output + * --------------------------- + * Enter number of elements: + * 10 + * Enter array of numbers: + * 12 43 9 -2 1 8 6 5 10 23 + * Enter number of queries: + * 6 + * Enter queries: + * Enter 1 to retrieve minimum in a range or 2 to update a value: + * 1 + * Enter corresponding query: + * 1 2 + * 9 (Output) + * Enter 1 to retrieve minimum in a range or 2 to update a value: + * 2 + * Enter corresponding query: + * 0 -12 + * Enter 1 to retrieve minimum in a range or 2 to update a value: + * 1 + * Enter corresponding query: + * 1 2 + * -12 (Output) + * Enter 1 to retrieve minimum in a range or 2 to update a value: + * 2 + * Enter corresponding query: + * 7 -100 + * Enter 1 to retrieve minimum in a range or 2 to update a value: + * 1 + * Enter corresponding query: + * 4 9 + * -100 (Output) + * Enter 1 to retrieve minimum in a range or 2 to update a value: + * 1 + * Enter corresponding query: + * 2 6 + * -2 (Output) + * + */ diff --git a/Selection_Sort/Selection_Sort.dart b/Selection_Sort/Selection_Sort.dart new file mode 100644 index 000000000..6dfa8e256 --- /dev/null +++ b/Selection_Sort/Selection_Sort.dart @@ -0,0 +1,63 @@ +//selection sort + +import 'dart:io'; + +void selection_sort (List arr, int n) +{ + int temp, min_index; + + for (int i = 0; i < n - 1; i++) + { + min_index = i; + + for (int j = i + 1; j < n; j++) + if ( arr[j] < arr[min_index] ) + min_index = j; + + if (i != min_index) + { + temp = arr[i]; + arr[i] = arr[min_index]; + arr[min_index] = temp; + } + } +} + +main() +{ + print ("Enter the size of array "); + int size = int.parse (stdin.readLineSync()); + + List array = List(); + + for (int i = 0; i < size; i++) + { + print ("Enter $i element "); + var ele = int.parse (stdin.readLineSync()); + array.add (ele); + } + + selection_sort (array, size); + + print (array); + +} + +/* +Enter the size of array +5 +Enter 0 element +50 +Enter 1 element +40 +Enter 2 element +30 +Enter 3 element +20 +Enter 4 element +10 +Sorted array is +[10, 20, 30, 40, 50] +*/ + + diff --git a/Selection_Sort/Selection_Sort.php b/Selection_Sort/Selection_Sort.php new file mode 100644 index 000000000..e4f57201d --- /dev/null +++ b/Selection_Sort/Selection_Sort.php @@ -0,0 +1,43 @@ +/* + * Selection sort is used for sorting arrays. + * It is based on identifying minimum element from the array + * and placing it in beginning. + * This is repeated until we reach the end of array. + */ + +/* + * Sample Output + * 1 3 4 5 10 + */ diff --git a/Selection_Sort/Selection_Sort.ts b/Selection_Sort/Selection_Sort.ts new file mode 100644 index 000000000..1c77907e8 --- /dev/null +++ b/Selection_Sort/Selection_Sort.ts @@ -0,0 +1,35 @@ +// function for selection sort logic +function Selection_Sort(numbers: number[]) : number[]{ + + let i: number; + let j: number; + let min: number; + let temp: number; + + // outer loop to traverse through each element + for(i = 0; i < numbers.length - 1; i++){ + min = i; + + // inner loop finds the minimum element and puts it in the beginning. + for(j = i + 1; j < numbers.length; j++){ + if(numbers[j] < numbers[min]){ + min = j; + } + } // inner loop ends + + if(i !== min){ + temp = numbers[i]; + numbers[i] = numbers[min]; + numbers[min] = temp; + } + } // outer loop ends + + return numbers; +} + +const numbers: number[] = [10, 9, 8, 1, 5, 2, 4, 7, 3]; + +console.log(Selection_Sort(numbers)); + +// INPUT [10, 9, 8, 1, 5, 2, 4, 7, 3] +// OUTPUT [ 1, 2, 3, 4, 5, 7, 8, 9, 10 ] diff --git a/Selection_Sort/Selection_sort.rs b/Selection_Sort/Selection_sort.rs new file mode 100644 index 000000000..2653dd244 --- /dev/null +++ b/Selection_Sort/Selection_sort.rs @@ -0,0 +1,63 @@ +// Rust program for Selection Sort +use std::io; + +fn main() { + println!(" Enter number of elements to be entered in the array "); + let mut size = String::new(); + + io::stdin().read_line(&mut size).expect("failed to read input."); + let size: usize = size.trim_end().parse().expect("invalid input"); + + let mut vector: Vec = Vec::with_capacity(size as usize); + + println!("Enter elements of array "); + let mut index = 0; + + // Enter values into vector + while index < size { + index += 1; + // Note: Rust takes spaces as non-intergral value + let mut temp_arr = String::new(); + io::stdin().read_line(&mut temp_arr).expect("failed to read input."); + let temp_arr: usize = temp_arr.trim_end().parse().expect("invalid input"); + vector.push(temp_arr); + } + + for index in 0..size - 1 { + let mut minimum = index; + let mut j = index + 1; + while j < size { + if vector[j] < vector[minimum] { + minimum = j; + j += 1; + } + // Swapping the smallest number in vector with the indexth location number + let temp = vector[minimum]; + vector[minimum] = vector[index]; + vector[index] = temp; + } + } + + println!("Sorted array is "); + for index in 0..size { + println!("{:?}",vector[index]); + } +} +/* +TEST CASE + +INPUT + Enter number of elements to be entered in the array +3 +Enter elements of array +3 +2 +1 + +OUTPUT +Sorted array is +1 +2 +3 +*/ + diff --git a/Shell_Sort/Shell_Sort.cs b/Shell_Sort/Shell_Sort.cs new file mode 100644 index 000000000..b41a7962a --- /dev/null +++ b/Shell_Sort/Shell_Sort.cs @@ -0,0 +1,66 @@ +// C# program implementation of the ShellSort algorithm +using System; + +class ShellSort +{ + //function to implement ShellSort + void shellsort(int []array, int size) + { + // Beginning with a big gap, and then keep on reducing it. + for (int g = size/2; g >= 1; g /= 2) + { + // Performing an insertion sort + for (int i = g; i < size; i += 1) + { + int j, temp = array[i]; + + //Shift other elements until the correct position of a[i] is found + for (j = i; array[j - g] > temp && j >= g ; j -= g) + array[j] = array[j - g]; + + // put the element a[i] in its correct position + array[j] = temp; + } + } + } + + public static void Main() + { + + int size; + Console.Write("How many numbers do you want to sort : "); + size = Convert.ToInt32(Console.ReadLine()); + int[] array = new int[size]; + Console.Write("\nEnter the numbers : "); + for (int i = 0; i < size; i++) + array[i] = Convert.ToInt32(Console.ReadLine()); + ShellSort ob = new ShellSort(); + ob.shellsort(array, size); + Console.Write("\nAfter sorting : "); + for (int i = 0; i < size; i++) + Console.Write(array[i] + " "); + } +} + +/*SAMPLE INPUT AND OUTPUT +SAMPLE 1 +How many numbers do you want to sort : 7 +Enter the numbers : + 4 + 9 + 3 + 9 + 4 + 7 + 5 +After sorting : 3 4 4 5 7 9 9 +SAMPLE 2 +How many numbers do you want to sort : 5 +Enter the numbers : + 5 + 1 + 7 + 3 + 2 +After sorting : 1 2 3 5 7 +*/ diff --git a/Shell_Sort/Shell_Sort.go b/Shell_Sort/Shell_Sort.go new file mode 100644 index 000000000..aafea87fa --- /dev/null +++ b/Shell_Sort/Shell_Sort.go @@ -0,0 +1,80 @@ +package main + +import ( + "fmt" + "strconv" +) + +func main() { + var n int + fmt.Scanf("%d", &n) + + // input the size of the array + var arr = make([]int, n) + + // input the elements of the array + for i := 0; i < n; i++ { + if _, err := fmt.Scan(&arr[i]); err != nil { + panic(err) + } + } + + // calling the shellsort function to sort the array + shellsort(arr) + + // printing the sorted array + for i := 0; i < n; i++ { + fmt.Print(strconv.Itoa(arr[i])+" ") + } +} + +func shellsort(items []int) { + var ( + n = len(items) + gaps = []int{1} + k = 1 + + ) + + // start with a bigger gap and then gradually reduce the gaps + for { + gap := element(2, k) + 1 + if gap > n-1 { + break + } + gaps = append([]int{gap}, gaps...) + k++ + } + + // shell sort logic + for _, gap := range gaps { + for i := gap; i < n; i += gap { + j := i + for j > 0 { + if items[j-gap] > items[j] { + items[j-gap], items[j] = items[j], items[j-gap] + } + j = j - gap + } + } + } +} + +// function to help calculate number of gaps +func element(a, b int) int { + e := 1 + for b > 0 { + if b&1 != 0 { + e *= a + } + b >>= 1 + a *= a + } + return e +} + +/* + SAMPLE INPUT: 5 + 5 4 1 2 3 + SAMPLE OUTPUT: 1 2 3 4 5 +*/ \ No newline at end of file diff --git a/Shell_Sort/Shell_Sort.php b/Shell_Sort/Shell_Sort.php new file mode 100644 index 000000000..b37063bc7 --- /dev/null +++ b/Shell_Sort/Shell_Sort.php @@ -0,0 +1,41 @@ + 0) + { + for($b = $a; $b < count($new_arr); $b++) //Comparing and Sorting the elements of array + { + $d = $new_arr[$b]; + $c = $b; + while($c >= $a && $new_arr[$c - $a] > $d) + { + $new_arr[$c] = $new_arr[$c - $a]; + $c -= $a; + } + $new_arr[$c] = $d; + } + $a = round($a / 2.2); + } + return $new_arr; //Array is returned after sorting +} + +//Driver Code : +$sample_arr = array(4, 9, 11, -5, 8, 1, 0, 6, -3); +echo "Array before sorting :
"; +echo implode(', ', $sample_arr); +echo "
"; +echo "
Array after sorting :
"; +echo implode(', ', shell_Sort($sample_arr)). PHP_EOL; + +/* +Implementing Shell Sort Algorithm : + +Array before sorting : +4, 9, 11, -5, 8, 1, 0, 6, -3 + +Array after sorting : +-5, -3, 0, 1, 4, 6, 8, 9, 11 +*/ + +?> diff --git a/Shell_Sort/Shell_Sort.rb b/Shell_Sort/Shell_Sort.rb new file mode 100644 index 000000000..30b17ada8 --- /dev/null +++ b/Shell_Sort/Shell_Sort.rb @@ -0,0 +1,76 @@ +# Shell Sort In Ruby + +# Function Definition +def shell_sort(values) + inct = values.size / 2 + + while inct > 0 + inct.upto(values.size - 1){ |i| + j = i + temp = values[i] + + while j >= inct and values[j - inct] > temp + values[j] = values[j - inct] + j -= inct + end + + values[j] = temp + } + inct = (inct == 2 ? 1 : inct * 10 / 22) + end + values +end + +# Taking User Input +puts "Enter the size of array: " +size = gets.to_i +puts +input_array = Array.new(size) + +counter = 0 + +# Input Array Values Using While Loop +while(counter != size) + puts "Enter the value at index #{counter}: " + input_array[counter] = gets.to_i + counter += 1 +end + +puts + +puts "Input Array: #{input_array}" +puts "Shell Sort: " + +# Function Call +shell_sort(input_array) +puts "#{input_array}" + += begin + +Enter the size of array: 5 + +Enter the value at index 0: 121 +Enter the value at index 1: 71 +Enter the value at index 2: 1 +Enter the value at index 3: 88 +Enter the value at index 4: 9 + +Input Array: [121, 71, 1, 88, 9] +Shell Sort: [1, 9, 71, 88, 121] + +----------------------------------------------- + +Enter the size of array: 7 + +Enter the value at index 0: 68 +Enter the value at index 1: 1 +Enter the value at index 2: 11 +Enter the value at index 3: -8 +Enter the value at index 4: 0 +Enter the value at index 5: 3 +Enter the value at index 6: 35 + +Input Array: [68, 1, 11, -8, 0, 3, 35] +Shell Sort: [-8, 0, 1, 3, 11, 35, 68] + += end diff --git a/Sieve_Of_Eratosthenes/Sieve_Of_Eratosthenes.php b/Sieve_Of_Eratosthenes/Sieve_Of_Eratosthenes.php new file mode 100644 index 000000000..342c1f089 --- /dev/null +++ b/Sieve_Of_Eratosthenes/Sieve_Of_Eratosthenes.php @@ -0,0 +1,29 @@ + + +/*Input: +Enter an integer + 10 +Output + 2 3 5 7 +*/ diff --git a/Sieve_Of_Eratosthenes/Sieve_Of_Eratosthenes.ts b/Sieve_Of_Eratosthenes/Sieve_Of_Eratosthenes.ts new file mode 100644 index 000000000..49fe44805 --- /dev/null +++ b/Sieve_Of_Eratosthenes/Sieve_Of_Eratosthenes.ts @@ -0,0 +1,51 @@ +export {} + +function SieveOfEratosthenes (n : number){ + + // Create a boolean array "prime[0..n]" and initialize + // all entries of it as true. A value in prime[i] will + // finally be false if i is Not a prime, else true. + + let prime : boolean[] = [true]; + let p : number; + let i : number; + + for(p = 0; p <= n; p++) + prime.push(true); + + for(p = 2; p * p <= n; p++){ + // If prime[p] is true, then it is a prime + if(prime[p]){ + // Update all multiples of p + for(i = p * p; i <= n; i += p) + prime[i] = false; + } + } + + // Print all prime numbers + for(p = 2; p <= n; p++) + if(prime[p]) + console.log(p); +} + +let n : number = 30; +console.log("The prime numbers upto " + n); +SieveOfEratosthenes(n); + +/* +INPUT +n = 30 + +OUTPUT +The prime numbers upto 30 +2 +3 +5 +7 +11 +13 +17 +19 +23 +29 +*/ diff --git a/Sleep_Sort/README.md b/Sleep_Sort/README.md new file mode 100644 index 000000000..6e39d8942 --- /dev/null +++ b/Sleep_Sort/README.md @@ -0,0 +1,84 @@ +# Sleep Sort + + Sleep sort works by starting a separate task for each item to be sorted, where each task sleeps for an interval corresponding to the item's sort key, then emits the item. Items are then collected sequentially in time. +# Example + Let’s assume we have a laptop that’s takes 1 seconds to work through each element. + + **INPUT: 10 8 6** + + - 1s 10 + - 2s: 8 + - 3s: 6 + - 9s: print(6) (6 wake up so print it) + - 10s: print(8) (8 wake up so print it) + - 11s: print(10) (10 wake up so print it) + + **OUTPUT : 6 8 10** + + # Time complexity + + - Creating multiple threads is done internally by the OS using a priority queue (used for scheduling purposes). Hence inserting all the array elements in the priority queue takes O(Nlog N) time. + +- Also the output is obtained only when all the threads are processed, i.e., when all the elements ‘wakes’ up. Since it takes O(arr[i]) time to wake the ith array element’s thread. So it will take a maximum of O(max_element(array)) for the largest element of the array to wake up. + + - Thus overall time complexitu is ,O(NlogN + max(input)) + ("where, N = number of elements in the input array, and input = input array elements") + + # Limitations + - This algorithm won’t work for negative numbers as a thread cannot sleep for a negative amount of time. + + # Sleep Sort Algorithm implementation in Python + import threading + import time + + _lk = threading.Lock() + + class SleepSortThread(threading.Thread): + def __init__(self, val): + self.val = val + threading.Thread.__init__(self) + + def run(self): + global _lk + # Thread is made to sleep in proportion to value + time.sleep(self.val * 0.1) + # Acquire lock + _lk.acquire() + print(self.val, end = " ") + # Release lock + _lk.release() + + def SleepSort(list): + ts = [] + # Intialize a thread corresponding to each element in list + for i in list: + t = SleepSortThread(i) + ts.append(t) + # Start all Threads + for i in ts: + i.start() + # Wait for all threads to terminate + for i in ts: + i.join() + + x = [2, 4, 3, 1, 6, 8, 4] + x = SleepSort(x) + + # Output + # 1 2 3 4 4 6 8 + +# Pseudocode + + procedure print(n) + sleep n second + print(n) + end + for arg in args + run print(arg) in background + end + + wait for all processes o finish + +[Reference: Geeksforgeeks](https://www.geeksforgeeks.org/sleep-sort-king-laziness-sorting-sleeping/) + +[Reference: Wikipedia](https://it.wikipedia.org/wiki/Sleep_sort) diff --git a/Sleep_Sort/Sleep_Sort.go b/Sleep_Sort/Sleep_Sort.go new file mode 100644 index 000000000..7d448061e --- /dev/null +++ b/Sleep_Sort/Sleep_Sort.go @@ -0,0 +1,47 @@ +package main + +import "fmt" +import "time" + +func sleepNumber(number int, results chan<- int) { + time.Sleep(time.Duration(number) * time.Second) + results <- number +} + +func sleepSort(data []int) { + results := make(chan int, len(data)) + for _, v := range data { + go sleepNumber(v, results) + } + + for i, _ := range data { + data[i] = <-results + } + close(results) +} + +func main() { + var x int + fmt.Printf("Enter the size of the array : ") + fmt.Scan(&x) + fmt.Printf("Enter the elements of the array : ") + a := make([]int, x) + for i := 0; i < x; i++ { + fmt.Scan(&a[i]) + } + data := a // A copy of the array 'a' is assigned to 'data' + sleepSort(data) + fmt.Println("After sorting", data) +} + +/* + +Sample Input : + Enter the size of the array : 5 + Enter the elements of the array : 34 23 1 78 6 + +Sample Output : + After sorting [1 6 23 34 78] + +*/ + diff --git a/Spiral_Array/SpiralArray.c b/Spiral_Array/SpiralArray.c new file mode 100644 index 000000000..ef1da21b5 --- /dev/null +++ b/Spiral_Array/SpiralArray.c @@ -0,0 +1,96 @@ +#include +int main() +{ + int a[20][20], int d, int i, int j, int ra, int ca, int r, int c, int k; + //accepting number of rows + do + { + printf("enter number of rows:"); + scanf("%d", &ra); + }while(ra < 1); + //accepting number of columns + do + { + printf("enter number of columns:"); + scanf("%d", &ca); + }while(ca < 1); + printf("\n\t enter elements:"); + printf("\n"); + //accepting matrix + for(i = 0; i < ra; i++) + { + for(j = 0; j < ca; j++) + { + scanf("%d", &a[i][j]); + } + } + printf(" INTIAL MATRIX = "); + for(i = 0; i < ra; i++) + { + printf("\n"); + + for(j = 0; j < ca; j++) + { + printf("%d" , a[i][j]); + } + } + printf("\n"); + printf("spiral form = "); + printf("\n"); + r = ra - 1; + c = ca - 1; + i = 0; + j = 0; + //printing each side so as to get spiral form + while(i <= c && j <= r) + { + if(d == 0) + { + for(k = i; k <= c; k++) + { + printf("%d", a[j][k]); + } + j++; + d = 1; + } + else if(d == 1) + { + for(k = j; k <= r; k++) + { + printf("%d", a[k][c]); + } + c--; + d = 2; + } + else if(d == 2) + { + for(k = c; k >= i; k--) + { + printf("%d", a[r][k]); + } + r--; + d = 3; + } + else if(d == 3) + { + for(k = r; k >= j; k--) + { + printf("%d", a[k][i]); + } + i++; + d = 0; + } + } +return 0; +} +/* Test Cases + +Input: + 1 2 3 4 + 5 6 7 8 + 9 10 11 12 + 13 14 15 16 +Output: +1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10 + +*/ diff --git a/Ternary_Search/Readme.md b/Ternary_Search/Readme.md new file mode 100644 index 000000000..f2f14dfc4 --- /dev/null +++ b/Ternary_Search/Readme.md @@ -0,0 +1,46 @@ +# Ternary Search + +Ternary search is a searching technique that is used to search the position of a specific value in an array. Ternary search is a divide-and-conquer algorithm. It is mandatory for the array to be sorted (in which you will search for an element). + +The array is divided into three parts and then we determine in which part the element exists. In this search, after each iteration it neglects ⅓ part of the array and repeats the same operations on the remaining ⅔. + +## Algorithm + + 1.mid1 = start + (end - start) / 3 and mid2 = mid1 + (end - start) / 3. + + 2.Compare the element to be searched with the element at mid1. If they are equal then return mid1. + + 3.Compare the element to be searched with the element at mid2. If they are equal then return mid2. + + 4.If the element to be searched is less than element at mid1 recur to the first part, otherwise if it is greater than the element at mid2 recur to the third part. If not both, then recur to the second part. + +## Pseudo Code + +``` + ternarySearch(array, start, end, searchKey) + if start <= end then + mid1 = start + (end - start) / 3 + mid2 = mid1 + (end - start) / 3 + if array[mid1] = searchKey then + return mid1 + if array[mid2] = searchKey then + return mid2 + if searchKey < array[mid1] then + call ternarySearch(array, start, mid1 - 1, searchKey) + if searchKey > array[mid2] then + call ternarySearch(array, mid2 + 1, end, searchKey) + else + call ternarySearch(array, mid1 + 1, mid2-1, searchKey) +``` + +## Complexity + Time Complexity: O(log3 n) + Space Complexity: O(1) + + ## Implementation + * [C Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Ternary_Search/Ternary_Search.c) + * [C++ Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Ternary_Search/Ternary_Search.cpp) + * [Java Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Ternary_Search/Ternary_Search.java) + * [Coffee Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Ternary_Search/Ternary_Search.coffee) + * [Python Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Ternary_Search/Ternary_Search.py) + * [JS Code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Ternary_Search/Ternary_Search.js) diff --git a/Ternary_Search/Ternary_Search.cs b/Ternary_Search/Ternary_Search.cs new file mode 100644 index 000000000..5d4212197 --- /dev/null +++ b/Ternary_Search/Ternary_Search.cs @@ -0,0 +1,103 @@ +using System; + +public class ternarysrc { + + // Function to perform Ternary Search + static int ternarySearch(int l, int r, int key, int[] ar) + { + while (r >= l) + { + + // Finding the mid1 and mid2 + int mid1 = l + (r - l) / 3; + int mid2 = r - (r - l) / 3; + + // To check if key is present at any mid + if (ar[mid1] == key) + { + return mid1; + } + if (ar[mid2] == key) + { + return mid2; + } + + // Checking region where KEY might be present + if (key < ar[mid1]) + { + r = mid1 - 1; + } + else if (key > ar[mid2]) + { + l = mid2 + 1; + } + else + { + l = mid1 + 1; + r = mid2 - 1; + } + } + + // If the KEY is not found + return -1; + } + + // Main Function to Execute + public static void Main(String[] args) + { + int l, r, p, i, key = 0, len = 0; + + // Taking the input of Array Length from user + Console.WriteLine("Enter Length of Array : "); + len = Convert.ToInt32(Console.ReadLine()); + + int[] ar = new int[len]; + + Console.WriteLine("Enter Array Elements in Ascending Order : "); + + for(i = 0; i < len; i++ ) // Array input + { + ar[i] = Convert.ToInt32(Console.ReadLine()); + } + + // Starting index + l = 0; + + // Ending Index + r = len - 1; + + Console.WriteLine("\nEnter the Number to be Searched : "); + // KEY to be searched in the array + key = Convert.ToInt32(Console.ReadLine()); + + // Searching the KEY using ternarySearch function + p = ternarySearch(l, r, key, ar); + + + // Checking if the KEY is present or not + if(p == -1) + Console.WriteLine("\nNumber Not Found"); + else + Console.WriteLine("\n The Index of " + key + " is " + p); + Console.ReadKey(); + + + } +} + +// Sample Input/Output: +/* + Enter Length of Array : 5 + Enter Array Elements in Ascending Order : + 10 + 20 + 30 + 40 + 50 + + Enter the Number to be Searched : + 50 + + The Index of 50 is 4 + +*/ diff --git a/Ternary_Search/Ternary_Search.kt b/Ternary_Search/Ternary_Search.kt new file mode 100644 index 000000000..65b82347a --- /dev/null +++ b/Ternary_Search/Ternary_Search.kt @@ -0,0 +1,77 @@ + import java.util.* + import kotlin.collections.ArrayList + + //Ternary Search begins + public fun ternarySearch(l:Int, r:Int, key:Int, ar:ArrayList): Int { + if(r>=1){ + var mid1 = l + (r - l) / 3 + var mid2 = r - (r - l) / 3 + + //Searching for the key element + if (ar[mid1] == key) { + return mid1 + } + + if (ar[mid2] == key) { + return mid2 + } + + if (key < ar[mid1]) { + return ternarySearch(l, mid1 - 1, key, ar) + } + + else if (key > ar[mid2]) { + return ternarySearch(mid2 + 1, r, key, ar) + } + + else { + return ternarySearch(mid1 + 1, mid2 - 1, key, ar) + } + } + return -1; +} + + //Main function + fun main() { + var l:Int = 0 + var r:Int + var p:Int + var key:Int + var scan1: Scanner = Scanner(System.`in`) + + //var ar = arrayOf(1,2,3,4,5,6,7,8,9,10) + var ar = ArrayList() + + //Taking input from user + println("Enter the number of elements: ") + var n:Int = scan1.nextInt() + var temp:Int + for (i in 1..n) { + temp = scan1.nextInt() + ar.add(temp) + } + + //Sorting the array + println("Sorting the array in ascending order...") + ar.sort() + r = ar.count() + println("Enter the key element to search for:") + key = scan1.nextInt() + p = ternarySearch(l, r, key, ar) + //Printing the key element with its position + print("Index of $key is $p \n") + + + /*Sample Input and Output + Enter the number of elements : + 6 + 5 + 4 + 3 + 2 + 1 + Sorting the array in ascending order... + Enter the key element to search for: + 5 + Index of 5 is 4 + */ diff --git a/Ternary_Search/Ternary_Search.php b/Ternary_Search/Ternary_Search.php new file mode 100644 index 000000000..1f8e53a4e --- /dev/null +++ b/Ternary_Search/Ternary_Search.php @@ -0,0 +1,63 @@ += l means there is some space to search x in ar + if( $r >= $l ) + { + /* Dividing the array into three parts + * namely ar[0]..ar[mid1], ar[mid1]...ar[mid2], ar[mid2]...ar[length - 1] + */ + $mid1 = (int)($l + ($r - $l) / 3); + $mid2 = (int)($mid1 + ($r - $l) / 3); + + // if x is present at mid1 + if($ar[$mid1] == $x) + return $mid1; + + // if x is present at mid2 + if($ar[$mid2] == $x) + return $mid2; + + // if x is present in left one-third part + if($ar[$mid1] > $x) + return ternary_search($ar, $l, $mid - 1, $x); + + // if x is present in right one third part + if($ar[$mid2] < $x) + return ternary_search($ar, $mid2 + 1, $r, $x); + + // if x is present in middle one third part + return ternary_search($ar, $mid1 + 1, $mid2 - 1, $x); + } + else + return -1; + // if x is not present in ar + } + + // Sample Input (make sure to use sorted array) + $ar = array(1, 2, 3, 4, 5, 6, 7, 8); + + // x will contain the value which is to be searched in given array + $x = 4; + + /* to search x in ar, we firstly pass whole of array to the ternary_search() function + * i.e., (l == 0, r == count(ar) - 1), where count(ar) returns the number of elements in ar + */ + + $index_x = ternary_search($ar, 0, count($ar) - 1, $x); + // index_x holds the "index" where x is found in ar or -1 if not found + + echo "$index_x"; + + /* Sample Output + * 3 + * Note that the 3 is the index of "4" in ar (ar[3] = 4) + */ +?> diff --git a/Ternary_Search/Ternary_Search.rb b/Ternary_Search/Ternary_Search.rb new file mode 100644 index 000000000..07bae69d4 --- /dev/null +++ b/Ternary_Search/Ternary_Search.rb @@ -0,0 +1,55 @@ +=begin + Ternary Search +------------------------------- +Ternary search is a searching technique that is used to search the position of a specific value in an array. +Ternary search is a divide-and-conquer algorithm. +It is mandatory for the array to be sorted (in which you will search for an element). +The array is divided into three parts and then we determine in which part the element exists. +In this search, after each iteration it neglects ⅓ part of the array and repeats the same operations on the remaining ⅔. +Time Complexity: O(log3 n) +Space Complexity: O(1) +=end + +def ternarySearch(l, r, key, ar) #function to perform ternary search + + if (r >= l) + #find mid1 and mid2 + mid1 = l + (r - l) / 3 + mid2 = r - (r - l) / 3 + if ar[mid1] == key #check if key is equal to mid1 + mid1 + elsif ar[mid2] == key #check if key is equal to mid2 + mid2 + #Since key is not present at mid, check in which region it is present + #then repeat the Search operation in that region + elsif key < ar[mid1] + ternarySearch(l, mid1 - 1, key, ar) + elsif (key > ar[mid2]) + ternarySearch(mid2 + 1, r, key, ar) + else + ternarySearch(mid1 + 1, mid2 - 1, key, ar) + end + end +end +n= gets.to_i #length of array +arr = [] +while n>0 + num = gets.chomp.to_i + arr.push(num) + n = n-1 +end +number = gets.to_i #number whose index is to be searched +puts "Index of #{number} is #{ternarySearch(0, arr.length - 1, number, arr)}" + +=begin +input-> +5 +21 +34 +54 +67 +78 +67 +output-> +Index of 67 is 3 +=end diff --git a/Topological_Sort/Topological_Sort.dart b/Topological_Sort/Topological_Sort.dart new file mode 100644 index 000000000..88d35a0b7 --- /dev/null +++ b/Topological_Sort/Topological_Sort.dart @@ -0,0 +1,181 @@ +/** + * Topological Sort implementation in Dart + * ------------------------------------------------------- + * + * In a directed acyclic graph, if there is an edge from u to v. Then, u comes before v. + * This observation has many real life application like scheduling tasks, ordering things etc.,. + * + * Topological sorting for Directed Acyclic Graph (DAG) is a linear ordering of vertices such that + * for every directed edge uv, vertex u comes before v in the ordering. + * + * Topological sorting is an application of Depth First Search. + * + */ + + +// Importing required libraries +import 'dart:io'; +import 'dart:core'; + +// Class for a graph +class Graph{ + + // Number of vertices in a graph. + int vertices; + + // Adjacency list to store the graph. + List< List< int > > adjlist; + + // Constructor + Graph(int v){ + + // Assigning number of vertices + this.vertices = v; + + // Initializing the graph + this.adjlist = new List< List< int > >(vertices); + + for (int i = 0 ; i < vertices ; i ++){ + + this.adjlist[i] = new List< int >(); + + } + + } + + // Method to add an edge + void add_edge(int source , int destination){ + + this.adjlist[source].add(destination); + + } + + + // Utility method for Topological Sort + void topologicalSortUtil(int source , List< int > stack , List< bool > visited){ + + // Marking source vertex visited + visited[source] = true; + + int len = this.adjlist[source].length; + + // Recursively visiting it's neighbours + for (int i = 0 ; i < len ; i ++){ + + if (visited[adjlist[source][i]] == false){ + + // Recursive call + topologicalSortUtil(adjlist[source][i] , stack , visited); + + } + } + + // Adding to stack + stack.add(source); + + } + + // Method to find the topological sort + void topologicalSort(){ + + // Stack required to print the topological sort + List< int > stack = new List< int >(); + + // Initializing the visited list. + List< bool > visited = new List< bool >.generate(this.vertices , ( i ) => false); + + // Running the utility on all vertices to cover the entire graph. + for (int i = 0 ; i < this.vertices ; i ++){ + + if (visited[i] == false){ + + topologicalSortUtil(i , stack , visited); + + } + + } + + // Converting the elements in the stack into a string and printing them. + String s; + + List temp = new List< int >(); + + while ( ! stack.isEmpty ){ + + temp.add(stack.removeLast()); + + } + + s = temp.join(" "); + + // Printing the result + print(s); + + } + +} + +// Driver function of the program +void main(){ + + // Taking input of number of vertices + print("Enter number of vertices:"); + + var input = stdin.readLineSync(); + + int n = int.parse(input); + + Graph g = new Graph(n); + + // Taking input of number of edges + print("Enter number of edges:"); + + input = stdin.readLineSync(); + + int m = int.parse(input); + + // Taking input of edges + print("Enter edges for vertices in 0 - n range:"); + + for(int i = 0 ; i < m ; i ++){ + + input = stdin.readLineSync(); + + var lis = input.split(" "); + + List list1 = lis.map(int.parse).toList(); + + g.add_edge(list1[0] , list1[1]); + + } + + // Printing the result + print("Following is the topological sort of the input graph: "); + + g.topologicalSort(); + +} + +/* + + Sample Input + ---------------------- + Enter number of vertices: + 8 + Enter number of edges: + 7 + Enter edges for vertices in 0 - n range: + 0 1 + 0 4 + 1 7 + 1 2 + 2 3 + 4 5 + 5 6 + + Sample Output + ----------------------- + Following is the topological sort of the input graph: + 0 4 5 6 1 2 3 7 + +*/ diff --git a/Topological_Sort/Topological_Sort.js b/Topological_Sort/Topological_Sort.js new file mode 100644 index 000000000..b76dfcc1f --- /dev/null +++ b/Topological_Sort/Topological_Sort.js @@ -0,0 +1,92 @@ +// Program to implement Topological Sort +class Graph { + constructor(nodes) { + //2 class variables + this.nodes = nodes; // no of vertices + this.adj = new Array(nodes); // adjacency list + for (let i = 0; i < nodes; i++) { + this.adj[i] = new Array(); + } + this.stack = []; // a stack for storing the ending times of dfs + } + + showGraph = () => { + const { + nodes, + adj + } = this; // destructuring for clarity + + for (let i = 0; i < nodes; i++) { + // show graph in readable format + console.log(`Vertex ${i} is connected to verices `, adj[i]); + } + }; + + addEdge = (x, y) => { + const { + nodes, + adj + } = this; + // x is connected to y + adj[x].push(y); + }; + + topoSort = () => { + const { + nodes, + adj + } = this; + + let visited = new Array(nodes); // visited array + for (let i = 0; i < nodes; i++) visited[i] = false; + + for (let i = 0; i < nodes; i++) + if (!visited[i]) this.topoUtil(i, visited); + }; + + topoUtil = (start, visited) => { + // utility function of topoSort + const { + nodes, + adj + } = this; + + visited[start] = true; + + for (let x of adj[start]) { + if (!visited[x]) { + this.topoUtil(x, visited); + } + } + + this.stack.push(start); // push the node when we have completed it + }; +} + +// implement +let n = 6; // 6 vertices +let graph = new Graph(n); // initialise the graph + +// add edges +graph.addEdge(5, 2); +graph.addEdge(5, 0); +graph.addEdge(4, 0); +graph.addEdge(4, 1); +graph.addEdge(2, 3); +graph.addEdge(3, 1); + +console.log("The Graph is:"); +graph.showGraph(); + +graph.topoSort(); +console.log(`The Topological sort is `, graph.stack.reverse()); + +// Output: +// The Graph is: +// Vertex 0 is connected to verices [] +// Vertex 1 is connected to verices [] +// Vertex 2 is connected to verices [ 3 ] +// Vertex 3 is connected to verices [ 1 ] +// Vertex 4 is connected to verices [ 0, 1 ] +// Vertex 5 is connected to verices [ 2, 0 ] +// The topological sort is [ 5, 4, 2, 3, 1, 0 ] diff --git a/Tower_Of_Hanoi/Tower_Of_Hanoi.go b/Tower_Of_Hanoi/Tower_Of_Hanoi.go new file mode 100644 index 000000000..939013a59 --- /dev/null +++ b/Tower_Of_Hanoi/Tower_Of_Hanoi.go @@ -0,0 +1,36 @@ +// Tower of Hanoi problem using recursion + +package main +import "fmt" + +func TowerOfHanoi(n int, source byte, destination byte, auxillary byte) { + if (n == 1) { + fmt.Printf("Move disk 1 from rod %c to rod %c \n", source, destination) + return + } + TowerOfHanoi(n - 1, source, auxillary, destination) + fmt.Printf("Move disk %d from rod %c to rod %c \n", n, source, destination) + TowerOfHanoi(n - 1, auxillary, destination, source) +} + +func main() { + var n int + fmt.Print("Enter number of disks: ") + fmt.Scan(&n) + // n = Number of disks + + TowerOfHanoi(n, 'A', 'C', 'B') + // A, B and C are names of rods + // A is source rod, B is auxillary rod, C is destination rod +} + +/* +Enter number of disks: 3 +Move disk 1 from rod A to rod C +Move disk 2 from rod A to rod B +Move disk 1 from rod C to rod B +Move disk 3 from rod A to rod C +Move disk 1 from rod B to rod A +Move disk 2 from rod B to rod C +Move disk 1 from rod A to rod C +*/ diff --git a/Tower_Of_Hanoi/Tower_Of_Hanoi.kt b/Tower_Of_Hanoi/Tower_Of_Hanoi.kt new file mode 100644 index 000000000..cd1422331 --- /dev/null +++ b/Tower_Of_Hanoi/Tower_Of_Hanoi.kt @@ -0,0 +1,44 @@ +/* + This is the solution for tower of hanoi problem using recursion implemented in Kotlin + Tower of Hanoi is an application of recursion + In this our aim is to shift n disks from source tower(peg) to destination tower(peg) + We can use third tower as auxilary tower. In it's solution we first try to shift n-1 disks. + Minimum number of steps required for this are 2^n-1 where n is number of disks. +*/ +import java.util.Scanner + +fun main() { + + val reader = Scanner(System.`in`) + var n:Int = reader.nextInt() + solveHanoi(n, 'A', 'C', 'B') +} + +/* + n - Number of disks + src - Source pole + dest - Destination pole + aux - Auxiliary pole +*/ + +fun solveHanoi(n: Int,src: Char, dest: Char, aux: Char) +{ + if(n >= 1) + { + solveHanoi(n - 1, src, dest, aux) + println("Move disk $n from $src to $dest") + solveHanoi(n - 1, aux, dest, src) + } +} + +/* +Output: + for 3 disks + Move disk 1 from A to C + Move disk 2 from A to C + Move disk 1 from B to C + Move disk 3 from A to C + Move disk 1 from B to C + Move disk 2 from B to C + Move disk 1 from A to C +*/ diff --git a/Tower_Of_Hanoi/Tower_Of_Hanoi.php b/Tower_Of_Hanoi/Tower_Of_Hanoi.php new file mode 100644 index 000000000..4a28a5272 --- /dev/null +++ b/Tower_Of_Hanoi/Tower_Of_Hanoi.php @@ -0,0 +1,43 @@ +/* This is an implementation of Tower Of Hanoi problem in PHP. + We have considered 4 disks in this case. +*/ + + + +/* Sample Output + +Move disk 1 from rod A to rod B +Move disk 2 from rod A to rod C +Move disk 1 from rod B to rod C +Move disk 3 from rod A to rod B +Move disk 1 from rod C to rod A +Move disk 2 from rod C to rod B +Move disk 1 from rod A to rod B +Move disk 4 from rod A to rod C +Move disk 1 from rod B to rod C +Move disk 2 from rod B to rod A +Move disk 1 from rod C to rod A +Move disk 3 from rod B to rod C +Move disk 1 from rod A to rod B +Move disk 2 from rod A to rod C +Move disk 1 from rod B to rod C + +*/ diff --git a/Tower_Of_Hanoi/Tower_Of_Hanoi.rb b/Tower_Of_Hanoi/Tower_Of_Hanoi.rb new file mode 100644 index 000000000..1165b804c --- /dev/null +++ b/Tower_Of_Hanoi/Tower_Of_Hanoi.rb @@ -0,0 +1,37 @@ +## Tower Of Hanoi In Ruby + +## Recursive Function +def tower(disk, source, auxilary, destination) + if disk == 1 + puts "Disk #{disk} moves from #{source} to #{destination}" + return + end + + tower(disk - 1, source, destination, auxilary) + puts "Disk #{disk} moves from #{source} to #{destination}" + tower(disk - 1, auxilary, source, destination) + nil + +end + +## Taking User Input For Number Of disks +puts "Enter the number of disks: " +disk = gets.to_i +puts + +## Fucntion Call +tower(disk, 'source', 'auxiliary', 'destination') + +=begin + +Enter the number of disks: 3 + +Disk 1 moves from Source to Destination +Disk 2 moves from Source to Auxiliary +Disk 1 moves from Destination to Auxiliary +Disk 3 moves from Source to Destination +Disk 1 moves from Auxiliary to Source +Disk 2 moves from Auxiliary to Destination +Disk 1 moves from Source to Destination + +=end diff --git a/Tower_Of_Hanoi/Tower_Of_Hanoi.ts b/Tower_Of_Hanoi/Tower_Of_Hanoi.ts new file mode 100644 index 000000000..8aabec37d --- /dev/null +++ b/Tower_Of_Hanoi/Tower_Of_Hanoi.ts @@ -0,0 +1,118 @@ +function solveHanoi( + count: number, + from: string, + to: string, + other: string, + move: (from: string, to: string) => void +) +{ + if (count > 0) { + //shift plat "from" to "to" using "other" plate + solveHanoi(count - 1, from, other, to, move) + move(from, to) + //shift plat "other" to "from" using "to" plate + solveHanoi(count - 1, other, to, from, move) + } +} +/**/ +// Example: six discs +var moveCount = 0 +solveHanoi(6, "Left", "Right", "Middle", (from , to) => { + ++moveCount + console.log(moveCount + ": Move Disk from " + from + " to " + to + ".") +}) + +//output for 3 +/* +1: Move Disk from Left to Right. +2: Move Disk from Left to Middle. +3: Move Disk from Right to Middle. +4: Move Disk from Left to Right. +5: Move Disk from Middle to Left. +6: Move Disk from Middle to Right. +7: Move Disk from Left to Right. +*/ + +//output for 4 +/* +1: Move Disk from Left to Middle. +2: Move Disk from Left to Right. +3: Move Disk from Middle to Right. +4: Move Disk from Left to Middle. +5: Move Disk from Right to Left. +6: Move Disk from Right to Middle. +7: Move Disk from Left to Middle. +8: Move Disk from Left to Right. +9: Move Disk from Middle to Right. +10: Move Disk from Middle to Left. +11: Move Disk from Right to Left. +12: Move Disk from Middle to Right. +13: Move Disk from Left to Middle. +14: Move Disk from Left to Right. +15: Move Disk from Middle to Right. +*/ + +//output for 6 +/* +1: Move Disk from Left to Middle. +2: Move Disk from Left to Right. +3: Move Disk from Middle to Right. +4: Move Disk from Left to Middle. +5: Move Disk from Right to Left. +6: Move Disk from Right to Middle. +7: Move Disk from Left to Middle. +8: Move Disk from Left to Right. +9: Move Disk from Middle to Right. +10: Move Disk from Middle to Left. +11: Move Disk from Right to Left. +12: Move Disk from Middle to Right. +13: Move Disk from Left to Middle. +14: Move Disk from Left to Right. +15: Move Disk from Middle to Right. +16: Move Disk from Left to Middle. +17: Move Disk from Right to Left. +18: Move Disk from Right to Middle. +19: Move Disk from Left to Middle. +20: Move Disk from Right to Left. +21: Move Disk from Middle to Right. +22: Move Disk from Middle to Left. +23: Move Disk from Right to Left. +24: Move Disk from Right to Middle. +25: Move Disk from Left to Middle. +26: Move Disk from Left to Right. +27: Move Disk from Middle to Right. +28: Move Disk from Left to Middle. +29: Move Disk from Right to Left. +30: Move Disk from Right to Middle. +31: Move Disk from Left to Middle. +32: Move Disk from Left to Right. +33: Move Disk from Middle to Right. +34: Move Disk from Middle to Left. +35: Move Disk from Right to Left. +36: Move Disk from Middle to Right. +37: Move Disk from Left to Middle. +38: Move Disk from Left to Right. +39: Move Disk from Middle to Right. +40: Move Disk from Middle to Left. +41: Move Disk from Right to Left. +42: Move Disk from Right to Middle. +43: Move Disk from Left to Middle. +44: Move Disk from Right to Left. +45: Move Disk from Middle to Right. +46: Move Disk from Middle to Left. +47: Move Disk from Right to Left. +48: Move Disk from Middle to Right. +49: Move Disk from Left to Middle. +50: Move Disk from Left to Right. +51: Move Disk from Middle to Right. +52: Move Disk from Left to Middle. +53: Move Disk from Right to Left. +54: Move Disk from Right to Middle. +55: Move Disk from Left to Middle. +56: Move Disk from Left to Right. +57: Move Disk from Middle to Right. +58: Move Disk from Middle to Left. +59: Move Disk from Right to Left. +60: Move Disk from Middle to Right. +61: Move Disk from Left to Middle. +62: Move Disk from Left to Right.*/ diff --git a/Tower_Of_Hanoi/Tower_of_Hanoi.cs b/Tower_Of_Hanoi/Tower_of_Hanoi.cs new file mode 100644 index 000000000..8e190dfc0 --- /dev/null +++ b/Tower_Of_Hanoi/Tower_of_Hanoi.cs @@ -0,0 +1,93 @@ +/* +C# recursive program to solve +tower of hanoi puzzle */ +using System; + +class geek +{ + + // C# recursive function to solve Tower of Hanoi puzzle + static void towerOfHanoi(int n, char from_rod, char to_rod, char aux_rod) + { + if (n == 1) + { + Console.WriteLine("Move disk 1 from rod " + from_rod + " to rod " + to_rod); + return; + } + towerOfHanoi(n-1, from_rod, aux_rod, to_rod); + Console.WriteLine("Move disk " + n + " from rod "+ from_rod + " to rod " + to_rod); + towerOfHanoi(n-1, aux_rod, to_rod, from_rod); + } + + // Driver method + public static void Main() + { + // Number of disks + int n; + String val; + + //Input taken + val = Console.ReadLine(); + n = Convert.ToInt32(val); + + // A, B and C are names of rods + towerOfHanoi(n, 'A', 'C', 'B'); + } +} + +/* +Input for Test Case 1: +4 //n = 4 +Output for Test Case 1: +Move disk 1 from rod A to rod B +Move disk 2 from rod A to rod C +Move disk 1 from rod B to rod C +Move disk 3 from rod A to rod B +Move disk 1 from rod C to rod A +Move disk 2 from rod C to rod B +Move disk 1 from rod A to rod B +Move disk 4 from rod A to rod C +Move disk 1 from rod B to rod C +Move disk 2 from rod B to rod A +Move disk 1 from rod C to rod A +Move disk 3 from rod B to rod C +Move disk 1 from rod A to rod B +Move disk 2 from rod A to rod C +Move disk 1 from rod B to rod C +*/ +/* +Input for Test Case 2: +5 //n = 5 +Output for Test case 2: +Move disk 1 from rod A to rod C +Move disk 2 from rod A to rod B +Move disk 1 from rod C to rod B +Move disk 3 from rod A to rod C +Move disk 1 from rod B to rod A +Move disk 2 from rod B to rod C +Move disk 1 from rod A to rod C +Move disk 4 from rod A to rod B +Move disk 1 from rod C to rod B +Move disk 2 from rod C to rod A +Move disk 1 from rod B to rod A +Move disk 3 from rod C to rod B +Move disk 1 from rod A to rod C +Move disk 2 from rod A to rod B +Move disk 1 from rod C to rod B +Move disk 5 from rod A to rod C +Move disk 1 from rod B to rod A +Move disk 2 from rod B to rod C +Move disk 1 from rod A to rod C +Move disk 3 from rod B to rod A +Move disk 1 from rod C to rod B +Move disk 2 from rod C to rod A +Move disk 1 from rod B to rod A +Move disk 4 from rod B to rod C +Move disk 1 from rod A to rod C +Move disk 2 from rod A to rod B +Move disk 1 from rod C to rod B +Move disk 3 from rod A to rod C +Move disk 1 from rod B to rod A +Move disk 2 from rod B to rod C +Move disk 1 from rod A to rod C +*/ diff --git a/Tower_Of_Hanoi/Tower_of_Hanoi.dart b/Tower_Of_Hanoi/Tower_of_Hanoi.dart new file mode 100644 index 000000000..03a2085e1 --- /dev/null +++ b/Tower_Of_Hanoi/Tower_of_Hanoi.dart @@ -0,0 +1,49 @@ +/* Tower of Hanoi is a mathematical problem where we have three rods A, B and C and n +number of disks where n is taken from user in this code. +The goal of the problem is to transfer the entire stack of disks to another rod, +obeying the conditions as follows: +1) Only one disk can be moved at a time. +2) Each move consists of taking the top disk from one of the stacks and placing +it on top of another stack. +3) No disk can be placed on top of a smaller disk. */ + +import 'dart:io'; + +void tower (int disks, String beg, String aux, String end) +{ + if (disks == 1) + { + print ("\nMove disk 1 from $beg ---> $end \n") ; + return ; + } + tower (disks - 1, beg, end, aux) ; + print ("\nMove disk $disks from $beg ---> $end \n") ; + tower (disks - 1, aux, beg, end) ; + return ; +} + +main() +{ + print ("ENTER NUMBER OF DISCS :\n") ; + int disks = int.parse (stdin.readLineSync()) ; + tower (disks, "A", "B", "C") ; +} + +/*OUTPUT: +ENTER NUMBER OF DISCS: +4 +Move disk 1 from A ---> B +Move disk 2 from A ---> C +Move disk 1 from B ---> C +Move disk 3 from A ---> B +Move disk 1 from C ---> A +Move disk 2 from C ---> B +Move disk 1 from A ---> B +Move disk 4 from A ---> C +Move disk 1 from B ---> C +Move disk 2 from B ---> A +Move disk 1 from C ---> A +Move disk 3 from B ---> C +Move disk 1 from A ---> B +Move disk 2 from A ---> C +Move disk 1 from B ---> C */ diff --git a/Tree_Inorder_Traversal/Inorder_Traversal.kt b/Tree_Inorder_Traversal/Inorder_Traversal.kt new file mode 100644 index 000000000..5acd29580 --- /dev/null +++ b/Tree_Inorder_Traversal/Inorder_Traversal.kt @@ -0,0 +1,62 @@ +//Code for printing inorder traversal in kotlin + +class Node +{ + //Structure of Binary tree node + int num; + Node left, right; + public node(int num) + { + key = item; + left = right = null; + } +} + +class BinaryTree +{ + Node root; + BinaryTree() + { + root = null; + } + //function to print inorder traversal + fun printInorder(Node: node):void + { + if (node == null) + return; + printInorder(node.left); + //printing val of node + println(node.num); + printInorder(node.right); + } + + fun printInorder():void + { + printInorder(root); + } +} + + //Main function +fun main() +{ + BinaryTree tree = new BinaryTree(); + var read = Scanner(System.`in`) + println("Enter the size of Array:") + val arrSize = read.nextLine().toInt() + var arr = IntArray(arrSize) + println("Enter data of binary tree") + + for(i in 0 until arrSize) + { + arr[i] = read.nextLine().toInt() + tree.root = new Node(arr[i]); + } + + println("Inorder traversal of binary tree is"); + tree.printInorder();//function call +} + +/* +Input: 10 8 3 30 5 19 4 5 1 +Output:5 3 1 2 8 10 19 30 4 +*/ diff --git a/Tree_Inorder_Traversal/Tree_Inorder_Traversal.cs b/Tree_Inorder_Traversal/Tree_Inorder_Traversal.cs new file mode 100644 index 000000000..0ef48879e --- /dev/null +++ b/Tree_Inorder_Traversal/Tree_Inorder_Traversal.cs @@ -0,0 +1,173 @@ +/** + Tree Inorder Traversal In C# +*/ + +using System; + +// Node Class To Declare Nodes Of The Tree +class Node +{ + public int data; + public Node left; + public Node right; + + public void display() + { + Console.Write(" ["); + Console.Write(data); + Console.Write("] "); + } +} + +// Tree Class To Declare Binary Search Tree +class Tree +{ + public Node root; + + // Constructor + public Tree() + { + root = null; + } + + public Node ReturnRoot() + { + return root; + } + + // Function To Insert Node Into BST + public void Insert(int id) + { + Node newNode = new Node(); + newNode.data = id; + + if (root == null) + root = newNode; + else + { + Node current = root; + Node parent; + + while (true) + { + parent = current; + if (id < current.data) + { + current = current.left; + if (current == null) + { + parent.left = newNode; + return; + } + } + + else + { + current = current.right; + if (current == null) + { + parent.right = newNode; + return; + } + } + } + } + } + + // Inorder Traversal Function + public void Inorder(Node Root) + { + if (Root != null) + { + Inorder(Root.left); + Console.Write(Root.data + " "); + Inorder(Root.right); + } + } +} + +class InorderTreeProgram +{ + public static void Main(string[] args) + { + // Declaring the Object Of Tree Class + Tree BST = new Tree(); + Console.WriteLine("1. Insert Node"); + Console.WriteLine("2. Display InOrder Traversal"); + Console.WriteLine("3. Exit"); + + while(true) + { + Console.WriteLine("\nEnter your choice: "); + String choice = Console.ReadLine(); + int Choice = int.Parse(choice); + + switch(Choice) + { + case 1: + { + Console.WriteLine("Enter the value to insert node: "); + String val = Console.ReadLine(); + int data = int.Parse(val); + BST.Insert(data); + break; + } + + case 2: + { + Console.WriteLine("\nTree Inorder Traversal: "); + BST.Inorder(BST.ReturnRoot()); + Console.WriteLine(" "); + break; + } + + case 3: + { + Console.WriteLine("Exit"); + System.Environment.Exit(0); + break; + } + } + } + } +} + +/** + +1. Insert Node +2. Display InOrder Traversal +3. Exit + +Enter your choice: 1 +Enter the value to insert node: 30 + +Enter your choice: 1 +Enter the value to insert node: 35 + +Enter your choice: 1 +Enter the value to insert node: 57 + +Enter your choice: 1 +Enter the value to insert node: 15 + +Enter your choice: 1 +Enter the value to insert node: 63 + +Enter your choice: 1 +Enter the value to insert node: 49 + +Enter your choice: 1 +Enter the value to insert node: 77 + +Enter your choice: 1 +Enter the value to insert node: 98 + +Enter your choice: 2 + +Tree Inorder Traversal: +15 30 35 49 57 63 77 98 + +Enter your choice: 3 +Exit + +*/ diff --git a/Tree_Inorder_Traversal/Tree_Inorder_Traversal.js b/Tree_Inorder_Traversal/Tree_Inorder_Traversal.js new file mode 100644 index 000000000..37ea90ebd --- /dev/null +++ b/Tree_Inorder_Traversal/Tree_Inorder_Traversal.js @@ -0,0 +1,38 @@ +/* + * Program to traverse a tree in Inorder. + */ + +// Creates a Tree Node with input value +class Node { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + +// Function for In Order Tree Transversal +function InOrder(root) { + if (root) { + InOrder(root.left); + console.log(root.value); + InOrder(root.right); + } +} + +// Sample Input +var root = new Node(1); +root.left = new Node(2); +root.right = new Node(3); +root.left.left = new Node(4); +root.left.right = new Node(5); +root.right.left = new Node(6); +root.right.right = new Node(7); + +// Sample Output +console.log("In Order traversal of tree is:-"); +InOrder(root); + +/* Output +In Order traversal of tree is:- 4 2 5 1 6 3 7 + */ diff --git a/Tree_Inorder_Traversal/Tree_Inorder_Traversal.ts b/Tree_Inorder_Traversal/Tree_Inorder_Traversal.ts new file mode 100644 index 000000000..dbb6ab474 --- /dev/null +++ b/Tree_Inorder_Traversal/Tree_Inorder_Traversal.ts @@ -0,0 +1,57 @@ +export {} +// Node +interface node +{ + key: number; + parent?: node; + left?: node; + right?: node; +} + + +// Defining the nodes with their values and left right children +const node9: node = { key: 9, left: undefined, right: undefined }; +const node8: node = { key: 8, left: undefined, right: undefined }; +const node7: node = { key: 7, left: undefined, right: undefined }; +const node6: node = { key: 6, left: undefined, right: undefined }; +const node5: node = { key: 5, left: undefined, right: undefined }; +const node4: node = { key: 4, left: node8, right: node9 }; +const node3: node = { key: 3, left: node6, right: node7 }; +const node2: node = { key: 2, left: node4, right: node5 }; +const root: node = { key: 1, parent: undefined, left: node2, right: node3 }; + +// Construct a tree by assigning parents +function constructTree(): node +{ + root.parent = undefined; + node2.parent = root; + node3.parent = root; + node4.parent = node2; + node5.parent = node2; + node6.parent = node3; + node7.parent = node3; + node8.parent = node4; + node9.parent = node4; + + return root; + } + +function inOrderTraversal(node: node) : null + { + if (!node) + return; + inOrderTraversal(node.left); + console.log(node.key + " -> "); + inOrderTraversal(node.right); + } + + +constructTree(); +console.log("The inorder traversal of the binary tree is :"); +inOrderTraversal(root); + +/* +Output +The inorder traversal of the binary tree is : +8 -> 4 -> 9 -> 2 -> 5 -> 1 -> 6 -> 3 -> 7 +*/ \ No newline at end of file diff --git a/Tree_Levelorder_Traversal/Tree_Levelorder_Traversal.js b/Tree_Levelorder_Traversal/Tree_Levelorder_Traversal.js new file mode 100644 index 000000000..0d546041a --- /dev/null +++ b/Tree_Levelorder_Traversal/Tree_Levelorder_Traversal.js @@ -0,0 +1,59 @@ +/*Description - Level order traveral of a tree is a traversal in which all the nodes which are at same +level are explored and then we move to another level. It is implemented using a queue. The root node +is pushed into queue intially and loops run till queue is not empty. The node at front is poped out +and if child of that node exist then those are pushed into queue. +Implementing Level Order Traversal in graph is also called Breath First Search. +*/ + +// Creates a Tree Node with input value +class Node { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + +//Level Order Traversal +var traversal = function (root) { + if (root === null) return root; + if (root.left === null && root.right === null) { + console.log(root.value); + return root; + } + const queue = []; + queue.push(root); + while (queue.length > 0) { + const node = queue.splice(0, 1)[0]; + console.log(node.value); + if (node.left) queue.push(node.left); + if (node.right) queue.push(node.right); + } + return root; +}; + +// Sample Input +var root = new Node(1); +root.left = new Node(2); +root.right = new Node(3); +root.left.left = new Node(4); +root.left.right = new Node(5); +root.right.left = new Node(6); +root.right.right = new Node(7); + +// Sample Output +console.log("Level Order traversal of tree is:-"); +traversal(root); + +/* +* Output +* +* Level Order traversal of tree is +1 +2 +3 +4 +5 +6 +7 +*/ diff --git a/Tree_Levelorder_Traversal/Tree_Levelorder_Traversal.kt b/Tree_Levelorder_Traversal/Tree_Levelorder_Traversal.kt new file mode 100644 index 000000000..43ec8d992 --- /dev/null +++ b/Tree_Levelorder_Traversal/Tree_Levelorder_Traversal.kt @@ -0,0 +1,104 @@ +// Code for printing Level Order of Tree in Kotlin + +class Node +{ + //Structure of Binary tree node + int num; + Node left, right; + public Node(int num) + { + key = item; + left = right = null; + } +} + +class BinaryTree +{ + Node root; + BinaryTree() + { + root = null; + } + + //function to print level order traversal + fun printLevelOrder():void + { + int h = height(root); + int i; + // To Print nodes at each level + for (i = 1; i <= h; i++) + { + printGivenLevel(root, i); + } + + } + + //Function to calculate height of Tree + fun height(Node: root):void + { + if (root == null) + { + return 0; + } + else + { + // compute height of each subtree + int lheight = height(root.left); + int rheight = height(root.right); + // use the larger one + if (lheight > rheight) + { + return(lheight + 1); + } + else + { + return(rheight + 1); + } + } + } + + fun printGivenLevel(Node:root ,int: level):void + { + if (root == null) + { + return; + } + //Print data + if (level == 1) + { + println(root.data); + } + else if (level > 1) + { + printGivenLevel(root.left, level-1); + printGivenLevel(root.right, level-1); + } + } + + fun main() + { + BinaryTree tree = new BinaryTree(); + var read = Scanner(System.`in`) + println("Enter the size of Array:") + val arrSize = read.nextLine().toInt() + var arr = IntArray(arrSize) + println("Enter data of binary tree") + + for(i in 0 until arrSize) + { + arr[i] = read.nextLine().toInt() + tree.root = new Node(arr[i]); + } + + println("Level order traversal of binary tree is "); + tree.printLevelOrder(); + } +} + +/* +Input: +1 2 3 4 5 6 7 8 9 +Output: +Level order traversal of binary tree is +1 2 3 4 5 6 7 8 9 +*/ diff --git a/Tree_Postorder_Traversal/Tree_Postorder_Traversal.kt b/Tree_Postorder_Traversal/Tree_Postorder_Traversal.kt new file mode 100644 index 000000000..ad866b553 --- /dev/null +++ b/Tree_Postorder_Traversal/Tree_Postorder_Traversal.kt @@ -0,0 +1,59 @@ +import java.util.* + +class Node( + var key:Int, + var left:Node? = null, + var right:Node? = null +) +{ + fun postorderTraversal() + { + left?.postorderTraversal() + right?.postorderTraversal() + print("$key ") + } +} + +fun main() { + var read = Scanner(System.`in`) + println("Enter the size of Array:") + val arrSize = read.nextLine().toInt() + var arr = IntArray(arrSize) + val nodes = mutableListOf>() + println("Enter the array respresentaion of binary tree") + + for(i in 0 until arrSize) + { + arr[i] = read.nextLine().toInt() + nodes.add(Node(arr[i])) + } + + for(i in 0..arrSize - 2) + { + if ((i * 2) + 1 < arrSize && arr[(i * 2) + 1] != -1) + { + nodes[i].left = nodes[(i * 2) + 1] + } + + if ((i * 2) + 2 < arrSize && arr[(i * 2) + 2] != -1) + { + nodes[i].right = nodes[(i * 2) + 2] + } + } + print("Post Order traversal of tree is ") + nodes[0].postorderTraversal() +} + +/* +*Enter the size of Array: +*7 +*Enter the array respresentaion of binary tree +*1 +*2 +*3 +*4 +*5 +*6 +*-1 +*Post Order traversal of tree is 4 5 2 6 3 1 +*/ diff --git a/Tree_Postorder_Traversal/Tree_Postorder_Traversal.ts b/Tree_Postorder_Traversal/Tree_Postorder_Traversal.ts new file mode 100644 index 000000000..024a2a638 --- /dev/null +++ b/Tree_Postorder_Traversal/Tree_Postorder_Traversal.ts @@ -0,0 +1,73 @@ +//Tree Postorder Traversal in TypeScript + +export {} + +// Tree Nodes +interface treeNodes +{ + val: number; + parent?: treeNodes; + left?: treeNodes; + right?: treeNodes; +} + +// Defining the nodes with their values and left right children. If a value is not given it is undefined. +const node11: treeNodes = { val: 11 }; +const node10: treeNodes = { val: 10 }; +const node9: treeNodes = { val: 9 }; +const node8: treeNodes = { val: 8 }; +const node7: treeNodes = { val: 7 }; +const node6: treeNodes = { val: 6, left: node10, right: node11}; +const node5: treeNodes = { val: 5 }; +const node4: treeNodes = { val: 4, left: node8, right: node9 }; +const node3: treeNodes = { val: 3, left: node6, right: node7 }; +const node2: treeNodes = { val: 2, left: node4, right: node5 }; +const root: treeNodes = { val: 1, left: node2, right: node3 }; + +// Construct a tree by assigning parent +function constructBinaryTree(): treeNodes +{ + root.parent = undefined; + node2.parent = root; + node3.parent = root; + node4.parent = node2; + node5.parent = node2; + node6.parent = node3; + node7.parent = node3; + node8.parent = node4; + node9.parent = node4; + node10.parent = node6; + node11.parent = node6; + + return root; +} + +// Recursive Function to call itself on left child, then on right child and then print value of current node +function postOrderTraversal(currentNode: treeNodes) +{ + if (!currentNode) + return; + postOrderTraversal(currentNode.left); + postOrderTraversal(currentNode.right); + console.log(currentNode.val + " -> "); +} + +constructBinaryTree(); +console.log("The postorder traversal of the binary tree is :"); +postOrderTraversal(root); + +/* +Output: +The postorder traversal of the binary tree is : +8 -> +9 -> +4 -> +5 -> +2 -> +10 -> +11 -> +6 -> +7 -> +3 -> +1 -> +*/ diff --git a/Tree_Preorder_Traversal/Tree_Preorder_Traversal.dart b/Tree_Preorder_Traversal/Tree_Preorder_Traversal.dart new file mode 100644 index 000000000..81898f6cf --- /dev/null +++ b/Tree_Preorder_Traversal/Tree_Preorder_Traversal.dart @@ -0,0 +1,139 @@ +import 'dart:io'; + +// Class to define the node of a binary tree. +class Node { + + int value; + Node left; + Node right; + + Node(int value) { + + this.value = value; + this.left = null; + this.right = null; + + } + +} + +// Class to define a binary tree. +class Tree { + + // The tree's root. + Node root; + + // Constructor + Tree(Node root) { + this.root = root; + } + + // Insert method to build the tree using recursion. + Node insert(Node root, int val) { + + if (root != null){ + + // Inserting in the left side if value is less than root. + if (val < root.value) { + root.left = insert(root.left, val); + } + else { + // Inserting in the right side if value is greater than root. + if (val > root.value) { + root.right = insert(root.right, val); + } + // Informing user that the value is already present. + else{ + print("Value is already present in the tree."); + } + } + } + else{ + // Insertion + root = Node(val); + } + + return root; + + } + + // Utility method used to print the preorder traversal using recursion. + void preorder_utility(Node node) { + + if (node != null) { + print(node.value); + + // Recursion + preorder_utility(node.left); + preorder_utility(node.right); + } + + } + + // Method to print the preorder traversal of the binary tree. + void tree_preorder_traversal(){ + + print("The preorder traversal of the tree in the given input is follows:"); + preorder_utility(this.root); + + } + +} + +// Driver method of the program +void main(){ + + // Reading user input + print("Enter root of the tree:"); + var input = stdin.readLineSync(); + int root_val = int.parse(input); + + // Root node + Node root_node = Node(root_val); + + // Binary Tree + Tree tree = Tree(root_node); + + String choice = "y"; + + while (choice == "y") { + + print("Enter number to insert:"); + var input3 = stdin.readLineSync(); + int insert_val = int.parse(input3); + tree.insert(root_node, insert_val); + + print("Do you want to insert another number into the tree? (y/n)"); + var input2 = stdin.readLineSync(); + choice = input2; + + } + + /* Sample Input tree + 8 + / \ + 3 12 + / \ / \ + 2 6 9 15 + / \ + 5 7 + */ + + // Calling method to print preorder traversal of the tree. + tree.tree_preorder_traversal(); + + /* Sample Output + The preorder traversal of the tree in the given input is follows: + 8 + 3 + 2 + 6 + 5 + 7 + 12 + 9 + 15 + */ + +} + diff --git a/Tree_Preorder_Traversal/Tree_Preorder_Traversal.kt b/Tree_Preorder_Traversal/Tree_Preorder_Traversal.kt new file mode 100644 index 000000000..18bef0bd6 --- /dev/null +++ b/Tree_Preorder_Traversal/Tree_Preorder_Traversal.kt @@ -0,0 +1,50 @@ +import java.util.* +class Node( + var key:Int, + var left:Node? = null, + var right:Node? = null +) +{ + fun preorderTraversal() + { + print("$key ") + left?.preorderTraversal() + right?.preorderTraversal() + } +} + +fun main() { + var read = Scanner(System.`in`) + println("Enter the size of Array:") + val arrSize = read.nextLine().toInt() + var arr = IntArray(arrSize) + val nodes = mutableListOf>() + println("Enter the array respresentaion of binary tree") + for(i in 0 until arrSize) + { + arr[i] = read.nextLine().toInt() + nodes.add(Node(arr[i])) + } + for(i in 0..arrSize-2) + { + if((i*2)+1 R regardless). + +``` +int L = 0, R = 0; +for (int i = 1; i < n; i++) { + if (i > R) { + L = R = i; + while (R < n && s[R-L] == s[R]){ + R++; + z[i] = R-L; + R--; + } + } + else { + int k = i-L; + if (z[k] < R-i+1) { + z[i] = z[k]; + } + else { + L = i; + while (R < n && s[R-L] == s[R]){ + R++; + z[i] = R-L; R--; + } + } +} +``` +## Example: +S = “abc”, T = “abcdabaabc” +L = “abc$abcdabaabc” +Compute Z values. +Z[1] = 0, Z[2] = 0, Z[3] = 0, Z[4] = 3, Z[5] = 0, Z[6] = 0, Z[7] = 0, Z[8] = 2, Z[9] = 0, Z[10] = 1, Z[11] = 3, Z[12] = 0, Z[13] = 0 +Look at values of Z[4] and Z[11] +hence string S matches at index 4 (abc$abcdabaabc) and index 11 (abc$abcdabaabc) + +## Time Complexity +O(n) +The algorithm runs in O(n) time. Characters are never compared at positions less than , and every time a match is found, is increased by one, so there are at most n comparisons + +## Implementation + - [c code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Z_Algorithm/Z_Algorithm.c) + - [coffee code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Z_Algorithm/Z_Algorithm.coffee) + - [cpp code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Z_Algorithm/Z_Algorithm.cpp) + - [c# code] + - [go code] + - [java code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Z_Algorithm/Z_Algorithm.java) + - [javaScript code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Z_Algorithm/Z_Algorithm.js) + - [kotlin code] + - [python code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Z_Algorithm/Z_Algorithm.py) + - [ruby code](https://github.com/jainaman224/Algo_Ds_Notes/blob/master/Z_Algorithm/Z_Algorithm.rb) + - [dart code] diff --git a/Z_Algorithm/Z_Algorithm.cs b/Z_Algorithm/Z_Algorithm.cs new file mode 100644 index 000000000..8c04a5f49 --- /dev/null +++ b/Z_Algorithm/Z_Algorithm.cs @@ -0,0 +1,121 @@ +/* + Z Algorithm In C# + + This algorithm finds all occurrences + of a pattern in a text in linear time. +*/ + +using System; + +class PatternSearch +{ + + /* + This function prints all the occurences + of a pattern in a text using Z algorithm + */ + + public static void search(string text, string pattern) + { + // Creation of Concatenated String + string concat = pattern + "$" + text; + int l = concat.Length; + + // Construct a new temporary array + int[] temp = new int[l]; + + getTempArr(concat, temp); + + /* + Iterate through temp array to + find the matching condition + */ + + for (int i = 0; i < l; ++i) + { + /* + If matched region is equal to + pattern lentgh, pattern is found + */ + + if (temp[i] == pattern.Length) + { + Console.WriteLine("Pattern occurs at index: " + + (i - pattern.Length - 1)); + } + } + } + + // Fills temporary array for given string str + private static void getTempArr(string str, int[] temp) + { + int n = str.Length; + int L = 0, R = 0; + + for (int i = 1; i < n; ++i) + { + if (i > R) + { + L = R = i; + + while (R < n && str[R - L] == str[R]) + { + R++; + } + temp[i] = R - L; + R--; + } + + else + { + int k = i - L; + + if (temp[k] < R - i + 1) + { + temp[i] = temp[k]; + } + + else + { + L = i; + + while (R < n && str[R - L] == str[R]) + { + R++; + } + temp[i] = R - L; + R--; + } + } + } + } + + public static void Main(string[] args) + { + Console.WriteLine("Enter the String value: "); + String text = Console.ReadLine(); + + Console.WriteLine("Enter the Pattern to search: "); + String pattern = Console.ReadLine(); + Console.WriteLine(); + + search(text, pattern); + } +} + +/** + +Enter the String value: AABACAADAAABACHGGH +Enter the Pattern to search: AABA + +Pattern occurs at index: 0 +Pattern occurs at index: 9 + +--------------------------------------------------- + +Enter the String value: THIS IS A TEST CASE +Enter the Pattern to search: TEST + +Pattern occurs at index: 10 + +*/ diff --git a/Z_Algorithm/Z_Algorithm.js b/Z_Algorithm/Z_Algorithm.js new file mode 100644 index 000000000..351dca2a5 --- /dev/null +++ b/Z_Algorithm/Z_Algorithm.js @@ -0,0 +1,102 @@ +/* +Z algorithm is a linear time string matching algorithm which runs in complexity. +It is used to find all occurrence of a pattern in a string , which is common +string searching problem. +*/ + +const setZArray = combined => { + + // Initiate zArray and fill it with zeros. + const zArray = Array.from({ length: combined.length }, () => 0); + + // Z box boundaries. + let leftIndex = 0, rightIndex = 0, shift = 0; + + // Go through all characters of the zString. + for (let i = 1; i < combined.length; i += 1) { + + if (i > rightIndex) { + + leftIndex = i; + rightIndex = i; + + while ( + rightIndex < combined.length + && combined[rightIndex - leftIndex] === combined[rightIndex] + ) { + + // Expanding Z box right boundary. + rightIndex += 1; + } + + + zArray[i] = rightIndex - leftIndex; + rightIndex -= 1; + + } + + else { + + // Calculate corresponding Z box shift. + shift = i - leftIndex; + + // Check if the value that has been already calculated before + if (zArray[shift] < (rightIndex - i) + 1) { + + zArray[i] = zArray[shift]; + } + else { + + // shift left boundary of Z box to current position. + leftIndex = i; + + // And start comparing characters one by one as we normally do for the case + while ( + rightIndex < combined.length + && combined[rightIndex - leftIndex] === combined[rightIndex] + ) { + rightIndex += 1; + } + + zArray[i] = rightIndex - leftIndex; + + rightIndex -= 1; + } + } + } + + // Return generated zArray. + return zArray; +} + + +zAlgorithm = (text, word) => { + + const wordPositions = []; + + // Concatenate word and text. Word will be a prefix to a text. + const zString = `${word}$${text}`; + + // Generate Z-array for concatenated string. + const zArray = setZArray(zString); + + for (let i = 1; i < zArray.length; i += 1) { + if (zArray[i] === word.length) { + + const wordPosition = i - word.length - 1; + wordPositions.push(wordPosition); + } + } + + // Return the list of word positions. + return wordPositions; +} + + +// I/O and O/P Examples: + +// The postions are: [0,10,16] +console.log(zAlgorithm("omgawesomeomgsftomg", "omg")); + +// The positions are: [3,12] +console.log(zAlgorithm("ohelloworldello", "llo")); diff --git a/Z_Algorithm/Z_Algorithm.rs b/Z_Algorithm/Z_Algorithm.rs new file mode 100644 index 000000000..e20bf9792 --- /dev/null +++ b/Z_Algorithm/Z_Algorithm.rs @@ -0,0 +1,103 @@ +/* Problem Statement : Find all occurrences of + * a pattern in a string in linear time O(m+n) + * where m is the length of the pattern and n + * is the length of the string.*/ + +use std::io::{stdin, stdout, Write}; +use std::convert::TryInto; + +fn z_array(zstring: &Vec) -> Vec { + let z_length = zstring.len(); + let mut z_arr = vec![0u32; z_length]; + z_arr[0] = 1; + let mut index = 1; + let mut var_ind = 0; + let mut left = 0; let mut right = 0; + /* To form the z array, run two loops from the beg of the + * array, match the char at that index for the outer loop + * with the char at index in the inner loop. If they match, + * move both of the indices forward, calculate the max length + * til which they match. */ + while index < z_length { + + if index > right { + left = index; right = index; + + while right < z_length && + zstring[right - left] == zstring[right] { + right += 1; + } + z_arr[index] = (right - left).try_into().unwrap(); + right -= 1; + } + else { + var_ind = index - left; + + if z_arr[var_ind] < ((right - index + 1).try_into().unwrap()) { + z_arr[index] = z_arr[var_ind]; + } + else { + left = index; + while (right < z_length && + zstring[right - left] == zstring[right]) { + right += 1; + } + + z_arr[index] = (right - left).try_into().unwrap(); + right -= 1; + } + } + index += 1; + } + + z_arr +} + +fn search_the_pattern(strng :&str, pattern :&str) { + let strng: Vec = strng.chars().collect(); + let pattern: Vec = pattern.chars().collect(); + let mut z_string = Vec::with_capacity(strng.len() + pattern.len()); + let pattern_length = pattern.len(); + z_string.extend(pattern); + z_string.push('$'); + z_string.extend(strng); + let z_array = z_array(&z_string); + + // Go through the z array, if at any index value is equal to the + // length of the pattern, the pattern appears in the string. + for index in pattern_length + 1.. z_array.len() - 1 { + if z_array[index] as usize == pattern_length { + println!("Pattern found at index : {}", index - pattern_length - 1); + } + } + +} + +fn main() { + println!("Enter the string :"); + let mut strng = String::new(); + //let _ = stdout().flush(); + stdin().read_line(&mut strng).expect("Error in string input."); + let strng: String = strng.trim().parse().unwrap(); + let strng: &str = &*strng; + + let mut pattern = String::new(); // make a mutable string variable + println!("Enter the pattern :"); + stdin().read_line(&mut pattern).expect("Error in pattern input."); + let pattern: String = pattern.trim().parse().unwrap(); + let pattern: &str = &*pattern; + //let tokens:Vec<&str>= strng.split(",").collect(); + + // Call the driver function with the string and the pattern + search_the_pattern(strng, pattern); +} + +/* Example : + * Enter the string : +The thesis was defended there then. +Enter the pattern : +the +Pattern found at index : 4 +Pattern found at index : 24 +Pattern found at index : 30 +*/ diff --git a/palindromic_string/palindromic_string.c b/palindromic_string/palindromic_string.c new file mode 100644 index 000000000..1984bbde4 --- /dev/null +++ b/palindromic_string/palindromic_string.c @@ -0,0 +1,54 @@ +/* +C Programme to check palindromic string. +A Palindromic String is a sequence of characters which is +the same when read both forward and backward. +*/ + +#include +#include + +// Driver function +int main() +{ + char string1[20]; + int i, length; + bool flag = false; + + printf("Enter a string: "); + scanf("%s", string1); + + length = strlen(string1); + + for(i = 0; i < length/2; i++) + { + if(string1[i] != string1[length - i - 1]) + { + flag = true; + break; + } + } + + if (flag) + { + printf("%s is not a palindrome", string1); + } + else + { + printf("%s is a palindrome", string1); + } + return 0; +} + +/* +Input: +radar + +Output: +radar is a palindrome + +Input: +Enter a string: india + +Output: +india is not a palindrome +*/ diff --git a/palindromic_string/palindromic_string.cpp b/palindromic_string/palindromic_string.cpp new file mode 100644 index 000000000..11720adbe --- /dev/null +++ b/palindromic_string/palindromic_string.cpp @@ -0,0 +1,55 @@ +/* +C++ Programme to check palindromic string. +A Palindromic String is a sequence of characters which is +the same when read both forward and backward. +*/ + +#include +#include +using namespace std; + +// Driver function +int main() +{ + char string1[20]; + int i, length; + bool flag = false; + + cout << "Enter a string: "; + cin >> string1; + + length = strlen(string1); + + for(i = 0; i < length/2; i++) + { + if(string1[i] != string1[length - i - 1]) + { + flag = true; + break; + } + } + + if (flag) + { + cout << string1 << " is not a palindrome" << endl; + } + else + { + cout << string1 << " is a palindrome" << endl; + } + + return 0; +} + +/*Input: +radar + +Output: +radar is a palindrome + +Input: +Enter a string: india + +Output: +india is not a palindrome +*/ \ No newline at end of file