├── README.md ├── modular_exponenation.py ├── variations_with_repetitions.py ├── shuffling.py ├── maximum_matching.py ├── longest_palindrome.py ├── extended_Euclicid.py ├── factorization_to_primes.py ├── pollard_rho.py ├── edit_distance.py ├── merge_sort.py ├── quick_sort.py ├── bin_search.py ├── erasthotenes_sieve.py ├── primarity_tests_one_fermat.py ├── Python-Algorithms ├── powersets_and_gray_code.py ├── miller_rabin_fermat_lucas_lehmer.py └── inv_index.py /README.md: -------------------------------------------------------------------------------- 1 | # Python-Algorithms 2 | # Repo to put tested and working various python algorithms 3 | -------------------------------------------------------------------------------- /modular_exponenation.py: -------------------------------------------------------------------------------- 1 | # modular exponenation https://en.wikipedia.org/wiki/Modular_exponentiation 2 | 3 | 4 | def modular_exponenation(base, exponent, modulus): 5 | if modulus == 1: 6 | return 0 7 | result = 1 8 | base = base % modulus 9 | while exponent > 0: 10 | if exponent % 2 == 1: 11 | result = (result * base) % modulus 12 | exponent >>= 1 13 | base = (base * base) % modulus 14 | return result 15 | -------------------------------------------------------------------------------- /variations_with_repetitions.py: -------------------------------------------------------------------------------- 1 | from itertools import product 2 | 3 | 4 | def variations_with_repetitions(data, count): 5 | """returns an iterator with variations with repetitions 6 | of data elements from a set with count number of elems""" 7 | for x in product(data, repeat=count): 8 | w = ''.join(x) 9 | yield (w) 10 | 11 | cnt = 0 12 | for i in variations_with_repetitions(['A', 'B', 'C', 'D'], 2): 13 | print(i) 14 | cnt += 1 15 | print("liczba = ", cnt) 16 | -------------------------------------------------------------------------------- /shuffling.py: -------------------------------------------------------------------------------- 1 | # algorithm for shuffling given subscriptable data structure (Knuth) 2 | 3 | import random 4 | 5 | 6 | def swap(alist, i, j): 7 | """swaps input lists i, j elements""" 8 | alist[i], alist[j] = alist[j], alist[i] 9 | 10 | 11 | def shuffle(data): 12 | """randomly shuffles element in the input data""" 13 | n = len(data) 14 | for token in range(n - 1): 15 | swap(data, token, random.randrange(token, n)) 16 | 17 | alist1 = [1, 3, 5, 6] 18 | print(alist1) 19 | shuffle(alist1) 20 | print(alist1) 21 | -------------------------------------------------------------------------------- /maximum_matching.py: -------------------------------------------------------------------------------- 1 | # Maximum matching, description here: https://lion137.blogspot.co.uk/2017/01/text-segmentation-maximum-matching-in.html 2 | 3 | def max_match(sentence, dictionary): 4 | if not sentence: 5 | return "" 6 | for i in range(len(sentence), -1, -1): 7 | first_word = sentence[:i] 8 | remainder = sentence[i:] 9 | if first_word in dictionary: 10 | return first_word + " " + max_match(remainder, dictionary) 11 | first_word = sentence[0] 12 | remainder = sentence[1:] 13 | return first_word + max_match(remainder, dictionary) 14 | -------------------------------------------------------------------------------- /longest_palindrome.py: -------------------------------------------------------------------------------- 1 | # searching the longest palindrome in a given string, returns tuple of indxes of a input string (start, end) 2 | 3 | 4 | def length(slice): a, b = slice; return b - a 5 | def grow(text, start, end): 6 | while(start > 0 and end < len(text) 7 | and text[start-1].upper() == text[end].upper()): 8 | start -= 1; end += 1 9 | return (start, end) 10 | def longest_palindrome(tex): 11 | if tex == '': return (0,0) 12 | cand = [grow(tex, start, end) 13 | for start in range(len(tex)) 14 | for end in (start,start + 1)] 15 | return max(cand, key=length) 16 | -------------------------------------------------------------------------------- /extended_Euclicid.py: -------------------------------------------------------------------------------- 1 | # Extended Euclicid https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm 2 | 3 | # Extended Euclicid Algorithm, returns gcd, and x, y in d = gcd(a, b) = ax + by 4 | # complexity: O(lg(b)) 5 | # 6 | # , and O(beta^3) bit operations (call it on 2 beta bits numbers) assuming that 7 | # mult and division is O(beta^2) 8 | 9 | def extended_euclicid(a, b): 10 | """ Extended Euclicid Algorithm, returns gcd, and x, y in d = gcd(a, b) = ax + by 11 | complexity: O(lg(b))""" 12 | if b == 0: 13 | return [a, 1, 0] 14 | else: 15 | [dn, xn, yn] = extendedeuclicid(b, a % b) 16 | [d, x, y] = [dn, yn, xn - (a // b) * yn] 17 | return [d, x, y] 18 | -------------------------------------------------------------------------------- /factorization_to_primes.py: -------------------------------------------------------------------------------- 1 | # Factorization algorithms 2 | 3 | # 1. Simple trial, having list of enough primes to factorize certain integer 4 | # Factorize by trial division over the list, we assume, that we have, a list of 5 | # primes generated, for example from Sieve of Erasthotenes. 6 | 7 | # Function factorize_trial 8 | 9 | from Euler import miller_rabin 10 | 11 | 12 | def factorize_trial(n, primes): 13 | """Factorizing n""" 14 | if miller_rabin(n): 15 | return n 16 | result = [] 17 | for p in primes: 18 | while n % p == 0: 19 | result.append(p) 20 | n //= p 21 | if miller_rabin(n): 22 | result.append(n) 23 | break 24 | return result 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /pollard_rho.py: -------------------------------------------------------------------------------- 1 | # pollard's rho algorithm to factorization https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm 2 | # https://lion137.blogspot.co.uk/2017/02/python-pollards-rho-algorithm.html 3 | 4 | 5 | from random import randint 6 | 7 | 8 | 9 | def gcd(a, b): 10 | if a < 0: 11 | a = -a 12 | if b < 0: 13 | b = -b 14 | if a == 0: 15 | return b 16 | while b != 0: 17 | a, b = b, a % b 18 | return a 19 | 20 | 21 | def pollard_rho(n): 22 | s = set() 23 | i = 0 24 | xi = randint(0, n-1) 25 | y = xi 26 | k = 2 27 | while i < 2 * n: 28 | i += 1 29 | xi = ((xi^2) - 1)%n 30 | d = gcd(y - xi, n) 31 | if d != 1 and d != n: 32 | s.add(d) 33 | if i == k: 34 | y = xi 35 | k *= 2 36 | return sorted(s) 37 | 38 | 39 | -------------------------------------------------------------------------------- /edit_distance.py: -------------------------------------------------------------------------------- 1 | # string edit distance algorithm description: 2 | # https://lion137.blogspot.co.uk/2017/01/algorithms-in-python.html 3 | 4 | 5 | st1 = "sunday euheu jodjodjsjdkeuamd" 6 | st2 = "saturdaydkwdwmmdwodqwrdhrtdkl" 7 | 8 | 9 | def edit_dist_dp(str1, str2, m, n): 10 | store = [[0 for x in range(n + 1)] for x in range(m + 1)] 11 | 12 | for i in range(m + 1): 13 | for j in range(n + 1): 14 | 15 | if i == 0: 16 | store[i][j] = j 17 | 18 | elif j == 0: 19 | store[i][j] = i 20 | 21 | elif str1[i - 1] == str2[j - 1]: 22 | store[i][j] = store[i - 1][j - 1] 23 | 24 | else: 25 | store[i][j] = 1 + min(store[i][j - 1], store[i - 1][j], 26 | store[i - 1][j - 1]) 27 | 28 | return store[m][n] 29 | 30 | 31 | print(edit_dist_dp(st1, st2, len(st1), len(st2))) 32 | # output: -> 22 33 | -------------------------------------------------------------------------------- /merge_sort.py: -------------------------------------------------------------------------------- 1 | # merge sort 2 | 3 | 4 | def merge_sort(alist): 5 | if len(alist) > 1: 6 | mid = len(alist) // 2 7 | lefthalf = alist[:mid] 8 | righthalf = alist[mid:] 9 | 10 | merge_sort(lefthalf) 11 | merge_sort(righthalf) 12 | 13 | i = 0 14 | j = 0 15 | k = 0 16 | while i < len(lefthalf) and j < len(righthalf): 17 | if lefthalf[i] < righthalf[j]: 18 | alist[k] = lefthalf[i] 19 | i += 1 20 | else: 21 | alist[k] = righthalf[j] 22 | j += 1 23 | k += 1 24 | while i < len(lefthalf): 25 | alist[k] = lefthalf[i] 26 | i += 1 27 | k += 1 28 | while j < len(righthalf): 29 | alist[k] = righthalf[j] 30 | j += 1 31 | k += 1 32 | 33 | 34 | alist1 = [54, 26, 93, 17, 77, 31, 44, 55, 20] 35 | merge_sort(alist1) 36 | print(alist1) 37 | 38 | ''' 39 | output -> [17, 20, 26, 31, 44, 54, 55, 77, 93] 40 | ''' 41 | -------------------------------------------------------------------------------- /quick_sort.py: -------------------------------------------------------------------------------- 1 | # quicksort (not randomized) 2 | 3 | import random 4 | import time 5 | 6 | 7 | def exchange(t, l, k): 8 | tmp = t[l] 9 | t[l] = t[k] 10 | t[k] = tmp 11 | 12 | 13 | def partition(a, p, r): 14 | s = p 15 | x = a[s] 16 | i = p - 1 17 | j = p 18 | while j <= r - 1: 19 | if a[j] <= x: 20 | i += 1 21 | exchange(a, i, j) 22 | j += 1 23 | exchange(a, i + 1, r) 24 | return i + 1 25 | 26 | 27 | def quicksort(a, p, r): 28 | if p < r: 29 | q = partition(a, p, r) 30 | quicksort(a, p, q - 1) 31 | quicksort(a, q + 1, r) 32 | 33 | 34 | A = [7, 2, 8, 0, 1, 3, 4, 6, 5] 35 | B = [] 36 | for cnt in range(100): 37 | B.append(random.randint(1, random.randint(2, 100000))) 38 | start_time = time.time() 39 | B.sort() 40 | print(B[:20]) 41 | print("time of running in secs: ", time.time() - start_time) 42 | 43 | 44 | ''' 45 | output -> 46 | [138, 173, 236, 422, 778, 850, 996, 1050, 1510, 1804, 1916, 2015, 2249, 2861, 2936, 3006, 3186, 3204, 3280, 3579] 47 | time of running in secs: 4.172325134277344e-05 <- 48 | ''' 49 | -------------------------------------------------------------------------------- /bin_search.py: -------------------------------------------------------------------------------- 1 | # binary search 2 | 3 | 4 | # recursive with slices 5 | 6 | 7 | def bin_search(alist, item): 8 | if len(alist) == 0: 9 | return False 10 | else: 11 | midpoint = len(alist) // 2 12 | if alist[midpoint] == item: 13 | return True 14 | else: 15 | if item < alist[midpoint]: 16 | return bin_search(alist[:midpoint], item) 17 | else: 18 | return bin_search(alist[midpoint + 1:], item) 19 | 20 | 21 | # iterative version 22 | 23 | def bin_search_iter(alist, item): 24 | L = 0 25 | R = len(alist) - 1 26 | test = False 27 | while L <= R and not test: 28 | m = (L + R) // 2 29 | if alist[m] < item: # m1 = 1, m2 = 2 30 | L = m + 1 31 | test = True 32 | if alist[m] > item: 33 | R = m - 1 34 | test = True 35 | if not test: 36 | return True 37 | test = False 38 | return False 39 | 40 | 41 | print(bin_search_iter([1, 2, 3], 743787874875857) == bin_search([1, 2, 3], -743787874875857) == False) 42 | 43 | # output: -> True 44 | -------------------------------------------------------------------------------- /erasthotenes_sieve.py: -------------------------------------------------------------------------------- 1 | # Erasthotenes Sieve algorithm 2 | # https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes 3 | 4 | from math import sqrt 5 | from Euler import prime_sieve 6 | 7 | def simple_sieve(n): 8 | arr = [True] * n 9 | for i in range(2, int(sqrt(n)) + 1): 10 | if arr[i] is True: 11 | j = i*i 12 | k = 1 13 | while j < n: 14 | arr[j] = False 15 | j = i * i + k * i 16 | k += 1 17 | output = [] 18 | for i in range(2, len(arr)): 19 | if arr[i] is True: 20 | output.append(i) 21 | return output 22 | 23 | 24 | 25 | def segmented_sieve(n): 26 | delta = n // int(sqrt(n)) 27 | def calculate_smallest_mult(a, p): 28 | left = a - delta + 1 29 | left_mul = (left) // p 30 | tmp = p * left_mul 31 | if tmp < left: 32 | return tmp + p 33 | else: 34 | return tmp 35 | ms = [] # initialize array of top of segments 36 | primes = [] # initialize primes array 37 | i = 2 * delta # used to create first delta primes 38 | ind = delta 39 | 40 | while i <= n: 41 | ms.append(i) 42 | i += delta 43 | primes = prime_sieve(delta) 44 | 45 | k = 1 # index of numbers in ms 46 | for num in ms: # num is another starting from the 2*delta topmost value of segments 47 | arr = [True] * delta 48 | ind = 0 49 | p = primes[ind] 50 | while p <= int(sqrt(num)): 51 | start = calculate_smallest_mult(num, p) 52 | while start <= num: 53 | # print(arr) 54 | arr[start - delta * k - 1] = False 55 | start += p 56 | ind += 1 57 | p = primes[ind] 58 | for x in range(len(arr)): 59 | if arr[x] is True: 60 | primes.append(x + delta * k + 1) 61 | k += 1 62 | return primes 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /primarity_tests_one_fermat.py: -------------------------------------------------------------------------------- 1 | # Primality Tests 2 | # 3 | # Copyleft 2018 lion137 4 | # 5 | # 1. Fermat Test 6 | 7 | #from Euler import modularexponenation 8 | from random import randint 9 | 10 | def modularexponenation(base, exponent, modulus): 11 | """modular exponentiation""" 12 | if modulus == 1: 13 | return 0 14 | result = 1 15 | base = base % modulus 16 | while exponent > 0: 17 | if exponent % 2 == 1: 18 | result = (result * base) % modulus 19 | exponent >>= 1 20 | base = (base * base) % modulus 21 | return result 22 | 23 | 24 | def fermat_test_single(n): 25 | """performs single Fermat test""" 26 | def test(a): 27 | return modularexponenation(a, n, n) == a 28 | return test(randint(1, n - 1)) 29 | 30 | 31 | def fermat_extended(n, cnt): 32 | """performing fermat tests in a loop, 33 | for #cnt of numbers (0, n) """ 34 | for i in range(cnt): 35 | if not fermat_test_single(n): 36 | return False 37 | return True 38 | 39 | # 2. Miler - Rabin 40 | 41 | # procedure nontrivial_root, which looking for a non trivial square root of one mod n 42 | 43 | def nontrivial_root(a, n): 44 | """checking Fermat Theorem, and non trivial square root""" 45 | 46 | # find t and u, such that u odd, t >= 1 and n - 1 = 2^tu: 47 | t, u = 0, n - 1 48 | while u % 2 == 0: 49 | t += 1 50 | u //= 2 51 | 52 | x0 = modularexponenation(a, u, n) 53 | for i in range(1, t + 1): 54 | x1 = x0 ** 2 % n 55 | if x1 == 1 and x0 != 1 and x0 != n - 1: 56 | return True 57 | if x1 != 1: 58 | return True 59 | return False 60 | 61 | 62 | def miller_rabin(n, s): 63 | """Miler Rabin Test""" 64 | 65 | # Return True if n = 2 66 | if n == 2: 67 | return True 68 | # Return False if even 69 | if n % 2 == 0: 70 | return False 71 | 72 | for i in range(s): 73 | a = randint(1, n - 1) 74 | if nontrivial_root(a, n): 75 | return False 76 | return True 77 | 78 | 79 | -------------------------------------------------------------------------------- /Python-Algorithms: -------------------------------------------------------------------------------- 1 | # program to generate the all 2^n subsets of n length binary sequence 2 | # ex.: 2 bits -> (00), (01), (10), (11) 3 | # also generating any m length sequences of k objects - both of them as 4 | # iterators, and recursively and iteratively (slow) generating gray code: 5 | # https://en.wikipedia.org/wiki/Gray_code 6 | 7 | 8 | def bin_pow_set(n): 9 | """returns power set of the all bit sequences of 10 | length n as an iterator""" 11 | def append_zeroes(x, n): 12 | """helper function to append zeroes""" 13 | x = bin(x) 14 | x = x[2:] 15 | return '0' * (n - len(x)) + x 16 | i = 0 17 | k = 0 18 | while k < 2 ** n - 1: 19 | k += 1 20 | i = append_zeroes(k, n) 21 | yield i 22 | 23 | 24 | def dec_to_any(n,base): 25 | conv_string = "0123456789ABCDEF" 26 | if n < base: 27 | return conv_string[n] 28 | else: 29 | return dec_to_any(n // base, base) + conv_string[n % base] 30 | 31 | def any_pow_set(n, m): 32 | """returns the all length n sequences of 33 | m elements, as an iterator""" 34 | def append_zeroes(x, n, base): 35 | """helper function to append zeroes""" 36 | x = dec_to_any(x, base) 37 | return '0' * (n - len(x)) + x 38 | i = 0 39 | k = 0 40 | while k < m ** n - 1: 41 | k += 1 42 | i = append_zeroes(k, n, m) 43 | yield i 44 | 45 | 46 | def gray(n, xs=[""]): 47 | """recursively computes a list of gray codes of 48 | length n""" 49 | def zero_pref(xs): 50 | if not xs: 51 | return ["0"] 52 | return ["0" + x for x in xs] 53 | 54 | def one_pref_rev(xs): 55 | if not xs: 56 | return ["1"] 57 | else: 58 | return ["1" + x for x in [y[::-1] for y in xs]] 59 | if n == 0: 60 | return "" 61 | else: 62 | return zero_pref(gray(n - 1, xs)) + one_pref_rev(gray(n - 1, xs)) 63 | 64 | def gray_iter(n): 65 | """iteratively computes a list of gray codes of 66 | length n""" 67 | def zero_pref(xs): 68 | if not xs: 69 | return ["0"] 70 | return ["0" + x for x in xs] 71 | 72 | def one_pref_rev(xs): 73 | if not xs: 74 | return ["1"] 75 | else: 76 | return ["1" + x for x in [y[::-1] for y in xs]] 77 | xs= [""] 78 | k = 0 79 | while k < n: 80 | xs = zero_pref(xs) + one_pref_rev(xs) 81 | k += 1 82 | return xs 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /powersets_and_gray_code.py: -------------------------------------------------------------------------------- 1 | # program to generate the all 2^n subsets of n length binary sequence 2 | # ex.: 2 bits -> (00), (01), (10), (11) 3 | # also generating any m length sequences of k objects - both of them as 4 | # iterators, and recursively and iteratively (slow) generating gray code: 5 | # https://en.wikipedia.org/wiki/Gray_code 6 | 7 | 8 | def bin_pow_set(n): 9 | """returns power set of the all bit sequences of 10 | length n as an iterator""" 11 | def append_zeroes(x, n): 12 | """helper function to append zeroes""" 13 | x = bin(x) 14 | x = x[2:] 15 | return '0' * (n - len(x)) + x 16 | i = 0 17 | k = 0 18 | yield '0' * n 19 | while k < 2 ** n - 1: 20 | k += 1 21 | i = append_zeroes(k, n) 22 | yield i 23 | 24 | 25 | def dec_to_any(n,base): 26 | conv_string = "0123456789ABCDEF" 27 | if n < base: 28 | return conv_string[n] 29 | else: 30 | return dec_to_any(n // base, base) + conv_string[n % base] 31 | 32 | def any_pow_set(n, m): 33 | """returns the all length n sequences of 34 | m elements, as an iterator""" 35 | def append_zeroes(x, n, base): 36 | """helper function to append zeroes""" 37 | x = dec_to_any(x, base) 38 | return '0' * (n - len(x)) + x 39 | i = 0 40 | k = 0 41 | yield "0" * n 42 | while k < m ** n - 1: 43 | k += 1 44 | i = append_zeroes(k, n, m) 45 | yield i 46 | 47 | 48 | def gray(n, xs=[""]): 49 | """recursively computes a list of gray codes of 50 | length n""" 51 | def zero_pref(xs): 52 | if not xs: 53 | return ["0"] 54 | return ["0" + x for x in xs] 55 | 56 | def one_pref_rev(xs): 57 | if not xs: 58 | return ["1"] 59 | else: 60 | return ["1" + x for x in [y[::-1] for y in xs]] 61 | if n == 0: 62 | return "" 63 | else: 64 | return zero_pref(gray(n - 1, xs)) + one_pref_rev(gray(n - 1, xs)) 65 | 66 | def gray_iter(n): 67 | """iteratively computes a list of gray codes of 68 | length n""" 69 | def zero_pref(xs): 70 | if not xs: 71 | return ["0"] 72 | return ["0" + x for x in xs] 73 | 74 | def one_pref_rev(xs): 75 | if not xs: 76 | return ["1"] 77 | else: 78 | return ["1" + x for x in [y[::-1] for y in xs]] 79 | xs= [""] 80 | k = 0 81 | while k < n: 82 | xs = zero_pref(xs) + one_pref_rev(xs) 83 | k += 1 84 | return xs 85 | 86 | 87 | if __name__ == '__main__': 88 | it_bin = bin_pow_set(3) 89 | print(list(it_bin)) # -> ['001', '010', '011', '100', '101', '110', '111'] 90 | it_any = any_pow_set(3, 3) 91 | print(list(it_any)) # -> ['001', '002', '010', '011', '012', ... , '220', '221', '222'] 92 | print(gray_iter(3)) 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /miller_rabin_fermat_lucas_lehmer.py: -------------------------------------------------------------------------------- 1 | # Primality Tests 2 | # 3 | # Copyleft 2018 lion137 4 | # 5 | # 1. Fermat Test 6 | 7 | 8 | from random import randint 9 | 10 | 11 | def modularexponenation(base, exponent, modulus): 12 | """modular exponentiation""" 13 | if modulus == 1: 14 | return 0 15 | result = 1 16 | base = base % modulus 17 | while exponent > 0: 18 | if exponent % 2 == 1: 19 | result = (result * base) % modulus 20 | exponent >>= 1 21 | base = (base * base) % modulus 22 | return result 23 | 24 | 25 | # Fast Exp 26 | def exp(x, n): 27 | if n == 0: 28 | return 1 29 | elif n == 1: 30 | return x 31 | elif n % 2 == 0: 32 | a = exp(x * x, n // 2) 33 | return a 34 | elif not n % 2 == 0: 35 | b = x * exp(x * x, (n - 1) // 2) 36 | return b 37 | 38 | 39 | def fermat_test_single(n): 40 | """performs single Fermat test""" 41 | def test(a): 42 | return modularexponenation(a, n, n) == a 43 | return test(randint(1, n - 1)) 44 | 45 | 46 | def fermat_extended(n, cnt): 47 | """performing fermat tests in a loop, 48 | for #cnt of numbers (0, n) """ 49 | for i in range(cnt): 50 | if not fermat_test_single(n): 51 | return False 52 | return True 53 | 54 | # 2. Miler - Rabin 55 | 56 | 57 | def miller_rabin(n, s): 58 | """Miler Rabin Test""" 59 | 60 | # procedure nontrivial_root, which looking for a non trivial square root of one mod n 61 | def nontrivial_root(a, n): 62 | """checking Fermat Theorem, and non trivial square root""" 63 | 64 | # find t and u, such that u odd, t >= 1 and n - 1 = 2^tu: 65 | t, u = 0, n - 1 66 | while u % 2 == 0: 67 | t += 1 68 | u //= 2 69 | 70 | x0 = modularexponenation(a, u, n) 71 | for i in range(1, t + 1): 72 | x1 = x0 ** 2 % n 73 | if x1 == 1 and x0 != 1 and x0 != n - 1: 74 | return True 75 | if x1 != 1: 76 | return True 77 | return False 78 | 79 | # Return True if n = 2 80 | if n == 2: 81 | return True 82 | # Return False if even 83 | if n % 2 == 0: 84 | return False 85 | 86 | for i in range(s): 87 | a = randint(1, n - 1) 88 | if nontrivial_root(a, n): 89 | return False 90 | return True 91 | 92 | 93 | # 3. Lucas - Lehmer Test, check primality only Mersenne Primes: 94 | # https://en.wikipedia.org/wiki/Mersenne_prime 95 | 96 | # Procedure Lucas-Lehmer, tests if Mp is prime, p > 2: 97 | 98 | def lucas_lehmer(p): 99 | s = 4 100 | m = exp(2, p) - 1 101 | for i in range(p - 2): 102 | s = ((s * s) - 2) % m 103 | return True if s == 0 else False 104 | 105 | if __name__ == '__main__': 106 | # print(miller_rabin(2 ** 44497 - 1, 40)) # -> True in... stop after 2008 secs:) 107 | print(lucas_lehmer(44497)) # -> True in 79.08 sec 108 | -------------------------------------------------------------------------------- /inv_index.py: -------------------------------------------------------------------------------- 1 | from porpositional_logic_eval import * 2 | 3 | 4 | def find(elem, d_list): 5 | l_return = [] 6 | i = 0 7 | for x in d_list: 8 | if elem in x: 9 | l_return.append(i) 10 | i += 1 11 | return l_return, len(l_return) 12 | 13 | 14 | def find_key(x, d): 15 | for y in d.keys(): 16 | if x in y: 17 | return y 18 | return "word not in a texts" 19 | 20 | 21 | d1 = ['i', 'did', 'enact', 'julius', 'caesar', 'i', 'was', 'kill', 'i', 'the', 'capitol', 'brutus', 'me'] 22 | d1 = set(d1) 23 | d2 = ['i', 'so', 'let', 'it', 'be', 'with', 'caesar', 'the', 'noble', 'brutus', 'hath', 'told', 'you', 24 | 'caesar', 'was', 'ambitious'] 25 | d2 = set(d2) 26 | doc_list = [] 27 | doc_list.append(d1) 28 | doc_list.append(d2) 29 | 30 | tokens = d1.union(d2) 31 | inv_index = {} 32 | for x in tokens: 33 | tmp, tmp1 = find(x, doc_list) 34 | inv_index[(x, tmp1)] = tmp 35 | 36 | 37 | def NOT(l1): 38 | indexes = l1 39 | ret_list = [] 40 | for x in range(len(doc_list)): 41 | if x not in indexes: 42 | ret_list.append(x) 43 | return ret_list 44 | 45 | 46 | def OR(l1, l2): 47 | tmp0 = set(l1) 48 | tmp1 = set(l2) 49 | indexes = tmp0.union(tmp1) 50 | ret_list = [] 51 | for x in indexes: 52 | ret_list.append(x) 53 | return ret_list 54 | 55 | 56 | def AND(l1, l2): 57 | tmp0 = set(l1) 58 | tmp1 = set(l2) 59 | indexes = tmp0.intersection(tmp1) 60 | ret_list = [] 61 | for x in indexes: 62 | ret_list.append(x) 63 | return ret_list 64 | 65 | 66 | def query_tree_evaluate(tree): 67 | opers = {'||': OR, '&&': AND, '~': NOT} 68 | leftT = tree.getLeftChild() 69 | rightT = tree.getRightChild() 70 | # pdb.set_trace() 71 | if leftT and not rightT: 72 | fn = opers[tree.getRootVal()] 73 | return fn(query_tree_evaluate(leftT)) 74 | elif leftT and rightT: 75 | fn = opers[tree.getRootVal()] 76 | return fn(query_tree_evaluate(leftT), query_tree_evaluate(rightT)) 77 | else: 78 | return tree.getRootVal() 79 | 80 | 81 | def build_query_parse_tree(exp): 82 | exp_list = exp.replace('(', ' ( ').replace(')', ' ) ').replace('~', ' ~ ').split() 83 | e_tree = BinaryTree('') 84 | current_tree = e_tree 85 | for token in exp_list: 86 | if token == '(': 87 | current_tree.insertLeft('') 88 | current_tree = current_tree.getLeftChild() 89 | elif token in ['||', '&&', '->', '==', 'XR']: 90 | if current_tree.getRootVal() == '~': 91 | current_tree.getParent().setRootVal(token) 92 | current_tree.insertRight('') 93 | current_tree = current_tree.getRightChild() 94 | else: 95 | current_tree.setRootVal(token) 96 | current_tree.insertRight('') 97 | current_tree = current_tree.getRightChild() 98 | elif token == '~': 99 | current_tree.setRootVal('~') 100 | current_tree.insertLeft('') 101 | current_tree = current_tree.getLeftChild() 102 | elif token == ')': 103 | current_tree = current_tree.getParent() 104 | elif re.search('[a-zA-z]', token): 105 | current_tree.setRootVal(inv_index[find_key(token, inv_index)]) 106 | current_tree = current_tree.getParent() 107 | if current_tree.getRootVal() == '~': 108 | current_tree = current_tree.getParent() 109 | else: 110 | raise ValueError 111 | return e_tree 112 | 113 | 114 | if __name__ == "__main__": 115 | exp = "((i && caesar) && ~julius)" 116 | tr = build_query_parse_tree(exp) 117 | inorder_traversal(tr) 118 | print(query_tree_evaluate(tr)) 119 | ''' 120 | output -> 121 | [0, 1] 122 | && 123 | [0, 1] 124 | && 125 | [0] 126 | ~ 127 | 128 | [1] 129 | ''' 130 | --------------------------------------------------------------------------------