From 039ff4a04718d459acb06b29ca74c73c0ab3ba3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=8E=9B=E2=8E=9D=20L=E2=88=86RBI=20=E2=8E=A0=E2=8E=9E?= <48409226+L4RBI@users.noreply.github.com> Date: Thu, 1 Oct 2020 02:08:07 +0100 Subject: [PATCH 1/5] added a classification algorithms folder --- classification/fcm.py | 57 +++++++++++++++++++++++++++++++++++++++++ classification/tools.py | 20 +++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 classification/fcm.py create mode 100644 classification/tools.py 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) From e743b42ab2405bfeb56b8ec242e480915262b7ca Mon Sep 17 00:00:00 2001 From: shivansh2310 Date: Mon, 5 Oct 2020 20:39:06 +0530 Subject: [PATCH 2/5] Added implementation of Hill_cipher In python --- algorithms/cryptography/Hill_cipher.py | 42 ++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 algorithms/cryptography/Hill_cipher.py 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) From 8aae48324555d20cfbb5d1b87c555b31484d2093 Mon Sep 17 00:00:00 2001 From: Sakshi Agrawal <66746828+SakshiiAgrawal@users.noreply.github.com> Date: Wed, 21 Oct 2020 22:17:16 +0530 Subject: [PATCH 3/5] zigzag traversal in a binary tree The idea is to use two stacks. We can use one stack for printing from left to right and other stack for printing from right to left. In every iteration, we have nodes of one level in one of the stacks. We print the nodes, and push nodes of next level in other stack. --- data-structures/zigzagtraversal_iterative.py | 75 ++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 data-structures/zigzagtraversal_iterative.py 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() + From dcbc0ea14a967941785d4e19a9b8962fbeee2920 Mon Sep 17 00:00:00 2001 From: shivansh kumar <42717219+shivansh2310@users.noreply.github.com> Date: Thu, 22 Oct 2020 00:29:23 +0530 Subject: [PATCH 4/5] Railfence Cipher implementation in cipher --- algorithms/cryptography/railfence_cipher.py | 78 +++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 algorithms/cryptography/railfence_cipher.py 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") From e08137879036d93042dc3ea7aa3a57bbf58728ca Mon Sep 17 00:00:00 2001 From: Hemanth Date: Mon, 2 Nov 2020 22:24:17 +0530 Subject: [PATCH 5/5] Add Tim Sort implementation --- algorithms/sorting/tim_sort.py | 90 ++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 algorithms/sorting/tim_sort.py 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()