├── Fractions in reduced form.py ├── GCD of n numbers.py ├── README.md ├── Maximum of all mods in an array.py ├── Modular Inverse when mod is prime.py ├── Check if a number is a power of 2 or not.py ├── Sum of products of all possible subarrays.py ├── Day on a particular date.py ├── Check if a number is prime or not.py ├── LCM of n numbers.py ├── DFS.py ├── Prime factors of a number.py ├── BFS.py ├── Factors or divisors of a number.py ├── Number of prime factors of a number.py ├── Number of values in a range.py ├── ncr mod m.py ├── Number of integral points in a triangle.py ├── isprime.py ├── Maximum subarray sum mod m.py ├── Coin Change Minimum Number of Coins.py ├── Knapsack 01.py ├── Subset Sum.py ├── List of ncr.py ├── Prime numbers till n.py ├── Modular Inverse.py ├── Connected Components using DFS.py ├── Fibonacci Series in logn.py ├── Maximum of all subarrays of size k (Sliding Window).py ├── Combinations.py ├── Sum of factors or divisors of a number.py ├── Lexicographic rank of a string.py ├── Fenwick Tree or Binary Indexed Tree.py ├── Submatrix Sum Queries.py ├── Longest Common Subsequence.py ├── Minimum Spanning Tree (Prims's).py ├── Print matrix diagonally.py ├── Lowest Common Ancestor.py ├── KMP Algorithm for pattern search.py ├── Z Algorithm for pattern search.py ├── Check if a graph is bipartite or not.py ├── Sum of maximum elements of sliding window of length K using fenwick tree.py ├── Segment Tree - Sum of a given range.py ├── Segment Tree - Range Minimum Query (RMQ).py ├── BST.py └── Lowest Common Ancestor (Optimised).py /Fractions in reduced form.py: -------------------------------------------------------------------------------- 1 | from fractions import Fraction 2 | print Fraction(3,63) 3 | -------------------------------------------------------------------------------- /GCD of n numbers.py: -------------------------------------------------------------------------------- 1 | from fractions import gcd 2 | li=[12,16,48] 3 | print reduce(gcd,li) 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python-modules-for-competitive-programming 2 | Important python codes that can be used in various contests held online! 3 | -------------------------------------------------------------------------------- /Maximum of all mods in an array.py: -------------------------------------------------------------------------------- 1 | li=[2,5,7,10,100] 2 | li.sort(reverse=True) 3 | for i in li: 4 | if i!=li[0]: 5 | print i 6 | break 7 | else: 8 | print 0 9 | -------------------------------------------------------------------------------- /Modular Inverse when mod is prime.py: -------------------------------------------------------------------------------- 1 | """ Works only if 'm' is prime """ 2 | def mod_inv(n,m): 3 | n=n%m 4 | return pow(n,m-2,m) 5 | 6 | mod=10**9+7 7 | print mod_inv(9,mod) 8 | -------------------------------------------------------------------------------- /Check if a number is a power of 2 or not.py: -------------------------------------------------------------------------------- 1 | def check(n): 2 | if n&(n-1)==0: 3 | return True 4 | else: 5 | return False 6 | 7 | print check(1024) 8 | print check(500) 9 | print check(100) 10 | -------------------------------------------------------------------------------- /Sum of products of all possible subarrays.py: -------------------------------------------------------------------------------- 1 | from itertools import izip, chain 2 | 3 | l = [2]*10000 4 | x = [1] 5 | for i in l: 6 | x = [a + b*i for a,b in izip(chain([0],x), chain(x,[0]))] 7 | print x[2]%(10**9+7) 8 | -------------------------------------------------------------------------------- /Day on a particular date.py: -------------------------------------------------------------------------------- 1 | import calendar 2 | day = {0:'MONDAY', 1:'TUESDAY', 2:'WEDNESDAY', 3:'THURSDAY', 4:'FRIDAY', 5:'SATURDAY', 6:'SUNDAY'} 3 | m,d,y = map(int,raw_input().split()) 4 | print day[calendar.weekday(y,m,d)] 5 | -------------------------------------------------------------------------------- /Check if a number is prime or not.py: -------------------------------------------------------------------------------- 1 | from math import sqrt; from itertools import count, islice 2 | 3 | def isPrime(n): 4 | if n < 2: return False 5 | return all(n%i for i in islice(count(2), int(sqrt(n)-1))) 6 | 7 | print isPrime(97) 8 | -------------------------------------------------------------------------------- /LCM of n numbers.py: -------------------------------------------------------------------------------- 1 | def gcd(x, y): 2 | while(y): 3 | x, y = y, x % y 4 | return x 5 | 6 | def lcm(x, y): 7 | lcm = (x*y)//gcd(x,y) 8 | return lcm 9 | 10 | def lcm_of_n(li): 11 | return reduce(lcm,li) 12 | 13 | li=[1,2,3,4,5,6,7,8,9,10] 14 | print lcm_of_n(li) 15 | -------------------------------------------------------------------------------- /DFS.py: -------------------------------------------------------------------------------- 1 | def dfs(graph, start, path=[]): 2 | q=[start] 3 | while q: 4 | v=q.pop(0) 5 | if v not in path: 6 | path=path+[v] 7 | q=graph[v]+q 8 | return path 9 | 10 | graph = {'A':['B','C'],'B':['D','E'],'C':['D','E'],'D':['E'],'E':['A']} 11 | print dfs(graph,'A') 12 | -------------------------------------------------------------------------------- /Prime factors of a number.py: -------------------------------------------------------------------------------- 1 | def pf(n): 2 | primfac = [] 3 | d = 2 4 | while d*d <= n: 5 | while (n % d) == 0: 6 | primfac.append(d) 7 | n //= d 8 | d += 1 9 | if n > 1: 10 | primfac.append(n) 11 | return primfac 12 | 13 | n=input() 14 | print pf(n) 15 | -------------------------------------------------------------------------------- /BFS.py: -------------------------------------------------------------------------------- 1 | def bfs(graph, start, path=[]): 2 | '''iterative breadth first search from start''' 3 | q=[start] 4 | while q: 5 | v=q.pop(0) 6 | if not v in path: 7 | path=path+[v] 8 | q=q+graph[v] 9 | return path 10 | 11 | graph = {'A':['B','C'],'B':['D','E'],'C':['D','E'],'D':['E'],'E':['A']} 12 | print bfs(graph,'A') 13 | -------------------------------------------------------------------------------- /Factors or divisors of a number.py: -------------------------------------------------------------------------------- 1 | def factors(n): 2 | l1, l2 = [], [] 3 | for i in range(1, int(n ** 0.5) + 1): 4 | q,r = n/i, n%i 5 | if r == 0: 6 | l1.append(i) 7 | l2.append(q) 8 | if l1[-1] == l2[-1]: 9 | l1.pop() 10 | l2.reverse() 11 | return l1 + l2 12 | 13 | n=128 14 | print factors(n) 15 | -------------------------------------------------------------------------------- /Number of prime factors of a number.py: -------------------------------------------------------------------------------- 1 | def pf(n): 2 | primfac={} 3 | d = 2 4 | while d*d <= n: 5 | while (n % d) == 0: 6 | try: 7 | primfac[d]+=1 8 | except: 9 | primfac[d]=1 10 | n //= d 11 | d += 1 12 | if n > 1: 13 | primfac[n]=1 14 | return primfac 15 | 16 | n=input() 17 | print pf(n) 18 | -------------------------------------------------------------------------------- /Number of values in a range.py: -------------------------------------------------------------------------------- 1 | from sys import stdin as ip 2 | from bisect import bisect_left as bl 3 | from bisect import bisect_right as br 4 | aa,bb=500,500 5 | n=int(ip.readline()) 6 | li=list(map(int,ip.readline().split())) 7 | q=int(ip.readline()) 8 | li.sort() 9 | for i in xrange(q): 10 | a,b=map(int,ip.readline().split()) 11 | i1= br(li,b) 12 | i2= bl(li,a) 13 | print i1-i2 14 | -------------------------------------------------------------------------------- /ncr mod m.py: -------------------------------------------------------------------------------- 1 | """ Works only if 'm' is prime """ 2 | def mod_inv(n,m): 3 | n=n%m 4 | return pow(n,m-2,m) 5 | def nCr(n,r,m): 6 | numerator=1 7 | for i in xrange(r): 8 | numerator=(numerator*(n-i))%m 9 | denomenator=1 10 | for i in xrange(2,r+1): 11 | denomenator=(denomenator*i)%m 12 | return (numerator*mod_inv(denomenator,m))%m 13 | mod=10**9+7 14 | print nCr(10000,500,mod) 15 | -------------------------------------------------------------------------------- /Number of integral points in a triangle.py: -------------------------------------------------------------------------------- 1 | #PICK'S THEOREM 2 | from fractions import gcd 3 | from math import ceil 4 | 5 | def no_of_points_in_triangle(x1,y1,x2,y2,x3,y3): 6 | a = abs(((x1-x2)*(y1+y2) + (x2-x3)*(y2+y3) + (x3-x1)*(y3+y1))) 7 | g1=gcd(abs(x1-x2), abs(y1-y2)) 8 | g2=gcd(abs(x2-x3), abs(y2-y3)) 9 | g3=gcd(abs(x3-x1), abs(y3-y1)) 10 | i = a + 2 - (g1+g2+g3) 11 | return i/2 12 | 13 | print no_of_points_in_triangle(1,1,2,10,5,5) 14 | -------------------------------------------------------------------------------- /isprime.py: -------------------------------------------------------------------------------- 1 | def isprime(n): 2 | if n == 2 or n == 3: 3 | return True 4 | if n < 2 or n % 2 == 0: 5 | return False 6 | if n < 9: 7 | return True 8 | if n % 3 == 0: 9 | return False 10 | r = int(n**0.5) 11 | f = 5 12 | while f <= r: 13 | if n % f == 0: 14 | return False 15 | if n % (f + 2) == 0: 16 | return False 17 | f += 6 18 | return True 19 | 20 | print isprime(999000011) 21 | -------------------------------------------------------------------------------- /Maximum subarray sum mod m.py: -------------------------------------------------------------------------------- 1 | def max_subarray_sum_mod_m(li,n,m): 2 | temp=0 3 | s=[] 4 | maxx=-1 5 | for i in xrange(n): 6 | temp=(temp+li[i])%m 7 | s.append([temp,i]) 8 | if temp>maxx: 9 | maxx=temp 10 | s.sort() 11 | minn=m+1 12 | for i in xrange(n-1): 13 | if s[i][1]>s[i+1][1]: 14 | minn=min(s[i+1][0]-s[i][0],minn) 15 | return max(maxx,m-minn) 16 | 17 | print max_subarray_sum_mod_m([10,15,23,28,30],5,6) 18 | -------------------------------------------------------------------------------- /Coin Change Minimum Number of Coins.py: -------------------------------------------------------------------------------- 1 | def min_coins(coins,total): 2 | len_coins=len(coins) 3 | dp=[[0 if i==0 else float("inf") for i in xrange(total+1)] for _ in xrange(len_coins)] 4 | for i in xrange(len_coins): 5 | for j in xrange(1,total+1): 6 | if j>=coins[i]: 7 | dp[i][j]=min(dp[i-1][j],1+dp[i][j-coins[i]]) 8 | else: 9 | dp[i][j]=dp[i-1][j] 10 | return dp[-1][-1] 11 | coins=[1,5,6,8] 12 | total=11 13 | print min_coins(coins,total) 14 | -------------------------------------------------------------------------------- /Knapsack 01.py: -------------------------------------------------------------------------------- 1 | def knapsack01(weight,value,max_weight): 2 | n=len(value) 3 | dp=[[0 for i in xrange(max_weight+1)] for j in xrange(n+1)] 4 | for i in xrange(1,n+1): 5 | for j in xrange(1,max_weight+1): 6 | if jj: 9 | dp[i][j]=dp[i-1][j] 10 | else: 11 | dp[i][j]=dp[i-1][j] or dp[i-1][j-li[i-1]] 12 | return dp[-1][-1] 13 | 14 | A=[3,34,4,12,5,2,124,421,412,125,1325,35,3,351,35,351,35,12312,1242142] 15 | s=8 16 | print subset_sum(A,s) 17 | -------------------------------------------------------------------------------- /List of ncr.py: -------------------------------------------------------------------------------- 1 | def ncr(n,r,li): 2 | if n==r: 3 | li[n][r]=1 4 | return li[n][r] 5 | if r==0: 6 | li[n][r]=1 7 | return li[n][r] 8 | if r==1: 9 | li[n][r]=n 10 | return li[n][r] 11 | if li[n][r]: 12 | return li[n][r] 13 | li[n][r]=ncr(n-1,r,li)+ncr(n-1,r-1,li) 14 | return li[n][r] 15 | 16 | li=[] 17 | for i in xrange(1,(10**1)+3): 18 | li.append([0]*(i)) 19 | li[0][0]=1 20 | for i in xrange(1,(10**1)): 21 | for j in xrange(0,i+1): 22 | li[i][j]=ncr(i+1,j+1,li) 23 | print li 24 | -------------------------------------------------------------------------------- /Prime numbers till n.py: -------------------------------------------------------------------------------- 1 | def primes(n): 2 | correction = (n%6>1) 3 | n = {0:n,1:n-1,2:n+4,3:n+3,4:n+2,5:n+1}[n%6] 4 | sieve = [True] * (n//3) 5 | sieve[0] = False 6 | for i in range(int(n**0.5)//3+1): 7 | if sieve[i]: 8 | k=3*i+1|1 9 | sieve[((k*k)//3)::2*k]=[False]*((n//6-(k*k)//6-1)//k+1) 10 | sieve[(k*k+4*k-2*k*(i&1))//3::2*k]=[False]*((n//6-(k*k+4*k-2*k*(i&1))//6-1)//k+1) 11 | return [2,3] + [3*i+1|1 for i in range(1,n//3-correction) if sieve[i]] 12 | 13 | 14 | li=primes((10**3)+1) 15 | print li 16 | -------------------------------------------------------------------------------- /Modular Inverse.py: -------------------------------------------------------------------------------- 1 | def extended_gcd(aa, bb): 2 | lastremainder, remainder = abs(aa), abs(bb) 3 | x, lastx, y, lasty = 0, 1, 1, 0 4 | while remainder: 5 | lastremainder, (quotient, remainder) = remainder, divmod(lastremainder, remainder) 6 | x, lastx = lastx - quotient*x, x 7 | y, lasty = lasty - quotient*y, y 8 | return lastremainder, lastx * (-1 if aa < 0 else 1), lasty * (-1 if bb < 0 else 1) 9 | 10 | def modinv(a, m): 11 | g, x, y = extended_gcd(a, m) 12 | if g != 1: 13 | raise ValueError 14 | return x % m 15 | 16 | mod=10**9+7 17 | print modinv(4,mod) 18 | -------------------------------------------------------------------------------- /Connected Components using DFS.py: -------------------------------------------------------------------------------- 1 | def connected_components(graph): 2 | seen = set() 3 | def dfs(v): 4 | vs = set([v]) 5 | component=[] 6 | while vs: 7 | v = vs.pop() 8 | seen.add(v) 9 | vs |= set(graph[v]) - seen 10 | component.append(v) 11 | return component 12 | ans=[] 13 | for v in graph: 14 | if v not in seen: 15 | d=dfs(v) 16 | ans.append(d) 17 | return ans 18 | 19 | graph={1: [2, 3], 2: [1, 3], 3: [2, 1], 4: [5], 5: [4, 6], 6: [5, 7], 7: [6]} 20 | n=7 21 | print connected_components(graph) 22 | -------------------------------------------------------------------------------- /Fibonacci Series in logn.py: -------------------------------------------------------------------------------- 1 | def matrix_mul(A, B): 2 | return ([A[0][0] * B[0][0] + A[0][1] * B[1][0], 3 | A[0][0] * B[0][1] + A[0][1] * B[1][1]], 4 | [A[1][0] * B[0][0] + A[1][1] * B[1][0], 5 | A[1][0] * B[0][1] + A[1][1] * B[1][1]]) 6 | 7 | def matrix_exp(A, e): 8 | if not e: 9 | return [[1,0],[0,1]] 10 | elif e % 2: 11 | return matrix_mul(A, matrix_exp(A, e-1)) 12 | else: 13 | sq= matrix_exp(A, e//2) 14 | return matrix_mul(sq, sq) 15 | 16 | def fibo(n): 17 | M = [[1,1],[1,0]] 18 | return matrix_exp(M, n)[0][0] 19 | 20 | print fibo(4) 21 | -------------------------------------------------------------------------------- /Maximum of all subarrays of size k (Sliding Window).py: -------------------------------------------------------------------------------- 1 | import heapq 2 | def subarray_max(li,n,k): 3 | ans=[] 4 | heap=[] 5 | for i in xrange(k): 6 | while heap!=[] and li[i]>=li[heap[-1]]: 7 | heap.pop() 8 | heapq.heappush(heap,i) 9 | for i in xrange(k,n): 10 | ans.append(li[heap[0]]) 11 | while heap!=[] and heap[0]<=i-k: 12 | heap.pop(0) 13 | while heap!=[] and li[i]>=li[heap[-1]]: 14 | heap.pop() 15 | heapq.heappush(heap,i) 16 | ans.append(li[heap[0]]) 17 | return ans 18 | n,k=6,3 19 | li=[5,1,4,2,3,9] 20 | print subarray_max(li,n,k) 21 | 22 | 23 | -------------------------------------------------------------------------------- /Combinations.py: -------------------------------------------------------------------------------- 1 | def combinations(iterable, r): 2 | temp=[] 3 | pool = tuple(iterable) 4 | n = len(pool) 5 | if r > n: 6 | return 7 | indices = range(r) 8 | temp.append( tuple(pool[i] for i in indices)) 9 | while True: 10 | for i in reversed(range(r)): 11 | if indices[i] != i + n - r: 12 | break 13 | else: 14 | return temp 15 | indices[i] += 1 16 | for j in range(i+1, r): 17 | indices[j] = indices[j-1] + 1 18 | temp.append(tuple(pool[i] for i in indices)) 19 | 20 | # combinations(li,k) will print all tuples of length k from the list li 21 | li=[1,2,3,4,5] 22 | print combinations(li,3) 23 | -------------------------------------------------------------------------------- /Sum of factors or divisors of a number.py: -------------------------------------------------------------------------------- 1 | def pf(n): 2 | primfac = [] 3 | d = 2 4 | while d*d <= n: 5 | while (n % d) == 0: 6 | primfac.append(d) # supposing you want multiple factors repeated 7 | n //= d 8 | d += 1 9 | if n > 1: 10 | primfac.append(n) 11 | return primfac 12 | 13 | def sof(n): 14 | li=pf(n) 15 | k=li[0] 16 | i=0 17 | ct=0 18 | s=1 19 | while i 0: 5 | s += BITTree[i] 6 | i -= i & (-i) 7 | return s 8 | 9 | def updatebit(BITTree , n , i ,v): 10 | i += 1 11 | while i <= n: 12 | BITTree[i] += v 13 | i += i & (-i) 14 | 15 | def construct(arr, n): 16 | BITTree = [0]*(n+1) 17 | for i in range(n): 18 | updatebit(BITTree, n, i, arr[i]) 19 | return BITTree 20 | 21 | freq = [2, 1, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9] 22 | BITTree = construct(freq,len(freq)) 23 | print("Sum of elements in arr[0..5] is " + str(getsum(BITTree,5))) 24 | freq[3] += 6 25 | updatebit(BITTree, len(freq), 3, 6) 26 | print("Sum of elements in arr[0..5] is " + str(getsum(BITTree,5))) 27 | -------------------------------------------------------------------------------- /Submatrix Sum Queries.py: -------------------------------------------------------------------------------- 1 | def preprocess(li,aux,n,m): 2 | for i in xrange(m): 3 | aux[0][i]=li[0][i] 4 | for i in xrange(1,n): 5 | for j in xrange(m): 6 | aux[i][j]=li[i][j]+aux[i-1][j] 7 | for i in xrange(n): 8 | for j in xrange(1,m): 9 | aux[i][j]+=aux[i][j-1] 10 | return aux 11 | 12 | def calculateSum(li,lj,ri,rj): 13 | res=aux[ri][rj] 14 | if li>0: 15 | res-=aux[li-1][rj] 16 | if lj>0: 17 | res-=aux[ri][lj-1] 18 | if li>0 and lj>0: 19 | res+=aux[li-1][lj-1] 20 | return res 21 | 22 | aux,li=[],[] 23 | li=[[1, 2, 3, 4, 6], 24 | [5, 3, 8, 1, 2], 25 | [4, 6, 7, 5, 5], 26 | [2, 4, 8, 9, 4]] 27 | n,m=4,5 28 | aux=[[0 for i in xrange(m)] for i in xrange(n)] 29 | aux=preprocess(li,aux,n,m) 30 | print calculateSum(0,0,1,1) 31 | 32 | -------------------------------------------------------------------------------- /Longest Common Subsequence.py: -------------------------------------------------------------------------------- 1 | def lcs(s1,s2): 2 | len_s1=len(s1) 3 | len_s2=len(s2) 4 | dp=[[0 for i in xrange(len_s2+1)] for i in xrange(len_s1+1)] 5 | ans='' 6 | for i in xrange(1,len_s1+1): 7 | for j in xrange(1,len_s2+1): 8 | if s1[i-1]==s2[j-1]: 9 | dp[i][j]+=dp[i-1][j-1]+1 10 | else: 11 | dp[i][j]=max(dp[i-1][j],dp[i][j-1]) 12 | 13 | while len_s1!=0 and len_s2!=0: 14 | if dp[len_s1][len_s2]==dp[len_s1-1][len_s2]: 15 | len_s1-=1 16 | elif dp[len_s1][len_s2]==dp[len_s1][len_s2-1]: 17 | len_s2-=1 18 | else: 19 | if s1[len_s1-1]==s2[len_s2-1]: 20 | ans=s1[len_s1-1]+ans 21 | len_s1-=1 22 | len_s2-=1 23 | return (ans,dp[i][j]) 24 | 25 | print lcs("teacher","cheater") 26 | 27 | -------------------------------------------------------------------------------- /Minimum Spanning Tree (Prims's).py: -------------------------------------------------------------------------------- 1 | def findMin(key,mstSet,n): 2 | m=float("inf") 3 | for v in xrange(n): 4 | if not mstSet[v] and key[v]=r or j>=c or j<0: 5 | return False 6 | else: 7 | return True 8 | def printDiagonally(li,n,m): 9 | for k in xrange(n): 10 | i=k-1 11 | j=1 12 | ct=0 13 | temp=[] 14 | while isvalid(i,j,n,m): 15 | temp.append( li[i][j]) 16 | ct+=1 17 | i-=1 18 | j+=1 19 | for i in xrange(ct-1,-1,-1): 20 | print temp[i], 21 | print li[k][0], 22 | for k in xrange(1,m): 23 | i=n-2 24 | j=k+1 25 | ct=0 26 | temp=[] 27 | while isvalid(i,j,n,m): 28 | temp.append( li[i][j]) 29 | i-=1 30 | j+=1 31 | ct+=1 32 | for i in xrange(ct-1,-1,-1): 33 | print temp[i], 34 | print li[n-1][k], 35 | 36 | printDiagonally([[1,2,3],[4,5,6],[7,8,9]],3,3) 37 | -------------------------------------------------------------------------------- /Lowest Common Ancestor.py: -------------------------------------------------------------------------------- 1 | def min_set_ancestor(tree, childrens): 2 | m = min(childrens) 3 | result = [] 4 | for node in childrens: 5 | if node != m and node in tree: 6 | result.append(tree[node]) 7 | result.append(m) 8 | result = list(set(result)) 9 | return result 10 | 11 | n = int(raw_input().strip()) 12 | data = raw_input().strip() 13 | n1 = int(raw_input().strip()) 14 | nodes = raw_input().strip() 15 | node_data = [int(d.strip()) for d in data.split(' ')] 16 | childrens = [int(d.strip()) for d in nodes.split(' ')] 17 | 18 | tree_data = {i : node_data[i-1] for i in range(1, len(node_data)+1)} 19 | 20 | print tree_data 21 | while len(childrens) > 1: 22 | childrens = min_set_ancestor(tree_data, childrens) 23 | 24 | print childrens[0] 25 | 26 | '''Test Input: 27 | 28 | 0 29 | / \ 30 | 1 2 31 | / | \ \ 32 | 3 4 5 6 33 | / / \ 34 | 7 8 9 35 | 36 | 10 37 | 0 0 1 1 1 2 3 4 4 38 | 3 39 | 7 8 9 40 | ''' 41 | -------------------------------------------------------------------------------- /KMP Algorithm for pattern search.py: -------------------------------------------------------------------------------- 1 | def KMPSearch(pattern, text): 2 | M = len(pattern) 3 | N = len(text) 4 | lps = [0]*M 5 | computeLPSArray(pattern, M, lps) 6 | i, j = 0, 0 7 | while i < N: 8 | if pattern[j] == text[i]: 9 | i += 1 10 | j += 1 11 | if j == M: 12 | print "Found patterntern at index " + str(i-j) 13 | j = lps[j-1] 14 | elif i < N and pattern[j] != text[i]: 15 | if j != 0: 16 | j = lps[j-1] 17 | else: 18 | i += 1 19 | 20 | def computeLPSArray(pattern, M, lps): 21 | length = 0 22 | i = 1 23 | while i < M: 24 | if pattern[i]==pattern[length]: 25 | length += 1 26 | lps[i] = length 27 | i += 1 28 | else: 29 | if length != 0: 30 | length = lps[length-1] 31 | else: 32 | lps[i] = 0 33 | i += 1 34 | 35 | text = "ABABDABACDABABCABAB" 36 | pattern = "ABABCABAB" 37 | KMPSearch(pattern, text) 38 | -------------------------------------------------------------------------------- /Z Algorithm for pattern search.py: -------------------------------------------------------------------------------- 1 | def calculateZ(s, length): 2 | Z = [0] * length 3 | Z[0] = length 4 | rt = 0 5 | lt = 0 6 | for k in range(1, length): 7 | if k > rt: 8 | n = 0 9 | while n + k < length and s[n] == s[n+k]: 10 | n += 1 11 | Z[k] = n 12 | if n > 0: 13 | lt = k 14 | rt = k+n-1 15 | else: 16 | p = k - lt 17 | right_part_len = rt - k + 1 18 | if Z[p] < right_part_len: 19 | Z[k] = Z[p] 20 | else: 21 | i = rt + 1 22 | while i < length and s[i] == s[i - k]: 23 | i += 1 24 | Z[k] = i - k 25 | lt = k 26 | rt = i - 1 27 | return Z 28 | 29 | def search(pattern, text): 30 | result = [] 31 | N, M = len(text), len(pattern) 32 | s = '{0}${1}'.format(pattern, text) 33 | zs = calculateZ(s, len(s)) 34 | for i, z in enumerate(zs): 35 | if z == M: 36 | result.append(i - M - 1) 37 | return result 38 | 39 | text = "ABABDABACDABABCABAB" 40 | pattern = "ABABCABAB" 41 | print search(pattern, text) 42 | -------------------------------------------------------------------------------- /Check if a graph is bipartite or not.py: -------------------------------------------------------------------------------- 1 | # When graph is in dictionary form: 2 | def isBipartite(graph,n): 3 | color=[-1 for _ in xrange(n)] 4 | for i in xrange(n): 5 | if color[i]!=-1: 6 | continue 7 | queue=[i] 8 | color[i]=1 9 | while queue: 10 | u=queue.pop(0) 11 | for v in graph[u]: 12 | if color[v]==-1: 13 | color[v]=1-color[u] 14 | elif color[v]==color[u]: 15 | return False 16 | return True 17 | 18 | # When graph is in adjacency matrix form: 19 | def isBipartite2(graph,n): 20 | color=[-1 for _ in xrange(n)] 21 | for i in xrange(n): 22 | if color[i]!=-1: 23 | continue 24 | queue=[i] 25 | color[i]=1 26 | while queue: 27 | u=queue.pop(0) 28 | for v in xrange(n): 29 | if graph[u][v] and color[v]==-1: 30 | color[v]=1-color[u] 31 | queue.append(v) 32 | elif graph[u][v] and color[v]==color[u]: 33 | return False 34 | return True 35 | 36 | 37 | graph={0:[1,3],1:[0,2],2:[1,3],3:[0,2]} 38 | n=4 39 | print isBipartite(graph,n) 40 | 41 | graph=[[0,1,0,1], 42 | [1,0,1,0], 43 | [0,1,0,1], 44 | [1,0,1,0]] 45 | print isBipartite2(graph,n) 46 | -------------------------------------------------------------------------------- /Sum of maximum elements of sliding window of length K using fenwick tree.py: -------------------------------------------------------------------------------- 1 | def left_extents(lst): 2 | result = [] 3 | stack = [-1] 4 | for i in range(len(lst)): 5 | while stack[-1] >= 0 and lst[i] >= lst[stack[-1]]: 6 | del stack[-1] 7 | result.append(stack[-1] + 1) 8 | stack.append(i) 9 | return result 10 | 11 | 12 | def right_extents(lst): 13 | result = [] 14 | stack = [len(lst)] 15 | for i in range(len(lst) - 1, -1, -1): 16 | while stack[-1] < len(lst) and lst[i] > lst[stack[-1]]: 17 | del stack[-1] 18 | result.append(stack[-1]) 19 | stack.append(i) 20 | result.reverse() 21 | return result 22 | 23 | 24 | def sliding_window_totals(lst): 25 | delta_constant = [0] * (len(lst) + 2) 26 | delta_linear = [0] * (len(lst) + 2) 27 | for l, i, r in zip(left_extents(lst), range(len(lst)), right_extents(lst)): 28 | a = i - l 29 | b = r - (i + 1) 30 | if a > b: 31 | a, b = b, a 32 | delta_linear[1] += lst[i] 33 | delta_linear[a + 1] -= lst[i] 34 | delta_constant[a + 1] += lst[i] * (a + 1) 35 | delta_constant[b + 2] += lst[i] * (b + 1) 36 | delta_linear[b + 2] -= lst[i] 37 | delta_linear[a + b + 2] += lst[i] 38 | delta_constant[a + b + 2] -= lst[i] * (a + 1) 39 | delta_constant[a + b + 2] -= lst[i] * (b + 1) 40 | result = [] 41 | constant = 0 42 | linear = 0 43 | for j in range(1, len(lst) + 1): 44 | constant += delta_constant[j] 45 | linear += delta_linear[j] 46 | result.append(constant + linear * j) 47 | return result 48 | 49 | print(sliding_window_totals([30,30,72,72])) 50 | -------------------------------------------------------------------------------- /Segment Tree - Sum of a given range.py: -------------------------------------------------------------------------------- 1 | from math import log,ceil 2 | class RMQ: 3 | def __init__(self, n): 4 | self.inf = float("inf") 5 | self.low, self.high=0, n-1 6 | self.sz = pow(2, int(ceil(log(n, 2)))) 7 | self.dat = [self.inf] * (2 * self.sz - 1) 8 | 9 | def build(self, arr): 10 | return self.build_help(arr, self.low, self.high, 0) 11 | 12 | def build_help(self, arr, low, high, pos): 13 | if low == high: 14 | self.dat[pos] = arr[low] 15 | return 16 | mid = (low + high) / 2 17 | self.build_help(arr, low, mid, 2*pos+1) 18 | self.build_help(arr, mid+1, high, 2*pos+2) 19 | self.dat[pos] = self.dat[2 * pos + 1]+self.dat[2 * pos + 2] 20 | 21 | def update(self, idx, val): 22 | self.update_help(idx,self.low,self.high,0,val) 23 | 24 | def update_help(self,idx,low,high,pos,val): 25 | if idxhigh: 26 | return 27 | if low==high: 28 | self.dat[pos]=val 29 | return 30 | mid=(low+high)/2 31 | self.update_help(idx,low,mid,2*pos+1,val) 32 | self.update_help(idx,mid+1,high,2*pos+2,val) 33 | self.dat[pos] = self.dat[2 * pos + 1]+self.dat[2 * pos + 2] 34 | 35 | def query(self, qlow, qhigh): 36 | return self.query_help(qlow, qhigh, 0, self.high, 0) 37 | 38 | def query_help(self, qlow, qhigh, low, high, pos): 39 | if qlow <= low and qhigh >= high: #TOTAL OVERLAP 40 | return self.dat[pos] 41 | if qlow > high or qhigh < low: #NO OVERLAP 42 | return 0 43 | mid = (low + high) / 2 44 | #PARTIAL OVERLAP 45 | return self.query_help(qlow, qhigh, low, mid, 2 * pos + 1)+self.query_help(qlow, qhigh, mid+1, high, 2 * pos + 2) 46 | 47 | n=5 48 | li=[-1,2,10,0,-5] 49 | rmq = RMQ(n) 50 | rmq.build(li) 51 | print rmq.query(2,4) 52 | print rmq.query(0,3) 53 | print rmq.query(1,2) 54 | rmq.update(2,-2) 55 | print rmq.query(1,2) 56 | print rmq.query(0,4) 57 | -------------------------------------------------------------------------------- /Segment Tree - Range Minimum Query (RMQ).py: -------------------------------------------------------------------------------- 1 | from math import log,ceil 2 | class RMQ: 3 | def __init__(self, n): 4 | self.inf = float("inf") 5 | self.low, self.high=0, n-1 6 | self.sz = pow(2, int(ceil(log(n, 2)))) 7 | self.dat = [self.inf] * (2 * self.sz - 1) 8 | 9 | def build(self, arr): 10 | return self.build_help(arr, self.low, self.high, 0) 11 | 12 | def build_help(self, arr, low, high, pos): 13 | if low == high: 14 | self.dat[pos] = arr[low] 15 | return 16 | mid = (low + high) / 2 17 | self.build_help(arr, low, mid, 2*pos+1) 18 | self.build_help(arr, mid+1, high, 2*pos+2) 19 | self.dat[pos] = min(self.dat[2 * pos + 1], self.dat[2 * pos + 2]) 20 | 21 | def update(self, idx, val): 22 | self.update_help(idx,self.low,self.high,0,val) 23 | 24 | def update_help(self,idx,low,high,pos,val): 25 | if idxhigh: 26 | return 27 | if low==high: 28 | self.dat[pos]=val 29 | return 30 | mid=(low+high)/2 31 | self.update_help(idx,low,mid,2*pos+1,val) 32 | self.update_help(idx,mid+1,high,2*pos+2,val) 33 | self.dat[pos] = min(self.dat[2 * pos + 1], self.dat[2 * pos + 2]) 34 | 35 | def query(self, qlow, qhigh): 36 | return self.query_help(qlow, qhigh, 0, self.high, 0) 37 | 38 | def query_help(self, qlow, qhigh, low, high, pos): 39 | if qlow <= low and qhigh >= high: #TOTAL OVERLAP 40 | return self.dat[pos] 41 | if qlow > high or qhigh < low: #NO OVERLAP 42 | return float("inf") 43 | mid = (low + high) / 2 44 | #PARTIAL OVERLAP 45 | return min(self.query_help(qlow, qhigh, low, mid, 2 * pos + 1), 46 | self.query_help(qlow, qhigh, mid+1, high, 2 * pos + 2)) 47 | 48 | n=5 49 | li=[-1,2,10,0,-5] 50 | rmq = RMQ(n) 51 | rmq.build(li) 52 | print rmq.query(2,4) 53 | print rmq.query(0,3) 54 | print rmq.query(1,2) 55 | rmq.update(2,-2) 56 | print rmq.query(1,2) 57 | print rmq.query(0,4) 58 | -------------------------------------------------------------------------------- /BST.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | 3 | def __init__(self, data): 4 | self.data = data 5 | self.left = None 6 | self.right = None 7 | 8 | 9 | def insert(root, data): 10 | if root is None: 11 | return Node(data) 12 | else: 13 | if data < root.data: 14 | if root.left is None: 15 | root.left = Node(data) 16 | else: 17 | insert(root.left, data) 18 | else: 19 | if root.right is None: 20 | root.right = Node(data) 21 | else: 22 | insert(root.right, data) 23 | return root 24 | 25 | 26 | def search(root, data): 27 | if root is None: 28 | return False 29 | else: 30 | if data == root.data: 31 | return True 32 | elif data < root.data: 33 | return search(root.left, data) 34 | else: 35 | return search(root.right, data) 36 | 37 | 38 | def findMin(root): 39 | while root.left is not None: 40 | root = root.left 41 | return root 42 | 43 | 44 | def delete(root, data): 45 | if root is None: 46 | return root 47 | else: 48 | if data < root.data: 49 | root.left = delete(root.left, data) 50 | elif data > root.data: 51 | root.right = delete(root.right, data) 52 | else: 53 | if root.left is None: 54 | temp = root.right 55 | root = None 56 | return temp 57 | elif root.right is None: 58 | temp = root.left 59 | root = None 60 | return temp 61 | temp = findMin(root.right) 62 | root.data = temp.data 63 | root.right = delete(root.right, temp.data) 64 | return root 65 | 66 | 67 | def inOrder(root): 68 | if not root: 69 | return 70 | inOrder(root.left) 71 | print root.data 72 | inOrder(root.right) 73 | 74 | 75 | def preOrder(root): 76 | if not root: 77 | return 78 | print root.data 79 | preOrder(root.left) 80 | preOrder(root.right) 81 | 82 | 83 | root = None 84 | root = insert(root, 50) 85 | root = insert(root, 30) 86 | root = insert(root, 20) 87 | root = insert(root, 40) 88 | root = insert(root, 70) 89 | root = insert(root, 60) 90 | root = insert(root, 80) 91 | 92 | print 'Inorder traversal of the given tree' 93 | inOrder(root) 94 | 95 | print '\nDelete 20' 96 | root = delete(root, 20) 97 | print 'Inorder traversal of the modified tree' 98 | inOrder(root) 99 | 100 | print '\nDelete 30' 101 | root = delete(root, 30) 102 | print 'Inorder traversal of the modified tree' 103 | inOrder(root) 104 | 105 | print '\nDelete 50' 106 | root = delete(root, 50) 107 | print 'Inorder traversal of the modified tree' 108 | inOrder(root) 109 | -------------------------------------------------------------------------------- /Lowest Common Ancestor (Optimised).py: -------------------------------------------------------------------------------- 1 | class RangeMin: 2 | def __init__(self,X): 3 | self._data = list(X) 4 | if len(X) > 1: 5 | big = map(max, self._ansv(False), self._ansv(True)) 6 | parents = dict([(i,big[i][1]) for i in range(len(X)) if big[i]]) 7 | self._lca = LCA(parents) 8 | 9 | def __getslice__(self,left,right): 10 | right = min(right, len(self._data)) 11 | if right <= left: 12 | return None 13 | return self._data[self._lca(left,right-1)] 14 | 15 | def __len__(self): 16 | return len(self._data) 17 | 18 | def _ansv(self,reversed): 19 | stack = [None] 20 | output = [0]*len(self._data) 21 | for xi in _pairs(self._data,reversed): 22 | while stack[-1] > xi: 23 | stack.pop() 24 | output[xi[1]] = stack[-1] 25 | stack.append(xi) 26 | return output 27 | 28 | def _lca(self,first,last): 29 | return 0 30 | 31 | class LCA: 32 | def __init__(self,parent): 33 | children = {} 34 | for x in parent: 35 | children.setdefault(parent[x],[]).append(x) 36 | root = [x for x in children if x not in parent] 37 | levels = [] 38 | self._representatives = {} 39 | self._visit(children,levels,root[0],0) 40 | self._rangemin = _RestrictedRangeMin(levels) 41 | 42 | def __call__(self,*nodes): 43 | r = [self._representatives[x] for x in nodes] 44 | return self._rangemin[min(r):max(r)+1][1] 45 | 46 | def _visit(self,children,levels,node,level): 47 | self._representatives[node] = len(levels) 48 | pair = (level,node) 49 | levels.append(pair) 50 | for child in children.get(node,[]): 51 | self._visit(children,levels,child,level+1) 52 | levels.append(pair) 53 | 54 | class _RestrictedRangeMin: 55 | def __init__(self,X): 56 | self._blocksize = _log2(len(X))//2 57 | self._blockmask = (1 << self._blocksize) - 1 58 | blocklen = 1 << self._blocksize 59 | blocks = [] 60 | ids = {} 61 | blockmin = [] 62 | self._prefix = [None] 63 | self._suffix = [] 64 | for i in range(0,len(X),blocklen): 65 | XX = X[i:i+blocklen] 66 | blockmin.append(min(XX)) 67 | self._prefix += _PrefixMinima(XX) 68 | self._suffix += _PrefixMinima(XX,reversed=True) 69 | id = len(XX) < blocklen and -1 or self._blockid(XX) 70 | blocks.append(id) 71 | if id not in ids: 72 | ids[id] = PrecomputedRangeMin(_pairs(XX)) 73 | self._blocks = [ids[b] for b in blocks] 74 | self._blockrange = LogarithmicRangeMin(blockmin) 75 | self._data = list(X) 76 | 77 | def __getslice__(self,left,right): 78 | firstblock = left >> self._blocksize 79 | lastblock = (right - 1) >> self._blocksize 80 | if firstblock == lastblock: 81 | i = left & self._blockmask 82 | position = self._blocks[firstblock][i:i+right-left][1] 83 | return self._data[position + (firstblock << self._blocksize)] 84 | else: 85 | best = min(self._suffix[left], self._prefix[right]) 86 | if lastblock > firstblock + 1: 87 | best = min(best, self._blockrange[firstblock+1:lastblock]) 88 | return best 89 | 90 | def _blockid(self,XX): 91 | id = 0 92 | for i in range(1,len(XX)): 93 | id = id*2 + (XX[i] > XX[i-1]) 94 | return id 95 | 96 | class PrecomputedRangeMin: 97 | 98 | def __init__(self,X): 99 | self._minima = [_PrefixMinima(X[i:]) for i in range(len(X))] 100 | 101 | def __getslice__(self,x,y): 102 | return self._minima[x][y-x-1] 103 | 104 | def __len__(self): 105 | return len(self._minima) 106 | 107 | class LogarithmicRangeMin: 108 | 109 | def __init__(self,X): 110 | self._minima = m = [list(X)] 111 | for j in range(_log2(len(X))): 112 | m.append(map(min, m[-1], m[-1][1<