diff --git a/algorithms/cryptography/Hill_cipher.py b/algorithms/cryptography/Hill_cipher.py new file mode 100644 index 0000000..943c463 --- /dev/null +++ b/algorithms/cryptography/Hill_cipher.py @@ -0,0 +1,42 @@ +import numpy as np +s=list(input("Enter a string")) +c=[] +for i in range(len(s)): + c.append(ord(s[i])-65) + +arr= np.array(c) + +a1=np.transpose(arr) +print(a1) +a1= a1.reshape(3,1) +print(a1.shape) + + +#key input +print("Enter the key for the encryption") +R = int(input("rows:")) +C = int(input("columns:")) +matrix = [] +print("Enter the key:") + +for i in range(R): + a =[] + for j in range(C): + a.append(int(input())) + matrix.append(a) + +for i in range(R): + for j in range(C): + print(matrix[i][j], end = " ") +matrix = np.array(matrix) +print(matrix.shape) +print(matrix[1][1]) + +mul=np.matmul(matrix,a1) +mul = np.array(mul) +print(mul.shape) +print(mul) +for i in range(R): + mul[i]=mul[i]%26 + +print(mul) diff --git a/algorithms/cryptography/railfence_cipher.py b/algorithms/cryptography/railfence_cipher.py new file mode 100644 index 0000000..0cdf24a --- /dev/null +++ b/algorithms/cryptography/railfence_cipher.py @@ -0,0 +1,78 @@ +def railencrypt(st,k): + c = 0 + x = 0 + m =[[0] * (len(st)) for i in range(k)] + for r in range(len(st)): + m[c][r] = st[r] + if x == 0: + if c == (k-1): + x = 1 + c -= 1 + else: + c += 1 + else: + if c == 0: + x = 0 + c += 1 + else: + c -= 1 + + result = [] + for i in range(k): + for j in range(len(st)): + if m[i][j] != 0: + result.append(m[i][j]) + print("CipherText:","" . join(result)) + +def raildecrypt(st,k): + c , x = 0 , 0 + m =[[0] * (len(st)) for i in range(k)] + for r in range(len(st)): + m[c][r] = 1 + if x == 0: + if c == (k-1): + x = 1 + c -= 1 + else: + c += 1 + else: + if c == 0: + x = 0 + c += 1 + else: + c -= 1 + result = [] + c , x = 0 , 0 + for i in range(k): + for j in range(len(st)): + if m[i][j] == 1: + m[i][j] = st[x] + x += 1 + for r in range(len(st)): + if m[c][r] != 0: + result.append(m[c][r]) + if x == 0: + if c == (k-1): + x = 1 + c -= 1 + else: + c += 1 + else: + if c == 0: + x = 0 + c += 1 + else: + c -= 1 + print("PlainText:","" . join(result)) + +if __name__ == "__main__": + string = input("Enter the Message:") + string = string.upper() + key = int(input("Enter the Key:")) + n = int(input("1.Encryption\n2.Decryption\nInput Your choice:")) + if(n == 1): + railencrypt(string,key) + elif(n == 2): + raildecrypt(string,key) + else: + print("Error") diff --git a/algorithms/data-structures/binarySerach.py b/algorithms/data-structures/binarySerach.py new file mode 100644 index 0000000..4169aee --- /dev/null +++ b/algorithms/data-structures/binarySerach.py @@ -0,0 +1,25 @@ +def binSearch(a, x, low, high): + #Return True if target is found in indicated portion of a Python list. + #The search only considers the portion from data[low] to data[high] inclusive. + + if low > high: + return False # interval is empty; no match + else: + mid = (low + high) // 2 + if x == a[mid]: # found a match + return True + elif x < a[mid]: + # recur on the portion left of the middle + return binSearch(a, x, low, mid - 1) + else: + # recur on the portion right of the middle + return binSearch(a, x, mid + 1, high) +a = [5, 10, 15, 20, 25, 30, 40] +x = 20 +low = 0 +high = 6 +result = binSearch(a, x, low, high) +if result: + print("The value ", x, " Found") +else: + print("The value ", x, " Not found") diff --git a/algorithms/data-structures/stack/stack.py b/algorithms/data-structures/stack/stack.py new file mode 100644 index 0000000..6865245 --- /dev/null +++ b/algorithms/data-structures/stack/stack.py @@ -0,0 +1,30 @@ +''' + Created by Luiz Guerra + My github github.com/LuizGuerra +''' + +class Stack: + + def __init__ (.self): + head = null + count = 0 + + def append(.self, e): + n = Node(e) + if count == 0: + head = n + count += 1 + else: + n.next = head.next + head = n + + def pop(.self): + n = head + head = head.next + return n.element + + +class Node (e): + __init__ (.self, e): + next = null + element = e diff --git a/algorithms/data-structures/stacks/node.py b/algorithms/data-structures/stacks/node.py new file mode 100644 index 0000000..757368c --- /dev/null +++ b/algorithms/data-structures/stacks/node.py @@ -0,0 +1,30 @@ +class Node: + + def __init__(self,item,next=None): + self.item = item + self.next = next + + def __str__(self): + string = '[' + str(self.item) + ']' + next = self.next + + while next: + if next: + string += ' -> ' + str(next) + next = next.get_next() + + return string + + + def get_item(self): + return self.item + + def get_next(self): + return self.next + + def set_item(self,item): + self.item = item + + def set_next(self,next): + self.next = next + diff --git a/algorithms/data-structures/stacks/stack.py b/algorithms/data-structures/stacks/stack.py new file mode 100644 index 0000000..085e7b6 --- /dev/null +++ b/algorithms/data-structures/stacks/stack.py @@ -0,0 +1,56 @@ +from node import Node + +class Stack: + + def __init__(self): + self.head = None + + def __str__(self): + node = self.head + list = [] + while node: + list.append(node.get_item()) + node = node.get_next() + return str(list) + + def is_empty(self): + return not self.head + + def push(self, item): + if not self.head: + self.head = Node(item) + else: + self.head = Node(item,self.head) + + def pop(self): + if not self.head: + raise EmptyStackException('Cannot pop from a empty stack') + else: + item = self.head.get_item() + + if self.head.get_next(): + self.head = self.head.get_next() + + else: + self.head = None + + return item + + + def peek(self): + if not self.head: + raise EmptyStackException('Cannot peek from an empty stack') + else: + return self.head.get_item() + + def size(self): + count = 0 + node = self.head + while node: + count += 1 + node = node.get_next() + return count + + +class EmptyStackException(Exception): + pass \ No newline at end of file diff --git a/algorithms/data-structures/stacks/stacks.py b/algorithms/data-structures/stacks/stacks.py new file mode 100644 index 0000000..22d90bd --- /dev/null +++ b/algorithms/data-structures/stacks/stacks.py @@ -0,0 +1,17 @@ +myStack = [] + +myStack.append('a') +myStack.append('b') +myStack.append('c') + +myStack + + +myStack.pop() + +myStack.pop() + +myStack.pop() + + +myStack.pop() \ No newline at end of file diff --git a/algorithms/data-structures/stacks/test_node.py b/algorithms/data-structures/stacks/test_node.py new file mode 100644 index 0000000..7f57f83 --- /dev/null +++ b/algorithms/data-structures/stacks/test_node.py @@ -0,0 +1,29 @@ +import unittest +from node import Node + +class TestNode(unittest.TestCase): + + def setUp(self): + self.next_node = Node('item 2') + self.node = Node('item 1',self.next_node) + + def test_str(self): + self.assertEqual(str(self.node),'[item 1] -> [item 2]') + + def test_get_item(self): + self.assertEqual(self.node.get_item(),'item 1') + + def test_get_next(self): + self.assertIs(self.node.get_next(),self.next_node) + + def test_set_item(self): + self.node.set_item('another item') + self.assertEqual(self.node.get_item(),'another item') + + def test_set_next(self): + another_node = Node('another item') + self.node.set_next(another_node) + self.assertIs(self.node.get_next(),another_node) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/algorithms/data-structures/stacks/test_stack.py b/algorithms/data-structures/stacks/test_stack.py new file mode 100644 index 0000000..bcadbae --- /dev/null +++ b/algorithms/data-structures/stacks/test_stack.py @@ -0,0 +1,53 @@ +import unittest +from stack import Stack, EmptyStackException + +class TestStack(unittest.TestCase): + + def setUp(self): + self.stack = Stack() + + def test_is_empty(self): + self.assertTrue(self.stack.is_empty()) + + def test_str_and_push(self): + self.stack.push(6) + self.assertEqual(str(self.stack),"[6]") + + def test_push_three_elements(self): + self.stack.push(3) + self.stack.push(2) + self.stack.push(1) + self.assertEqual(str(self.stack),"[1, 2, 3]") + + def test_pop_exception(self): + with self.assertRaises(EmptyStackException): + self.stack.pop() + + def test_pop_with_one_element(self): + self.stack.push("Item") + self.assertEqual(self.stack.pop(),"Item") + self.assertTrue(self.stack.is_empty()) + + def test_pop_with_two_elements(self): + self.stack.push(2) + self.stack.push(1) + self.assertEqual(self.stack.pop(),1) + self.assertEqual(str(self.stack),'[2]') + + def test_peek_exception(self): + with self.assertRaises(EmptyStackException): + self.stack.peek() + + def test_peek(self): + self.stack.push(1) + self.assertEqual(self.stack.peek(),1) + + def test_size(self): + self.assertEqual(self.stack.size(),0) + self.stack.push(1) + self.stack.push(2) + self.stack.push(3) + self.assertEqual(self.stack.size(),3) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/algorithms/data-structures/trees/size_of_subtree.py b/algorithms/data-structures/trees/size_of_subtree.py new file mode 100644 index 0000000..eb594f0 --- /dev/null +++ b/algorithms/data-structures/trees/size_of_subtree.py @@ -0,0 +1,28 @@ +""" + This is an efficient algorithm to find the size of a subtree from every node in O(n) time. + The idea is to use one dfs and first calculate the size of subtree of children of a node recursively. + Then add the size of each subtree of its children to get the size of its subtree. +""" +from collections import defaultdict as dd + + +def dfs(source, parent): + # Initial size of root is 1 + size[source] = 1 + for child in graph[source]: + if child != parent: + # Recursively calculate size of subtree of children nodes + dfs(child, source) + # Adding size of each child's subtree. + size[source] += size[child] + + +size = dd(int) +graph = dd(set) +n = int(input()) +for i in range(n-1): + u, v = map(int, input().split()) + graph[u].add(v) + graph[v].add(u) +dfs(1, 0) +print(size) diff --git a/algorithms/data-structures/trie/trie.py b/algorithms/data-structures/trie/trie.py new file mode 100644 index 0000000..13f5568 --- /dev/null +++ b/algorithms/data-structures/trie/trie.py @@ -0,0 +1,40 @@ +class trienode: + def __init__(self,character): + self.character = character + self.nextnodes = {} + self.isEnd = False + self.dataNode = None + +class trie: # use case: username/password + def __init__(self): + self.start = trienode('') + def insert(self,id,value): # returns true on successful insertion (value == password) + temp = self.start + for nextChar in id: + temp.nextnodes[nextChar] = temp.nextnodes.get(nextChar,trienode(nextChar)) + temp = temp.nextnodes[nextChar] + if temp.isEnd == True: + print("ID already Exists!!") + return False + temp.isEnd =True + temp.dataNode = value + return True + def findNode(self,id): # returns false if node doesn't exist and true, node if it does + temp = self.start + for nextChar in id: + next = temp.nextnodes.get(nextChar,None) + if next is None: + return False,None + temp = next + if temp.isEnd == True: + return True,temp + else: + return False,None + +if __name__ == '__main__': + t = trie() + t.insert('test1',"dummy1") + t.insert('test2',"dummy2") + print(t.findNode('test')) # (false,None) + a,b = t.findNode('test1') + print(a,b.dataNode) # true,dummy1 \ No newline at end of file diff --git a/algorithms/divide-and-conquer/mergesort.py b/algorithms/divide-and-conquer/mergesort.py new file mode 100644 index 0000000..05e5a0b --- /dev/null +++ b/algorithms/divide-and-conquer/mergesort.py @@ -0,0 +1,26 @@ +def merge(left_subarray,right_subarray): + i,j = 0,0 + result = [] + + while i partialSum + array[i]: + partialSum = array[i] + fromIndex = i + else: + partialSum += array[i] + + if partialSum >= bestSum: + bestSum = partialSum + toIndex = i + + return { + "fromIndex" : fromIndex, + "toIndex" : toIndex, + "bestSum" : bestSum + } + +n = int(input("Enter the size of the array: ")) +print("Input the array") +array = map(int,raw_input().split()) + +kadane = Kadane(array) +print("Sum: %d From: %d To: %d" % (kadane['bestSum'], kadane['fromIndex'], kadane['toIndex'])) \ No newline at end of file diff --git a/algorithms/dynamic-programming/matrix_chain_multiplication.py b/algorithms/dynamic-programming/matrix_chain_multiplication.py new file mode 100644 index 0000000..f0c73a5 --- /dev/null +++ b/algorithms/dynamic-programming/matrix_chain_multiplication.py @@ -0,0 +1,39 @@ +# Python program to solve Matrix chain multiplication using Dynamic Programming +# MatrixChain returns the minimum number of scalar multiplications needed to +# Compute the product of the chain +import sys +# Matrix Ai has dimension p[i-1] x p[i] for i = 1..n +def MatrixChain(p, n): + # For simplicity of the program, one extra row and one + # extra column are allocated in m[][]. 0th row and 0th + # column of m[][] are not used + m = [[0 for x in range(n)] for x in range(n)] + + # m[i, j] = Minimum number of scalar multiplications needed + # to compute the matrix A[i]A[i + 1]...A[j] = A[i..j] where + # dimension of A[i] is p[i-1] x p[i] + + # cost is zero when multiplying one matrix. + for i in range(1, n): + m[i][i] = 0 + + # L is chain length. + for L in range(2, n): + for i in range(1, n-L + 1): + j = i + L-1 + m[i][j] = sys.maxsize # sys.maxsize is a very large integer value (Refer https://stackoverflow.com/questions/48138632/in-python-what-is-sys-maxsize for more details if intrested) + for k in range(i, j): + + # q = cost / scalar multiplications + q = m[i][k] + m[k + 1][j] + p[i-1]*p[k]*p[j] + if q < m[i][j]: + m[i][j] = q + + return m[1][n-1] + +# Program to test above function +arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +size = len(arr) + +print("Minimum number of multiplications is " + + str(MatrixChain(arr, size))) diff --git a/algorithms/graphs/Bron-Kerbosch.py b/algorithms/graphs/Bron-Kerbosch.py new file mode 100644 index 0000000..d802445 --- /dev/null +++ b/algorithms/graphs/Bron-Kerbosch.py @@ -0,0 +1,29 @@ +# dealing with a graph as list of lists +graph = [[0,1,0,0,1,0],[1,0,1,0,1,0],[0,1,0,1,0,0],[0,0,1,0,1,1],[1,1,0,1,0,0],[0,0,0,1,0,0]] + + +#function determines the neighbors of a given vertex +def N(vertex): + c = 0 + l = [] + for i in graph[vertex]: + if i is 1 : + l.append(c) + c+=1 + return l + +#the Bron-Kerbosch recursive algorithm +def bronk(r,p,x): + if len(p) == 0 and len(x) == 0: # when no more possible neighbors are found, the max clique is printed + print(r) + return + for vertex in p[:]: # iterates through all possible neigbors + r_new = r[::] + r_new.append(vertex) + p_new = [val for val in p if val in N(vertex)] # p intersects N(vertex) + x_new = [val for val in x if val in N(vertex)] # x intersects N(vertex) + bronk(r_new,p_new,x_new) # recursiv call with new r, p and x + p.remove(vertex) + x.append(vertex) + +bronk([], [0,1,2,3,4,5], []) \ No newline at end of file diff --git a/algorithms/linkedlist/find_length_linkedList.py b/algorithms/linkedlist/find_length_linkedList.py new file mode 100644 index 0000000..7fe4cf7 --- /dev/null +++ b/algorithms/linkedlist/find_length_linkedList.py @@ -0,0 +1,56 @@ +# A complete working Python program to find length of a +# Linked List iteratively + +# Node class +class Node: + # Function to initialise the node object + def __init__(self, data): + self.data = data # Assign data + self.next = None # Initialize next as null + + +# Linked List class contains a Node object +class LinkedList: + + # Function to initialize head + def __init__(self): + self.head = None + + + # This function is in LinkedList class. It inserts + # a new node at the beginning of Linked List. + def push(self, new_data): + + # 1 & 2: Allocate the Node & + # Put in the data + new_node = Node(new_data) + + # 3. Make next of new Node as head + new_node.next = self.head + + # 4. Move the head to point to new Node + self.head = new_node + + + # This function counts number of nodes in Linked List + # iteratively, given 'node' as starting node. + def getCount(self): + temp = self.head # Initialise temp + count = 0 # Initialise count + + # Loop while end of linked list is not reached + while (temp): + count += 1 + temp = temp.next + return count + + +# Code execution starts here +if __name__=='__main__': + llist = LinkedList() + llist.push(1) + llist.push(3) + llist.push(1) + llist.push(2) + llist.push(1) + print ("Count of nodes is :",llist.getCount()) diff --git a/algorithms/linkedlist/middle_of_linkedlist.py b/algorithms/linkedlist/middle_of_linkedlist.py new file mode 100644 index 0000000..c0d55df --- /dev/null +++ b/algorithms/linkedlist/middle_of_linkedlist.py @@ -0,0 +1,56 @@ +class Node: + def __init__(self,data): + self.data = data + self.next = None + +class LinkedList: + def __init__(self): + self.head = None + self.tail = None + self.count = 0 + + def isEmpty(self): + if self.count == 0: + return True + return False + + def add_node(self,data): + new = Node(data) + + if self.isEmpty(): + self.head = new + self.tail = new + self.count += 1 + else: + new.next = self.head + self.head = new + self.count += 1 + + def show(self): + list = '' + ptr = self.head + while ptr: + print ptr.data + print ' -> ' + ptr = ptr.next + print list + + def middle(self): + fast = self.head + slow = self.head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + print slow.data + + +def main(): + L = LinkedList() + L.add_node(2) + L.add_node(32) + L.add_node(21) + L.add_node(67) + L.add_node(89) + L.middle() +if __name__ == '__main__': + main() diff --git a/algorithms/linkedlist/reverse_linkedlist.py b/algorithms/linkedlist/reverse_linkedlist.py new file mode 100644 index 0000000..c5b75de --- /dev/null +++ b/algorithms/linkedlist/reverse_linkedlist.py @@ -0,0 +1,64 @@ +# Recursively reverse a linked list + +class Node: + def __init__(self,data): + self.data = data + self.next = None + +class LinkedList: + def __init__(self): + self.head = None + self.tail = None + self.count = 0 + + def isEmpty(self): + if self.count == 0: + return True + return False + + def addnode(self,data): + new = Node(data) + if self.isEmpty(): + self.head = new + self.tail = new + self.count += 1 + else: + new.next = self.head + self.head = new + self.count += 1 + + def show(self): + list = '' + ptr = self.head + while ptr: + list += str(ptr.data) + list += '->' + ptr = ptr.next + print list + + def reverse(self,cur): + cur = cur + n = cur.next + + if n.next: + self.reverse(cur.next) + n.next = cur + cur.next = None + else: + n.next = cur + self.head = n + +def main(): + L = LinkedList() + L.addnode(89) + L.addnode(67) + L.addnode(21) + L.addnode(32) + L.addnode(2) + L.show() + L.reverse(L.head) + L.show() + + +if __name__ == '__main__': + main() diff --git a/algorithms/math/Fibonacci_Sequence.py b/algorithms/math/Fibonacci_Sequence.py new file mode 100644 index 0000000..507c766 --- /dev/null +++ b/algorithms/math/Fibonacci_Sequence.py @@ -0,0 +1,12 @@ +# Fibonacci Sequence + +if __name__ == '__main__': + f = [0, 1] + index1=0 + index2=1 + fibonacci_len = 10 # Lenght of Fibonacci Sequence + for n in range(fibonacci_len): + val = f[index1+n]+f[index2+n] + f.append(val) + f.pop(0) + print f diff --git a/algorithms/math/Sieve of Eratosthenes.py b/algorithms/math/Sieve of Eratosthenes.py new file mode 100644 index 0000000..d4b866d --- /dev/null +++ b/algorithms/math/Sieve of Eratosthenes.py @@ -0,0 +1,20 @@ +def SieveOfEratosthenes(n): + prime = [True for i in range(n+1)] + p = 2 + while (p * p <= n): + # If prime[p] is not changed, then it is a prime + if (prime[p] == True): + # Update all multiples of p + for i in range(p * p, n+1, p): + prime[i] = False + p += 1 + # Print all prime numbers + for p in range(2, n): + if prime[p]: + print (p), + # driver program +if __name__=='__main__': + n = 30 + print ("Following are the prime numbers smaller") + print ("than or equal to", n) + SieveOfEratosthenes(n) diff --git a/algorithms/math/SieveOfEratosthenes.py b/algorithms/math/SieveOfEratosthenes.py new file mode 100644 index 0000000..8fbb1ba --- /dev/null +++ b/algorithms/math/SieveOfEratosthenes.py @@ -0,0 +1,31 @@ +import math + + +def sieve(number): # taking a number as input and we'll find all prime values below it + primes = [0] * number + primes[0] = primes[1] = 1 # initialise 0 and 1 to not prime numbers + for prime in range(2, int(math.sqrt(len(primes)))): + if primes[prime] == 0: + for y in range(prime * 2, len(primes), prime): + primes[y] = 1 + else: + pass + + return primes + + +while True: # take input and reject any non integer inputs + try: + num = int(input("Type in a number: ")) + break + + except ValueError: + print("Type in an integer!") + +nums = sieve(num) + +for num in range(len(nums)): + if nums[num] == 0: + print(num) + else: + pass diff --git a/algorithms/math/SieveOfEratosthenes_PrimeNumbers.py b/algorithms/math/SieveOfEratosthenes_PrimeNumbers.py new file mode 100644 index 0000000..5285a72 --- /dev/null +++ b/algorithms/math/SieveOfEratosthenes_PrimeNumbers.py @@ -0,0 +1,22 @@ +#time complexity: O(n log(log n)) + +def Sieve(n): + prime = [True for i in range(n + 1)] + p = 2 + + #Here, we mark all the numbers that are not prime + while(p * p <= n): + if prime[p] == True: + for i in range(p * p, n + 1, p): + prime[i] = False + p += 1 + + #only the numbers that are unmarked, are prime. Hence, we print them + for p in range(2, n): + if prime[p]: + print(p, end = ' ') + +#driver code +n = int(input()) +print("All prime numbers till", n, "are: ") +Sieve(n) diff --git a/algorithms/math/armstrong_number.py b/algorithms/math/armstrong_number.py new file mode 100644 index 0000000..4a37b0a --- /dev/null +++ b/algorithms/math/armstrong_number.py @@ -0,0 +1,18 @@ +def armstrong(number): + l1=list(number) + Sum=0 + order=len(l1) + for i in l1: + Sum+=(int(i)**order) + + if Sum==int(number): + + print(number,"is an Armstrong number") + else: + + print(number,"is not an Armstrong number") + + + +number=input("Enter the number to check for Armstrong : ") +armstrong(number) \ No newline at end of file diff --git a/algorithms/math/common_divisor_count.py b/algorithms/math/common_divisor_count.py new file mode 100644 index 0000000..ef28f92 --- /dev/null +++ b/algorithms/math/common_divisor_count.py @@ -0,0 +1,31 @@ + + + +''' + +The function takes two integers as input and return the number of common divisors of +that pair + + + +''' +def cd_count(a,b): + + if a==0 or b==0: + return 2 + a=(-1*a if a<0 else a) + b=(-1*b if b<0 else b) + + result=0 + while a!=0: + c=a + a=b%a + b=c + + for i in range(1,int((b**0.5)+1)): + if b%i==0: + if b/i==i: + result=result+1 + else: + result=result+2 + return result diff --git a/algorithms/math/eulerTotient.py b/algorithms/math/eulerTotient.py new file mode 100644 index 0000000..bb9af68 --- /dev/null +++ b/algorithms/math/eulerTotient.py @@ -0,0 +1,24 @@ +from math import sqrt + +""" +this function calculate euler totien function +""" +def eulerTotienFunction(n): + if n == 1: + return 1 + result = 1 + temp = n + for i in range(2,int(sqrt(n))+10): + if (temp % i == 0): + j = 0 + while(temp % i == 0): + j += 1 + temp //= i + result = result * (i**(j-1)) * (i-1) + if temp == n: + return n-1 + return result + + + + diff --git a/algorithms/math/extendedEuclidean.py b/algorithms/math/extendedEuclidean.py new file mode 100644 index 0000000..f220a37 --- /dev/null +++ b/algorithms/math/extendedEuclidean.py @@ -0,0 +1,20 @@ +""" + for numbers a, b returns x, y such as x * a + y * b = gcd(a,b) +""" + +def extendedEuclidean(a,b): + a_old, b_old = a,b + a, b = max(a, b), min(a, b) + x, y, old_x, old_y = 0, 1, 1, 0 + while b != 0: + quotient = a // b + residue = a % b + a, b = b, residue + x, old_x = old_x, (old_x - quotient * x) + y, old_y = old_y, (old_y - quotient * y) + if a_old > b_old: + return x, y + return y, x + + + diff --git a/algorithms/math/factorial.py b/algorithms/math/factorial.py new file mode 100644 index 0000000..ac732ea --- /dev/null +++ b/algorithms/math/factorial.py @@ -0,0 +1,21 @@ +''' +To find factorial of a number +''' +def factorial(num): #recursive function + if num==1 or num==0: + return 1 + else: + return factorial(num-1)*num #function calling itself + +num=int(input("Enter the number to find factorial:")) +''' +To check whether the number inputted is positive or not +''' +while num<0: + print("INVALID INPUT !") + num=int(input("Enter the number to find factorial:")) +''' +function calling +''' +x=factorial(num) +print("Factorial of ",num," is ",x) \ No newline at end of file diff --git a/algorithms/math/fibonacci-recursive.py b/algorithms/math/fibonacci-recursive.py new file mode 100644 index 0000000..51b27a9 --- /dev/null +++ b/algorithms/math/fibonacci-recursive.py @@ -0,0 +1,13 @@ +def fibonacciUn(n,Un_2=None,Un_1=None): + if(n<1): + return Un_2 or n + if (n==1): + return Un_1 or n + return fibonacciUn(n-1,Un_2,Un_1) + fibonacciUn (n-2,Un_2,Un_1) +# Test + +print("The first item of the sequence is:") +print(fibonacciUn(1,10,15)) + +print("The tweleth item of the sequence is:") +print(fibonacciUn(12)) \ No newline at end of file diff --git a/algorithms/math/fibonacci.py b/algorithms/math/fibonacci.py new file mode 100644 index 0000000..4420883 --- /dev/null +++ b/algorithms/math/fibonacci.py @@ -0,0 +1,11 @@ +def fibonacciUn(Un_2,Un_1,n): + if(n<1): + return Un_2 + if (n==1): + return Un_1 + for i in range(n): + fib=Un_1+Un_2 + Un_2=Un_1 + Un_1=fib + return Un_1 +print(fibonacciUn(10,15,2)) \ No newline at end of file diff --git a/algorithms/math/gaussfilter.py b/algorithms/math/gaussfilter.py new file mode 100644 index 0000000..724a5e8 --- /dev/null +++ b/algorithms/math/gaussfilter.py @@ -0,0 +1,35 @@ +import math + + +def gaussfilt(xdata, ydata, sigma, xfilt=None, M=None, extrap=None): + if xfilt is None: + xfilt = xdata + if M is None: + M = 3 * sigma + if extrap is None: + extrap = 0 + yfilt = [0] * len(xfilt) + for i in range(0, len(xfilt), 1): + indices = [k for k, x in enumerate(xdata) if x > (xfilt[i] - M) and x < (xfilt[i] + M)] + if indices: + x = [] + for ind in indices: + x.append(xdata[ind] - xfilt[i]) + gaussfactors = gausskernel(x, sigma) + y = [] + yd = [] + for ind in indices: + yd.append(ydata[ind]) + for j in range(0, len(gaussfactors), 1): + y.append(gaussfactors[j] * yd[j]) + yfilt[i] = sum(y) / sum(gaussfactors) + if not indices: + yfilt[i] = extrap + return yfilt + + +def gausskernel(x, sigma): + res = [] + for element in x: + res.append(1 / (sigma * math.sqrt(2 * math.pi)) * math.exp(-0.5 * pow((element / sigma), 2))) + return res diff --git a/algorithms/math/gcd.py b/algorithms/math/gcd.py new file mode 100644 index 0000000..5eb748b --- /dev/null +++ b/algorithms/math/gcd.py @@ -0,0 +1,10 @@ +def gcd(A, B): + if B>A: + A, B = B, A + while B!=0: + temp = B + B = A%B + A = temp + return A + +print(gcd(10,20)) diff --git a/algorithms/math/recursive_greatest_common_divisor.py b/algorithms/math/recursive_greatest_common_divisor.py new file mode 100644 index 0000000..5983355 --- /dev/null +++ b/algorithms/math/recursive_greatest_common_divisor.py @@ -0,0 +1,26 @@ +""" +In mathematics, the greatest common divisor (gcd) of two or more integers, +which are not all zero, is the largest positive integer that divides each of the integers. +For example, the gcd of 8 and 12 is 4. +ยป https://en.wikipedia.org/wiki/Greatest_common_divisor + +Due to limited recursion depth this algorithm is not suited for calculating the GCD of big integers. +""" + +def recGCD(x, y, div = 0): + # Detemine which integer is greater and set the divisor accordingly + if div == 0: + if x > y: + div = x + else: + div = y + # If both integers can be divided without a remainder the gcd has been found + if x % div == 0 and y % div == 0: + return div + # Decrease divisor by one and try again + else: + return recGCD(x, y, div-1) + +x = int(input("x = ")) +y = int(input("y = ")) +print(f"gcd({x}, {y}) = {recGCD(x,y)}") diff --git a/algorithms/recursion/Coin-Change-Problem.py b/algorithms/recursion/Coin-Change-Problem.py new file mode 100644 index 0000000..c88529f --- /dev/null +++ b/algorithms/recursion/Coin-Change-Problem.py @@ -0,0 +1,11 @@ +def coin_change(v,items): + ans = 99 + if v <= 0: + return 0; + for item in items: + if v - item >= 0: + update = 1 + coin_change(v - item, items) + ans = min(ans, update); + return ans; + +print(coin_change(4, [1,2,3,5])) \ No newline at end of file diff --git a/algorithms/recursion/Factorial By Recursion Python.py b/algorithms/recursion/Factorial By Recursion Python.py new file mode 100644 index 0000000..25ec0d6 --- /dev/null +++ b/algorithms/recursion/Factorial By Recursion Python.py @@ -0,0 +1,11 @@ +#FINDING FACTORIAL THROUGH RECURSION +def recursion(n): + if(n==0): + return 1 + else: + return n*recursion(n-1) +a=int(input("Enter The Number You Want The Factorial Of")) #Asking User The Number for the factorial +if(a>=0): # Checking if the Number is positive or not + print(recursion()) +else: + print("Enter Valid Positive Number") diff --git a/algorithms/recursion/Fibonacci-Series-by-python.py b/algorithms/recursion/Fibonacci-Series-by-python.py new file mode 100644 index 0000000..33bf3a3 --- /dev/null +++ b/algorithms/recursion/Fibonacci-Series-by-python.py @@ -0,0 +1,13 @@ + +### Program to calculate fibonacci series + +def fibo(n): // function to calculate fibonacci series + if(n == 0): + return 0 + elif(n == 1): + return 1 + else: + return(fibo(n-1) + fibo(n-2)) +num = int(input("Enter a number: ")) // enter number upto which you want to calculate fibonacci series +for n in range(0,(num+1)): + print(fibo(n),end=" ") diff --git a/algorithms/recursion/exponentiation.py b/algorithms/recursion/exponentiation.py new file mode 100644 index 0000000..5709894 --- /dev/null +++ b/algorithms/recursion/exponentiation.py @@ -0,0 +1,21 @@ + +def exponentiation(baseNumber, power): + answer = None + + if power > 1: + halfAnswer = exponentiation(baseNumber, power//2) + answer = halfAnswer * halfAnswer + + if power%2 == 1: + answer *= baseNumber + + elif power == 1: + answer = baseNumber + + elif power == 0: + answer = 1 + + else: # negative power + answer = 1 / exponentiation(baseNumber, abs(power)) + + return answer diff --git a/algorithms/searches/exponential_search.py b/algorithms/searches/exponential_search.py new file mode 100644 index 0000000..9021089 --- /dev/null +++ b/algorithms/searches/exponential_search.py @@ -0,0 +1,7 @@ +def exponentialSearch(lys, val): + if lys[0] == val: + return 0 + index = 1 + while index < len(lys) and lys[index] <= val: + index = index * 2 + return BinarySearch( arr[:min(index, len(lys))], val) diff --git a/algorithms/searches/fibonacci_search.py b/algorithms/searches/fibonacci_search.py new file mode 100644 index 0000000..32be35d --- /dev/null +++ b/algorithms/searches/fibonacci_search.py @@ -0,0 +1,65 @@ +# Python3 program for Fibonacci search. +from bisect import bisect_left + +# Returns index of x if present, else +# returns -1 +def fibMonaccianSearch(arr, x, n): + + # Initialize fibonacci numbers + fibMMm2 = 0 # (m-2)'th Fibonacci No. + fibMMm1 = 1 # (m-1)'th Fibonacci No. + fibM = fibMMm2 + fibMMm1 # m'th Fibonacci + + # fibM is going to store the smallest + # Fibonacci Number greater than or equal to n + while (fibM < n): + fibMMm2 = fibMMm1 + fibMMm1 = fibM + fibM = fibMMm2 + fibMMm1 + + # Marks the eliminated range from front + offset = -1; + + # while there are elements to be inspected. + # Note that we compare arr[fibMm2] with x. + # When fibM becomes 1, fibMm2 becomes 0 + while (fibM > 1): + + # Check if fibMm2 is a valid location + i = min(offset+fibMMm2, n-1) + + # If x is greater than the value at + # index fibMm2, cut the subarray array + # from offset to i + if (arr[i] < x): + fibM = fibMMm1 + fibMMm1 = fibMMm2 + fibMMm2 = fibM - fibMMm1 + offset = i + + # If x is greater than the value at + # index fibMm2, cut the subarray + # after i+1 + elif (arr[i] > x): + fibM = fibMMm2 + fibMMm1 = fibMMm1 - fibMMm2 + fibMMm2 = fibM - fibMMm1 + + # element found. return index + else : + return i + + # comparing the last element with x */ + if(fibMMm1 and arr[offset+1] == x): + return offset+1; + + # element not found. return -1 + return -1 + +# Driver Code +arr = [10, 22, 35, 40, 45, 50, + 80, 82, 85, 90, 100] +n = len(arr) +x = 85 +print("Found at index:", + fibMonaccianSearch(arr, x, n)) diff --git a/algorithms/searches/jump_search.py b/algorithms/searches/jump_search.py new file mode 100644 index 0000000..b34efc6 --- /dev/null +++ b/algorithms/searches/jump_search.py @@ -0,0 +1,20 @@ +import math + +def jumoSearch (listA, theGoalValue): + length = len(listA) + jump = int(math.sqrt(length)) + left, right = 0, 0 + while length > left && theGoalValue >= listA[left]: + right = min(length - 1, left + jump) + if listA[left] <= theGoalValue and listA[right] >= theGoalValue: + break + left += jump; + if left >= length or listA[left] > theGoalValue: + return -1 + right = min(length - 1, right) + i = left + while i <= right and listA[i] <= theGoalValue: + if listA[i] == theGoalValue: + return i + i += 1 + return -1 diff --git a/algorithms/sorting/cocktail_sort.py b/algorithms/sorting/cocktail_sort.py new file mode 100644 index 0000000..71f7b38 --- /dev/null +++ b/algorithms/sorting/cocktail_sort.py @@ -0,0 +1,26 @@ +def cocktailSort(array) + n = len(array) + swap = 1 + begin = 0 + end = n-1 + #Sorting start + while (swap == 1): + swap = 0 + + #sorting from begin + for i in range (begin, end): + if (a[i] > a[i+1]) : + a[i], a[i+1]= a[i+1], a[i] + swap=1 + + if (swap==0): + break swap = 0 + + end = end-1 + #sorting from end + for i in range(end-1, begin-1,-1): + if (a[i] > a[i+1]): + a[i], a[i+1] = a[i+1], a[i] + swap = 1 + + begin = begin+1 \ No newline at end of file diff --git a/algorithms/sorting/shell_sort.py b/algorithms/sorting/shell_sort.py new file mode 100644 index 0000000..1269179 --- /dev/null +++ b/algorithms/sorting/shell_sort.py @@ -0,0 +1,35 @@ +"""This is a Python implementation of the shell sort algorithm + +Shell sort is a variation of insertion sort. This method starts by sorting +pairs of elements far away from each other, then progressively reducing the +gap between elements to be compared. + +""" +from random import randint + + +def shell_sort(arr): + + n = len(arr) + gap = n//2 + + while gap > 0: + for i in range(gap, n): + tmp = arr[i] + + j = i + while j >= gap and arr[j-gap] > tmp: + arr[j] = arr[j-gap] + j -= gap + arr[j] = tmp + + gap //= 2 + + return arr + + +# Tests +if __name__ == '__main__': + print(shell_sort([randint(0, 1000) for _ in range(10)])) + print(shell_sort([randint(-500, 500) for _ in range(10)])) + diff --git a/algorithms/sorting/tim_sort.py b/algorithms/sorting/tim_sort.py new file mode 100644 index 0000000..993c07e --- /dev/null +++ b/algorithms/sorting/tim_sort.py @@ -0,0 +1,90 @@ +from random import randint + + +class TimSort: + """ A class to demonstrate Tim Sort """ + + def __init__(self, array): + self.array = array + self.arrayLength = len(array) + self.__RUN = 32 + + def insertionSort(self, arr): + """ Sorts the given array from given starting index to ending index """ + + for i in range(1, len(arr)): + currentElement = arr[i] + j = i - 1 + while j >= 0 and arr[j] > currentElement: + arr[j + 1] = arr[j] + j -= 1 + arr[j + 1] = currentElement + + return arr + + def mergeRuns(self, arr1, arr2): + """ Merges the given two arrays: arr1 and arr2 """ + + newArray = list() + lengthOfArr1 = len(arr1) + lengthOfArr2 = len(arr2) + + # The variable i is used to keep track of the indices of the first array + # The variable j is used to keep track of the indices of the second array + # The variable k is used to keep track of the indices of the newArray array which is to be returned + i, j, k = 0, 0, 0 + + while i < lengthOfArr1 and j < lengthOfArr2: + if arr1[i] <= arr2[j]: + newArray[k] = arr1[i] + k += 1 + i += 1 + elif arr1[i] >= arr2[j]: + newArray[k] = arr2[j] + k += 1 + j += 1 + + # The below two loops will append any remaining elements left in any of the two arrays. + while i < lengthOfArr1: + newArray.append(arr1[i]) + i += 1 + + while j < lengthOfArr2: + newArray.append(arr2[j]) + j += 1 + + return newArray + + def changeRun(self, newRun): + self.__RUN = newRun + + def algorithm(self): + """ This function will perfom Tim Sort on the given array """ + + # Breaking the array into chunks of subarray(RUNS) of size RUN and perfomring insertionSort on them. + for i in range(0, self.arrayLength, self.__RUN): + currentRunElements = self.array[i: i + self.__RUN] + + self.array[i: i + + self.__RUN] = self.insertionSort(currentRunElements) + + temp_runner = self.__RUN + while temp_runner < self.arrayLength: + for idx in range(0, self.arrayLength, temp_runner * 2): + firstArray = self.array[idx: idx + temp_runner] + secondArray = self.array[idx + + temp_runner: idx + temp_runner * 2] + self.array[idx: idx + temp_runner * + 2] = self.mergeRuns(firstArray, secondArray) + temp_runner = self.__RUN * 2 + + print(f"The sorted array is : {self.array}") + + def __repr__(self): + return f"Array: {self.array}\nRUN: {self.__RUN}" + + +myArray = [randint(1, 100) for i in range(15)] +demo = TimSort(myArray) +print(demo) +demo.algorithm() diff --git a/algorithms/strings/change_case.py b/algorithms/strings/change_case.py new file mode 100644 index 0000000..17da182 --- /dev/null +++ b/algorithms/strings/change_case.py @@ -0,0 +1,12 @@ +# Simple function that converts uppercase characters to lowercase and vice versa. +# Author: jotslo + +def change_case(string): + # Iterates through string, if character is lowercase, convert to upper else lower + new_string = [char.upper() if char.islower() else char.lower() for char in string] + + # Joins list with an empty string to form the new string and return + return "".join(new_string) + +print(change_case("Hello, world!")) # hELLO, WORLD! +print(change_case("TEST")) # test diff --git a/algorithms/strings/levenstein.py b/algorithms/strings/levenstein.py new file mode 100644 index 0000000..66ad47d --- /dev/null +++ b/algorithms/strings/levenstein.py @@ -0,0 +1,9 @@ +def distance_levenstein(a, b): + f = [[(i+j) if i*j == 0 else 0 for j in range(len(b)+1)] for i in range(len(a) + 1)] + for i in range(1, len(a) + 1): + for j in range(1, len(b) + 1): + if a[i-1] == b[j-1]: + f[i][j] = f[i-1][j-1] + else: + f[i][j] = 1 + min(f[i-1][j], f[i][j-1], f[i-1][j-1]) + return f[len(a)][len(b)] diff --git a/algorithms/strings/word_length_dict.py b/algorithms/strings/word_length_dict.py new file mode 100644 index 0000000..673fb8d --- /dev/null +++ b/algorithms/strings/word_length_dict.py @@ -0,0 +1,10 @@ +""" + Determines the length of each word in a string and puts the word and its length in a dictionary +""" + +def word_length_dict(text): + d = {e: len(e) for e in text.split(" ")} + return d + +text = "The quick brown fox jumps over the lazy dog" +print(word_length_dict(text)) diff --git a/classification/fcm.py b/classification/fcm.py new file mode 100644 index 0000000..79a3ee9 --- /dev/null +++ b/classification/fcm.py @@ -0,0 +1,57 @@ +from tools import * + +# https://en.wikipedia.org/wiki/Fuzzy_clustering + + +class FuzzyCMeans: + def __init__(self, n_clusters, initial_centers, data, max_iter=250, m=2, error=1e-5): + assert m > 1 + #assert initial_centers.shape[0] == n_clusters + self.U = None + self.centers = initial_centers + self.max_iter = max_iter + self.m = m + self.error = error + self.data = data + + def membership(self, data, centers): + U_temp = cdist(data, centers, 'euclidean') + U_temp = numpy.power(U_temp, 2/(self.m - 1)) + denominator_ = U_temp.reshape( + (data.shape[0], 1, -1)).repeat(U_temp.shape[-1], axis=1) + denominator_ = U_temp[:, :, numpy.newaxis] / denominator_ + return 1 / denominator_.sum(2) + + def Centers(self, data, U): + um = U ** self.m + return (data.T @ um / numpy.sum(um, axis=0)).T + + def newImage(self, U, centers, im): + best = numpy.argmax(self.U, axis=-1) + # print(best) + # numpy.round() + image = im.astype(int) + for i in range(256): + image = numpy.where(image == float(i), centers[best[i]][0], image) + return image + + def compute(self): + self.U = self.membership(self.data, self.centers) + + past_U = numpy.copy(self.U) + begin_time = datetime.datetime.now() + for i in range(self.max_iter): + + self.centers = self.Centers(self.data, self.U) + self.U = self.membership(self.data, self.centers) + + if norm(self.U - past_U) < self.error: + break + past_U = numpy.copy(self.U) + x = datetime.datetime.now() - begin_time + return self.centers, self.U, x + +# that's how you run it, data being your data, and the other parameters being the basic FCM parameters such as numbe rof cluseters, degree of fuzziness and so on +# f = FuzzyCMeans(n_clusters=C, initial_centers=Initial_centers, +# data=data m=2, max_iter=1000, error=1e-5) +# centers, U, time = f.compute() diff --git a/classification/tools.py b/classification/tools.py new file mode 100644 index 0000000..682268a --- /dev/null +++ b/classification/tools.py @@ -0,0 +1,20 @@ +from matplotlib.image import imread +import matplotlib.pyplot as plt +from math import sqrt +import math +import random +import numpy +import operator +from scipy.spatial.distance import cdist +from scipy.linalg import norm +import datetime + + +def Histogram(path): + image = imread(path) + if len(image.shape) != 2: + def gray(rgb): return numpy.dot(rgb[..., :3], [0.2989, 0.5870, 0.1140]) + gray = gray(image) + image = gray + hist, bins = numpy.histogram(image.ravel(), 256, [0, 256]) + return adapt(hist) diff --git a/data-structures/Array Intersection.py b/data-structures/Array Intersection.py new file mode 100644 index 0000000..86545d5 --- /dev/null +++ b/data-structures/Array Intersection.py @@ -0,0 +1,14 @@ +### Here You can Use this Program For Finding Same elements in two Arrays. +def Array_Inter(arr1,n,arr2,m): ## Here I am Function + for i in range(n) : + for j in range(m) : + if arr1[i] == arr2[j] : + print(arr1[i], end = " ") + break +t=int(input("Test cases: ")) ## take test cases to be run +for k in range(t): + n=int(input("Size of Array One: ")) ## Size of array one by the user + arr1=[int(x) for x in input().split()] ## take inputs from user seperated by space + m=int(input("Size Of Array Two: ")) + arr2=[int(y) for y in input().split()] +Array_Inter(arr1,n,arr2,m) diff --git a/data-structures/InorderTreeTraversal.py b/data-structures/InorderTreeTraversal.py new file mode 100644 index 0000000..4929c7c --- /dev/null +++ b/data-structures/InorderTreeTraversal.py @@ -0,0 +1,50 @@ +class Node: + """A binary tree node""" + def __init__(self, data, left=None, right=None): + self.data = data + self.left = left + self.right = right + + +def morris_traversal(root): + """Generator function for iterative inorder tree traversal""" + + current = root + + while current is not None: + + if current.left is None: + yield current.data + current = current.right + else: + + # Find the inorder predecessor of current + pre = current.left + while pre.right is not None and pre.right is not current: + pre = pre.right + + if pre.right is None: + + # Make current as right child of its inorder predecessor + pre.right = current + current = current.left + + else: + # Revert the changes made in the 'if' part to restore the + # original tree. i.e., fix the right child of predecessor + pre.right = None + yield current.data + current = current.right + +# Driver program to test the above function + +root = Node(1, + right = Node(3), + left = Node(2, + left = Node(4), + right = Node(5) + ) + ) + +for v in morris_traversal(root): + print(v, end=' ') diff --git a/data-structures/binarySerach.py b/data-structures/binarySerach.py new file mode 100644 index 0000000..4169aee --- /dev/null +++ b/data-structures/binarySerach.py @@ -0,0 +1,25 @@ +def binSearch(a, x, low, high): + #Return True if target is found in indicated portion of a Python list. + #The search only considers the portion from data[low] to data[high] inclusive. + + if low > high: + return False # interval is empty; no match + else: + mid = (low + high) // 2 + if x == a[mid]: # found a match + return True + elif x < a[mid]: + # recur on the portion left of the middle + return binSearch(a, x, low, mid - 1) + else: + # recur on the portion right of the middle + return binSearch(a, x, mid + 1, high) +a = [5, 10, 15, 20, 25, 30, 40] +x = 20 +low = 0 +high = 6 +result = binSearch(a, x, low, high) +if result: + print("The value ", x, " Found") +else: + print("The value ", x, " Not found") diff --git a/data-structures/dequeue.py b/data-structures/dequeue.py new file mode 100644 index 0000000..884c698 --- /dev/null +++ b/data-structures/dequeue.py @@ -0,0 +1,48 @@ +class Dequeue: + def __init__(self): + self.items = [] + + def is_empty(self): + return self.items == [] + + def append(self, data): + self.items.append(data) + + def append_left(self, data): + self.items.insert(0, data) + + def pop(self): + return self.items.pop() + + def pop_left(self): + return self.items.pop(0) + + +q = Dequeue() +print('Menu') +print('append ') +print('appendleft ') +print('pop') +print('popleft') +print('quit') + +while True: + do = input('What would you like to do? ').split() + + operation = do[0].strip().lower() + if operation == 'append': + q.append(int(do[1])) + elif operation == 'appendleft': + q.append_left(int(do[1])) + elif operation == 'pop': + if q.is_empty(): + print('Dequeue is empty.') + else: + print('Popped value from right: ', q.pop()) + elif operation == 'popleft': + if q.is_empty(): + print('Dequeue is empty.') + else: + print('Popped value from left: ', q.pop_left()) + elif operation == 'quit': + break \ No newline at end of file diff --git a/data-structures/linked-lists/circulardoublylinkedlist.py b/data-structures/linked-lists/circulardoublylinkedlist.py new file mode 100644 index 0000000..eef2769 --- /dev/null +++ b/data-structures/linked-lists/circulardoublylinkedlist.py @@ -0,0 +1,109 @@ +class Node: + def __init__(self, data): + self.data = data + self.next = None + self.prev = None + + +class CircularDoublyLinkedList: + def __init__(self): + self.first = None + + def get_node(self, index): + current = self.first + for i in range(index): + current = current.next + if current == self.first: + return None + return current + + def insert_after(self, ref_node, new_node): + new_node.prev = ref_node + new_node.next = ref_node.next + new_node.next.prev = new_node + ref_node.next = new_node + + def insert_before(self, ref_node, new_node): + self.insert_after(ref_node.prev, new_node) + + def insert_at_end(self, new_node): + if self.first is None: + self.first = new_node + new_node.next = new_node + new_node.prev = new_node + else: + self.insert_after(self.first.prev, new_node) + + def insert_at_beg(self, new_node): + self.insert_at_end(new_node) + self.first = new_node + + def remove(self, node): + if self.first.next == self.first: + self.first = None + else: + node.prev.next = node.next + node.next.prev = node.prev + if self.first == node: + self.first = node.next + + def display(self): + if self.first is None: + return + current = self.first + while True: + print(current.data, end = ' ') + current = current.next + if current == self.first: + break + + +a_cdllist = CircularDoublyLinkedList() + +print('Menu') +print('insert after ') +print('insert before ') +print('insert at beg') +print('insert at end') +print('remove ') +print('quit') + +while True: + print('The list: ', end = '') + a_cdllist.display() + print() + do = input('What would you like to do? ').split() + + operation = do[0].strip().lower() + + if operation == 'insert': + data = int(do[1]) + position = do[3].strip().lower() + new_node = Node(data) + suboperation = do[2].strip().lower() + if suboperation == 'at': + if position == 'beg': + a_cdllist.insert_at_beg(new_node) + elif position == 'end': + a_cdllist.insert_at_end(new_node) + else: + index = int(position) + ref_node = a_cdllist.get_node(index) + if ref_node is None: + print('No such index.') + continue + if suboperation == 'after': + a_cdllist.insert_after(ref_node, new_node) + elif suboperation == 'before': + a_cdllist.insert_before(ref_node, new_node) + + elif operation == 'remove': + index = int(do[1]) + node = a_cdllist.get_node(index) + if node is None: + print('No such index.') + continue + a_cdllist.remove(node) + + elif operation == 'quit': + break \ No newline at end of file diff --git a/data-structures/linked-lists/circularsinglelinkedlist.py b/data-structures/linked-lists/circularsinglelinkedlist.py new file mode 100644 index 0000000..1ef3c6e --- /dev/null +++ b/data-structures/linked-lists/circularsinglelinkedlist.py @@ -0,0 +1,116 @@ +class Node: + def __init__(self, data): + self.data = data + self.next = None + + +class CircularLinkedList: + def __init__(self): + self.head = None + + def get_node(self, index): + if self.head is None: + return None + current = self.head + for i in range(index): + current = current.next + if current == self.head: + return None + return current + + def get_prev_node(self, ref_node): + if self.head is None: + return None + current = self.head + while current.next != ref_node: + current = current.next + return current + + def insert_after(self, ref_node, new_node): + new_node.next = ref_node.next + ref_node.next = new_node + + def insert_before(self, ref_node, new_node): + prev_node = self.get_prev_node(ref_node) + self.insert_after(prev_node, new_node) + + def insert_at_end(self, new_node): + if self.head is None: + self.head = new_node + new_node.next = new_node + else: + self.insert_before(self.head, new_node) + + def insert_at_beg(self, new_node): + self.insert_at_end(new_node) + self.head = new_node + + def remove(self, node): + if self.head.next == self.head: + self.head = None + else: + prev_node = self.get_prev_node(node) + prev_node.next = node.next + if self.head == node: + self.head = node.next + + def display(self): + if self.head is None: + return + current = self.head + while True: + print(current.data, end = ' ') + current = current.next + if current == self.head: + break + + +a_cllist = CircularLinkedList() + +print('Menu') +print('insert after ') +print('insert before ') +print('insert at beg') +print('insert at end') +print('remove ') +print('quit') + +while True: + print('The list: ', end = '') + a_cllist.display() + print() + do = input('What would you like to do? ').split() + + operation = do[0].strip().lower() + + if operation == 'insert': + data = int(do[1]) + position = do[3].strip().lower() + new_node = Node(data) + suboperation = do[2].strip().lower() + if suboperation == 'at': + if position == 'beg': + a_cllist.insert_at_beg(new_node) + elif position == 'end': + a_cllist.insert_at_end(new_node) + else: + index = int(position) + ref_node = a_cllist.get_node(index) + if ref_node is None: + print('No such index.') + continue + if suboperation == 'after': + a_cllist.insert_after(ref_node, new_node) + elif suboperation == 'before': + a_cllist.insert_before(ref_node, new_node) + + elif operation == 'remove': + index = int(do[1]) + node = a_cllist.get_node(index) + if node is None: + print('No such index.') + continue + a_cllist.remove(node) + + elif operation == 'quit': + break \ No newline at end of file diff --git a/data-structures/linked-lists/is_palindrome.py b/data-structures/linked-lists/is_palindrome.py new file mode 100644 index 0000000..22c93ce --- /dev/null +++ b/data-structures/linked-lists/is_palindrome.py @@ -0,0 +1,72 @@ +def is_palindrome(head): + if not head: + return True + fast, slow = head.next, head + while fast and fast.next: + fast = fast.next.next + slow = slow.next + second = slow.next + node = None + while second: + nxt = second.next + second.next = node + node = second + second = nxt + while node: + if node.val != head.val: + return False + node = node.next + head = head.next + return True + + +def is_palindrome_stack(head): + if not head or not head.next: + return True + + # Get the midpoint + slow = fast = cur = head + while fast and fast.next: + fast, slow = fast.next.next, slow.next + + # Push the second half into the stack + stack = [slow.val] + while slow.next: + slow = slow.next + stack.append(slow.val) + + # Comparison + while stack: + if stack.pop() != cur.val: + return False + cur = cur.next + + return True + + +def is_palindrome_dict(head): + if not head or not head.next: + return True + d = {} + pos = 0 + while head: + if head.val in d.keys(): + d[head.val].append(pos) + else: + d[head.val] = [pos] + head = head.next + pos += 1 + checksum = pos - 1 + middle = 0 + for v in d.values(): + if len(v) % 2 != 0: + middle += 1 + else: + step = 0 + for i in range(0, len(v)): + if v[i] + v[len(v) - 1 - step] != checksum: + return False + step += 1 + if middle > 1: + return False + return True diff --git a/data-structures/linked-lists/singleLinkedModule.py b/data-structures/linked-lists/singleLinkedModule.py new file mode 100644 index 0000000..bda9418 --- /dev/null +++ b/data-structures/linked-lists/singleLinkedModule.py @@ -0,0 +1,97 @@ +# The program that creates a single link list of true values +# and implements the actions outlined in the link list. + +class LinkedList: + class ListNode: + def __init__(self, data, next= None): + self.info = data + self.next = next + + def getInfo(self): + return self.info + + def setInfo(self, value): + self.info = value + + def getNext(self): + return self.next + + def setNext(self, ptr): + self.next = ptr #end of listNode class + + def __init__(self): + self.head = None + self.last = None + self.size = 0 + + def __del__(self): + current = self.head + while current: + ptr = current + current = current.next + del ptr + + def getSize(self): + return self.size + def isEmpty(self): + return self.head == None + +#Search Node + + def searchNode(self, data): + if (self.isEmpty()): + return None + else: + ptr = self.head + found = False + while ptr and found is False: + if ptr.getInfo() == data: + found == True + else: + ptr == ptr.getNext() + return ptr + + def insertAtFirst(self, ptr): + self.head = ptr + self.size += 1 + if self.getSize() == 1: + self.last = self.head + return True + + def insertAfterNode(self, ptr): + if (self.isEmpty()): + self.head = self.last = ptr + else: + self.last.next = ptr + self.last = ptr + self.size += 1 + + def deleteNode(self, data): + current = self.head + pre = None + found = False + while current and found is False: + if current.getInfo() == data: + found = True + else: + pre = current + current = current.getNext() + if found: + if current == self.head: #first Node deleted + self.head = current.next + del current + else: + pre.next = current.next + current.next = None + del current #current = None + self.size -= 1 + return found + + def traverse(self): + if (self.isEmpty() != True): + ptr = self.head + while ptr: + print(ptr.info, end = "\n") + ptr = ptr.getNext() + + diff --git a/data-structures/zigzagtraversal_iterative.py b/data-structures/zigzagtraversal_iterative.py new file mode 100644 index 0000000..fa485b3 --- /dev/null +++ b/data-structures/zigzagtraversal_iterative.py @@ -0,0 +1,75 @@ +class Node: + """ + A Node has data variable and pointers to its left and right nodes. + """ + + def __init__(self, data): + self.left = None + self.right = None + self.data = data + +def make_tree() -> Node: + root = Node(1) + root.left = Node(2) + root.right = Node(3) + root.left.left = Node(4) + root.left.right = Node(5) + return root + +def zigzag_iterative(root: Node): + """ + ZigZag traverse by iterative method: Print node left to right and right to left, alternatively. + """ + if root == None: + return + + # two stacks to store alternate levels + s1 = [] # For levels to be printed from right to left + s2 = [] # For levels to be printed from left to right + + # append first level to first stack 's1' + s1.append(root) + + # Keep printing while any of the stacks has some nodes + while not len(s1) == 0 or not len(s2) == 0: + + # Print nodes of current level from s1 and append nodes of next level to s2 + while not len(s1) == 0: + temp = s1[-1] + s1.pop() + print(temp.data, end = " ") + + # Note that is left is appended before right + if temp.left: + s2.append(temp.left) + if temp.right: + s2.append(temp.right) + + # Print nodes of current level from s2 and append nodes of next level to s1 + while not len(s2) == 0: + temp = s2[-1] + s2.pop() + print(temp.data, end = " ") + + # Note that is rightt is appended before left + if temp.right: + s1.append(temp.right) + if temp.left: + s1.append(temp.left) + +def main(): # Main function for testing. + """ + Create binary tree. + """ + root = make_tree() + print("\nZigzag order traversal(iterative) is: ") + zigzag_iterative(root) + print() + + +if __name__ == "__main__": + import doctest + + doctest.testmod() + main() +