├── data_structures ├── __init__.py ├── queue │ ├── __init__.py │ ├── deqeue.py │ ├── queue_on_list.py │ └── queue_on_pseudo_stack.py ├── union_find │ └── __init__.py ├── hashing │ ├── number_theory │ │ ├── __init__.py │ │ └── prime_numbers.py │ ├── __init__.py │ ├── quadratic_probing.py │ ├── hash_table_with_linked_list.py │ └── double_hash.py ├── arrays.py ├── stacks │ ├── next.py │ ├── __init__.py │ ├── balanced_parentheses.py │ ├── stock_span_problem.py │ └── postfix_evaluation.py ├── linked_list │ ├── __init__.py │ └── swapNodes.py └── binary tree │ └── fenwick_tree.py ├── digital_image_processing ├── __init__.py └── filters │ ├── __init__.py │ └── median_filter.py ├── .vs ├── slnx.sqlite └── Python │ └── v15 │ └── .suo ├── sorts ├── sorting_graphs.png ├── pancake_sort.py ├── merge_sort_fastest.py ├── wiggle_sort.py ├── radix_sort.py ├── gnome_sort.py ├── quick_sort_3_partition.py ├── topological_sort.py ├── cocktail_shaker_sort.py ├── tree_sort.py ├── bubble_sort.py ├── insertion_sort.py ├── bogosort.py ├── quick_sort.py ├── selection_sort.py ├── shell_sort.py ├── random_normal_distribution_quicksort.py ├── comb_sort.py ├── BitonicSort.py ├── cyclesort.py └── heap_sort.py ├── ciphers ├── prehistoric_men.txt ├── base16.py ├── base32.py ├── base85.py ├── cryptomath_module.py ├── rot13.py ├── onepad_cipher.py ├── transposition_cipher_encrypt_decrypt_file.py ├── transposition_cipher.py ├── rsa_key_generator.py ├── base64_cipher.py └── vigenere_cipher.py ├── other ├── game_of_life │ └── sample.gif ├── euclidean_gcd.py ├── fischer_yates_shuffle.py ├── palindrome.py ├── tower_of_hanoi.py ├── two_sum.py ├── findingPrimes.py ├── anagrams.py ├── word_patterns.py ├── password_generator.py ├── linear_congruential_generator.py ├── binary_exponentiation.py ├── binary_exponentiation_2.py ├── nested_brackets.py └── detecting_english_programmatically.py ├── searches ├── tabu_test_data.txt ├── jump_search.py ├── quick_select.py ├── linear_search.py └── sentinel_linear_search.py ├── simple_client ├── README.md ├── server.py └── client.py ├── analysis └── compression_analysis │ ├── example_image.jpg │ ├── original_image.png │ ├── PSNR-example-base.png │ ├── compressed_image.png │ ├── PSNR-example-comp-10.jpg │ ├── example_wikipedia_image.jpg │ └── psnr.py ├── project_euler ├── problem_20 │ ├── sol2.py │ └── sol1.py ├── problem_24 │ └── sol1.py ├── problem_09 │ ├── sol3.py │ ├── sol1.py │ └── sol2.py ├── problem_25 │ ├── sol2.py │ └── sol1.py ├── problem_08 │ ├── sol2.py │ └── sol1.py ├── problem_12 │ ├── sol2.py │ └── sol1.py ├── problem_16 │ └── sol1.py ├── problem_13 │ └── sol1.py ├── problem_48 │ └── sol1.py ├── problem_02 │ ├── sol2.py │ ├── sol3.py │ └── sol1.py ├── problem_03 │ ├── sol2.py │ └── sol1.py ├── problem_01 │ ├── sol1.py │ ├── sol5.py │ ├── sol2.py │ ├── sol4.py │ └── sol3.py ├── problem_07 │ ├── sol2.py │ ├── sol1.py │ └── sol3.py ├── problem_15 │ └── sol1.py ├── problem_14 │ ├── sol1.py │ └── sol2.py ├── problem_05 │ ├── sol1.py │ └── sol2.py ├── problem_04 │ ├── sol2.py │ └── sol1.py ├── problem_28 │ └── sol1.py ├── problem_52 │ └── sol1.py ├── problem_10 │ ├── sol2.py │ └── sol1.py ├── problem_06 │ ├── sol2.py │ ├── sol1.py │ └── sol3.py ├── problem_36 │ └── sol1.py ├── problem_40 │ └── sol1.py ├── problem_76 │ └── sol1.py ├── problem_53 │ └── sol1.py ├── problem_11 │ ├── sol2.py │ └── grid.txt ├── problem_29 │ └── solution.py ├── problem_21 │ └── sol1.py ├── problem_22 │ └── sol1.py ├── problem_19 │ └── sol1.py ├── problem_31 │ └── sol1.py └── problem_17 │ └── sol1.py ├── Maths ├── FindMax.py ├── average.py ├── FindMin.py ├── abs.py ├── absMin.py ├── find_lcm.py ├── absMax.py ├── 3n+1.py └── extended_euclidean_algorithm.py ├── machine_learning └── Random Forest Regression │ ├── Position_Salaries.csv │ └── random_forest_regression.py ├── maths ├── PrimeCheck.py ├── modular_exponential.py ├── greater_common_divisor.py ├── factorial_python.py ├── sieve_of_eratosthenes.py ├── fibonacci_sequence_recursion.py ├── trapezoidal_rule.py ├── simpson_rule.py ├── segmented_sieve.py ├── basic_maths.py └── newton_raphson.py ├── dynamic_programming ├── FractionalKnapsack.py ├── minimum_partition.py ├── abbreviation.py ├── longest_increasing_subsequence_O(nlogn).py ├── coin_change.py ├── longest_sub_array.py ├── longest_common_subsequence.py ├── floyd_warshall.py ├── integer_partition.py ├── fastfibonacci.py ├── knapsack.py ├── longest_increasing_subsequence.py ├── matrix_chain_order.py └── fibonacci.py ├── arithmetic_analysis ├── newton_method.py ├── intersection.py ├── lu_decomposition.py ├── newton_raphson_method.py └── bisection.py ├── .lgtm.yml ├── Graphs ├── graph_matrix.py ├── graph_list.py ├── kahns_algorithm_long.py ├── kahns_algorithm_topo.py ├── minimum_spanning_tree_kruskal.py ├── BFS.py ├── finding_bridges.py ├── scc_kosaraju.py ├── graph.py ├── DFS.py ├── floyd_warshall.py ├── articulation_points.py ├── check_bipartite_graph_bfs.py ├── bellman_ford.py ├── dijkstra_2.py ├── dijkstra.py ├── even_tree.py ├── depth_first_search.py └── breadth_first_search.py ├── matrix └── searching_in_sorted_matrix.py ├── strings ├── naiveStringSearch.py └── rabin_karp.py ├── .travis.yml ├── License ├── file_transfer_protocol ├── ftp_send_receive.py └── ftp_client_server.py ├── .gitignore ├── binary_tree └── basic_binary_tree.py └── networking_flow ├── ford_fulkerson.py └── minimum_cut.py /data_structures/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data_structures/queue/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data_structures/union_find/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /digital_image_processing/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /digital_image_processing/filters/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data_structures/hashing/number_theory/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.vs/slnx.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/subbarayudu-j/TheAlgorithms-Python/HEAD/.vs/slnx.sqlite -------------------------------------------------------------------------------- /.vs/Python/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/subbarayudu-j/TheAlgorithms-Python/HEAD/.vs/Python/v15/.suo -------------------------------------------------------------------------------- /sorts/sorting_graphs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/subbarayudu-j/TheAlgorithms-Python/HEAD/sorts/sorting_graphs.png -------------------------------------------------------------------------------- /data_structures/arrays.py: -------------------------------------------------------------------------------- 1 | arr = [10, 20, 30, 40] 2 | arr[1] = 30 # set element 1 (20) of array to 30 3 | print(arr) 4 | -------------------------------------------------------------------------------- /ciphers/prehistoric_men.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/subbarayudu-j/TheAlgorithms-Python/HEAD/ciphers/prehistoric_men.txt -------------------------------------------------------------------------------- /other/game_of_life/sample.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/subbarayudu-j/TheAlgorithms-Python/HEAD/other/game_of_life/sample.gif -------------------------------------------------------------------------------- /searches/tabu_test_data.txt: -------------------------------------------------------------------------------- 1 | a b 20 2 | a c 18 3 | a d 22 4 | a e 26 5 | b c 10 6 | b d 11 7 | b e 12 8 | c d 23 9 | c e 24 10 | d e 40 11 | -------------------------------------------------------------------------------- /simple_client/README.md: -------------------------------------------------------------------------------- 1 | # simple client server 2 | 3 | #### Note: 4 | - Run **`server.py`** first. 5 | - Now, run **`client.py`**. 6 | - verify the output. 7 | -------------------------------------------------------------------------------- /analysis/compression_analysis/example_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/subbarayudu-j/TheAlgorithms-Python/HEAD/analysis/compression_analysis/example_image.jpg -------------------------------------------------------------------------------- /analysis/compression_analysis/original_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/subbarayudu-j/TheAlgorithms-Python/HEAD/analysis/compression_analysis/original_image.png -------------------------------------------------------------------------------- /analysis/compression_analysis/PSNR-example-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/subbarayudu-j/TheAlgorithms-Python/HEAD/analysis/compression_analysis/PSNR-example-base.png -------------------------------------------------------------------------------- /analysis/compression_analysis/compressed_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/subbarayudu-j/TheAlgorithms-Python/HEAD/analysis/compression_analysis/compressed_image.png -------------------------------------------------------------------------------- /project_euler/problem_20/sol2.py: -------------------------------------------------------------------------------- 1 | from math import factorial 2 | def main(): 3 | print(sum([int(x) for x in str(factorial(100))])) 4 | if __name__ == '__main__': 5 | main() -------------------------------------------------------------------------------- /analysis/compression_analysis/PSNR-example-comp-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/subbarayudu-j/TheAlgorithms-Python/HEAD/analysis/compression_analysis/PSNR-example-comp-10.jpg -------------------------------------------------------------------------------- /analysis/compression_analysis/example_wikipedia_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/subbarayudu-j/TheAlgorithms-Python/HEAD/analysis/compression_analysis/example_wikipedia_image.jpg -------------------------------------------------------------------------------- /data_structures/hashing/__init__.py: -------------------------------------------------------------------------------- 1 | from .hash_table import HashTable 2 | 3 | class QuadraticProbing(HashTable): 4 | 5 | def __init__(self): 6 | super(self.__class__, self).__init__() 7 | -------------------------------------------------------------------------------- /project_euler/problem_24/sol1.py: -------------------------------------------------------------------------------- 1 | from itertools import permutations 2 | def main(): 3 | result=list(map("".join, permutations('0123456789'))) 4 | print(result[999999]) 5 | 6 | if __name__ == '__main__': 7 | main() -------------------------------------------------------------------------------- /project_euler/problem_09/sol3.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | print([a*b*c for a in range(1,999) for b in range(a,999) for c in range(b,999) 3 | if (a*a+b*b==c*c) and (a+b+c==1000 ) ][0]) 4 | 5 | if __name__ == '__main__': 6 | main() 7 | -------------------------------------------------------------------------------- /project_euler/problem_25/sol2.py: -------------------------------------------------------------------------------- 1 | def fibonacci_genrator(): 2 | a, b = 0,1 3 | while True: 4 | a,b = b,a+b 5 | yield b 6 | answer = 1 7 | gen = fibonacci_genrator() 8 | while len(str(next(gen))) < 1000: 9 | answer += 1 10 | assert answer+1 == 4782 11 | -------------------------------------------------------------------------------- /project_euler/problem_08/sol2.py: -------------------------------------------------------------------------------- 1 | from functools import reduce 2 | 3 | def main(): 4 | number=input().strip() 5 | print(max([reduce(lambda x,y: int(x)*int(y),number[i:i+13]) for i in range(len(number)-12)])) 6 | 7 | if __name__ == '__main__': 8 | main() 9 | -------------------------------------------------------------------------------- /Maths/FindMax.py: -------------------------------------------------------------------------------- 1 | # NguyenU 2 | 3 | def find_max(nums): 4 | max = nums[0] 5 | for x in nums: 6 | if x > max: 7 | max = x 8 | print(max) 9 | 10 | def main(): 11 | find_max([2, 4, 9, 7, 19, 94, 5]) 12 | 13 | if __name__ == '__main__': 14 | main() 15 | -------------------------------------------------------------------------------- /Maths/average.py: -------------------------------------------------------------------------------- 1 | def average(nums): 2 | sum = 0 3 | n = 0 4 | for x in nums: 5 | sum += x 6 | n += 1 7 | avg = sum / n 8 | print(avg) 9 | 10 | def main(): 11 | average([2, 4, 6, 8, 20, 50, 70]) 12 | 13 | if __name__ == '__main__': 14 | main() 15 | -------------------------------------------------------------------------------- /Maths/FindMin.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | def findMin(x): 3 | minNum = x[0] 4 | for i in x: 5 | if minNum > i: 6 | minNum = i 7 | return minNum 8 | 9 | print(findMin([0,1,2,3,4,5,-3,24,-56])) # = -56 10 | 11 | if __name__ == '__main__': 12 | main() 13 | -------------------------------------------------------------------------------- /project_euler/problem_12/sol2.py: -------------------------------------------------------------------------------- 1 | def triangle_number_generator(): 2 | for n in range(1,1000000): 3 | yield n*(n+1)//2 4 | 5 | def count_divisors(n): 6 | return sum([2 for i in range(1,int(n**0.5)+1) if n%i==0 and i*i != n]) 7 | 8 | print(next(i for i in triangle_number_generator() if count_divisors(i) > 500)) 9 | -------------------------------------------------------------------------------- /machine_learning/Random Forest Regression/Position_Salaries.csv: -------------------------------------------------------------------------------- 1 | Position,Level,Salary 2 | Business Analyst,1,45000 3 | Junior Consultant,2,50000 4 | Senior Consultant,3,60000 5 | Manager,4,80000 6 | Country Manager,5,110000 7 | Region Manager,6,150000 8 | Partner,7,200000 9 | Senior Partner,8,300000 10 | C-level,9,500000 11 | CEO,10,1000000 -------------------------------------------------------------------------------- /project_euler/problem_16/sol1.py: -------------------------------------------------------------------------------- 1 | power = int(input("Enter the power of 2: ")) 2 | num = 2**power 3 | 4 | string_num = str(num) 5 | 6 | list_num = list(string_num) 7 | 8 | sum_of_num = 0 9 | 10 | print("2 ^",power,"=",num) 11 | 12 | for i in list_num: 13 | sum_of_num += int(i) 14 | 15 | print("Sum of the digits are:",sum_of_num) 16 | -------------------------------------------------------------------------------- /project_euler/problem_13/sol1.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Problem Statement: 3 | Work out the first ten digits of the sum of the N 50-digit numbers. 4 | ''' 5 | from __future__ import print_function 6 | 7 | n = int(input().strip()) 8 | 9 | array = [] 10 | for i in range(n): 11 | array.append(int(input().strip())) 12 | 13 | print(str(sum(array))[:10]) 14 | 15 | -------------------------------------------------------------------------------- /Maths/abs.py: -------------------------------------------------------------------------------- 1 | def absVal(num): 2 | """ 3 | Function to fins absolute value of numbers. 4 | >>absVal(-5) 5 | 5 6 | >>absVal(0) 7 | 0 8 | """ 9 | if num < 0: 10 | return -num 11 | else: 12 | return num 13 | 14 | def main(): 15 | print(absVal(-34)) # = 34 16 | 17 | if __name__ == '__main__': 18 | main() 19 | -------------------------------------------------------------------------------- /maths/PrimeCheck.py: -------------------------------------------------------------------------------- 1 | import math 2 | def primeCheck(number): 3 | if number % 2 == 0 and number > 2: 4 | return False 5 | return all(number % i for i in range(3, int(math.sqrt(number)) + 1, 2)) 6 | 7 | def main(): 8 | print(primeCheck(37)) 9 | print(primeCheck(100)) 10 | print(primeCheck(77)) 11 | 12 | if __name__ == '__main__': 13 | main() 14 | -------------------------------------------------------------------------------- /ciphers/base16.py: -------------------------------------------------------------------------------- 1 | import base64 2 | 3 | def main(): 4 | inp = input('->') 5 | encoded = inp.encode('utf-8') #encoded the input (we need a bytes like object) 6 | b16encoded = base64.b16encode(encoded) #b16encoded the encoded string 7 | print(b16encoded) 8 | print(base64.b16decode(b16encoded).decode('utf-8'))#decoded it 9 | 10 | if __name__ == '__main__': 11 | main() 12 | -------------------------------------------------------------------------------- /ciphers/base32.py: -------------------------------------------------------------------------------- 1 | import base64 2 | 3 | def main(): 4 | inp = input('->') 5 | encoded = inp.encode('utf-8') #encoded the input (we need a bytes like object) 6 | b32encoded = base64.b32encode(encoded) #b32encoded the encoded string 7 | print(b32encoded) 8 | print(base64.b32decode(b32encoded).decode('utf-8'))#decoded it 9 | 10 | if __name__ == '__main__': 11 | main() 12 | -------------------------------------------------------------------------------- /ciphers/base85.py: -------------------------------------------------------------------------------- 1 | import base64 2 | 3 | def main(): 4 | inp = input('->') 5 | encoded = inp.encode('utf-8') #encoded the input (we need a bytes like object) 6 | a85encoded = base64.a85encode(encoded) #a85encoded the encoded string 7 | print(a85encoded) 8 | print(base64.a85decode(a85encoded).decode('utf-8'))#decoded it 9 | 10 | if __name__ == '__main__': 11 | main() 12 | -------------------------------------------------------------------------------- /Maths/absMin.py: -------------------------------------------------------------------------------- 1 | from Maths.abs import absVal 2 | def absMin(x): 3 | """ 4 | # >>>absMin([0,5,1,11]) 5 | 0 6 | # >>absMin([3,-10,-2]) 7 | -2 8 | """ 9 | j = x[0] 10 | for i in x: 11 | if absVal(i) < absVal(j): 12 | j = i 13 | return j 14 | 15 | def main(): 16 | a = [-3,-1,2,-11] 17 | print(absMin(a)) # = -1 18 | 19 | if __name__ == '__main__': 20 | main() -------------------------------------------------------------------------------- /Maths/find_lcm.py: -------------------------------------------------------------------------------- 1 | def find_lcm(num_1, num_2): 2 | max = num_1 if num_1 > num_2 else num_2 3 | lcm = max 4 | while (True): 5 | if ((lcm % num_1 == 0) and (lcm % num_2 == 0)): 6 | break 7 | lcm += max 8 | return lcm 9 | 10 | 11 | def main(): 12 | num_1 = 12 13 | num_2 = 76 14 | print(find_lcm(num_1, num_2)) 15 | 16 | 17 | if __name__ == '__main__': 18 | main() 19 | -------------------------------------------------------------------------------- /ciphers/cryptomath_module.py: -------------------------------------------------------------------------------- 1 | def gcd(a, b): 2 | while a != 0: 3 | a, b = b % a, a 4 | return b 5 | 6 | def findModInverse(a, m): 7 | if gcd(a, m) != 1: 8 | return None 9 | u1, u2, u3 = 1, 0, a 10 | v1, v2, v3 = 0, 1, m 11 | while v3 != 0: 12 | q = u3 // v3 13 | v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q *v3), v1, v2, v3 14 | return u1 % m 15 | -------------------------------------------------------------------------------- /maths/modular_exponential.py: -------------------------------------------------------------------------------- 1 | def modularExponential(base, power, mod): 2 | if power < 0: 3 | return -1 4 | base %= mod 5 | result = 1 6 | 7 | while power > 0: 8 | if power & 1: 9 | result = (result * base) % mod 10 | power = power >> 1 11 | base = (base * base) % mod 12 | return result 13 | 14 | 15 | def main(): 16 | print(modularExponential(3, 200, 13)) 17 | 18 | 19 | if __name__ == '__main__': 20 | main() 21 | -------------------------------------------------------------------------------- /Maths/absMax.py: -------------------------------------------------------------------------------- 1 | def absMax(x): 2 | """ 3 | #>>>absMax([0,5,1,11]) 4 | 11 5 | >>absMax([3,-10,-2]) 6 | -10 7 | """ 8 | j =x[0] 9 | for i in x: 10 | if abs(i) > abs(j): 11 | j = i 12 | return j 13 | 14 | 15 | def main(): 16 | a = [1,2,-11] 17 | print(absMax(a)) # = -11 18 | 19 | 20 | if __name__ == '__main__': 21 | main() 22 | 23 | """ 24 | print abs Max 25 | """ 26 | -------------------------------------------------------------------------------- /project_euler/problem_48/sol1.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | ''' 3 | Self Powers 4 | Problem 48 5 | 6 | The series, 11 + 22 + 33 + ... + 1010 = 10405071317. 7 | 8 | Find the last ten digits of the series, 11 + 22 + 33 + ... + 10001000. 9 | ''' 10 | 11 | try: 12 | xrange 13 | except NameError: 14 | xrange = range 15 | 16 | total = 0 17 | for i in xrange(1, 1001): 18 | total += i**i 19 | 20 | 21 | print(str(total)[-10:]) -------------------------------------------------------------------------------- /project_euler/problem_08/sol1.py: -------------------------------------------------------------------------------- 1 | import sys 2 | def main(): 3 | LargestProduct = -sys.maxsize-1 4 | number=input().strip() 5 | for i in range(len(number)-12): 6 | product=1 7 | for j in range(13): 8 | product *= int(number[i+j]) 9 | if product > LargestProduct: 10 | LargestProduct = product 11 | print(LargestProduct) 12 | 13 | 14 | if __name__ == '__main__': 15 | main() 16 | -------------------------------------------------------------------------------- /project_euler/problem_02/sol2.py: -------------------------------------------------------------------------------- 1 | def fib(n): 2 | """ 3 | Returns a list of all the even terms in the Fibonacci sequence that are less than n. 4 | """ 5 | ls = [] 6 | a, b = 0, 1 7 | while b < n: 8 | if b % 2 == 0: 9 | ls.append(b) 10 | a, b = b, a+b 11 | return ls 12 | 13 | if __name__ == '__main__': 14 | n = int(input("Enter max number: ").strip()) 15 | print(sum(fib(n))) 16 | -------------------------------------------------------------------------------- /project_euler/problem_03/sol2.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Problem: 3 | The prime factors of 13195 are 5,7,13 and 29. What is the largest prime factor of a given number N? 4 | e.g. for 10, largest prime factor = 5. For 17, largest prime factor = 17. 5 | ''' 6 | 7 | from __future__ import print_function 8 | n=int(input()) 9 | prime=1 10 | i=2 11 | while(i*i<=n): 12 | while(n%i==0): 13 | prime=i 14 | n//=i 15 | i+=1 16 | if(n>1): 17 | prime=n 18 | print(prime) 19 | -------------------------------------------------------------------------------- /dynamic_programming/FractionalKnapsack.py: -------------------------------------------------------------------------------- 1 | from itertools import accumulate 2 | from bisect import bisect 3 | 4 | def fracKnapsack(vl, wt, W, n): 5 | 6 | r = list(sorted(zip(vl,wt), key=lambda x:x[0]/x[1],reverse=True)) 7 | vl , wt = [i[0] for i in r],[i[1] for i in r] 8 | acc=list(accumulate(wt)) 9 | k = bisect(acc,W) 10 | return 0 if k == 0 else sum(vl[:k])+(W-acc[k-1])*(vl[k])/(wt[k]) if k!=n else sum(vl[:k]) 11 | 12 | print("%.0f"%fracKnapsack([60, 100, 120],[10, 20, 30],50,3)) 13 | -------------------------------------------------------------------------------- /sorts/pancake_sort.py: -------------------------------------------------------------------------------- 1 | # Pancake sort algorithm 2 | # Only can reverse array from 0 to i 3 | 4 | def pancakesort(arr): 5 | cur = len(arr) 6 | while cur > 1: 7 | # Find the maximum number in arr 8 | mi = arr.index(max(arr[0:cur])) 9 | # Reverse from 0 to mi 10 | arr = arr[mi::-1] + arr[mi+1:len(arr)] 11 | # Reverse whole list 12 | arr = arr[cur-1::-1] + arr[cur:len(arr)] 13 | cur -= 1 14 | return arr 15 | 16 | print(pancakesort([0,10,15,3,2,9,14,13])) 17 | -------------------------------------------------------------------------------- /data_structures/stacks/next.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | # Function to print element and NGE pair for all elements of list 3 | def printNGE(arr): 4 | 5 | for i in range(0, len(arr), 1): 6 | 7 | next = -1 8 | for j in range(i+1, len(arr), 1): 9 | if arr[i] < arr[j]: 10 | next = arr[j] 11 | break 12 | 13 | print(str(arr[i]) + " -- " + str(next)) 14 | 15 | # Driver program to test above function 16 | arr = [11,13,21,3] 17 | printNGE(arr) 18 | -------------------------------------------------------------------------------- /project_euler/problem_01/sol1.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Problem Statement: 3 | If we list all the natural numbers below 10 that are multiples of 3 or 5, 4 | we get 3,5,6 and 9. The sum of these multiples is 23. 5 | Find the sum of all the multiples of 3 or 5 below N. 6 | ''' 7 | from __future__ import print_function 8 | try: 9 | raw_input # Python 2 10 | except NameError: 11 | raw_input = input # Python 3 12 | n = int(raw_input().strip()) 13 | sum=0 14 | for a in range(3,n): 15 | if(a%3==0 or a%5==0): 16 | sum+=a 17 | print(sum) 18 | -------------------------------------------------------------------------------- /arithmetic_analysis/newton_method.py: -------------------------------------------------------------------------------- 1 | # Newton's Method - https://en.wikipedia.org/wiki/Newton%27s_method 2 | 3 | def newton(function,function1,startingInt): #function is the f(x) and function1 is the f'(x) 4 | x_n=startingInt 5 | while True: 6 | x_n1=x_n-function(x_n)/function1(x_n) 7 | if abs(x_n-x_n1) < 10**-5: 8 | return x_n1 9 | x_n=x_n1 10 | 11 | def f(x): 12 | return (x**3) - (2 * x) -5 13 | 14 | def f1(x): 15 | return 3 * (x**2) -2 16 | 17 | if __name__ == "__main__": 18 | print(newton(f,f1,3)) 19 | -------------------------------------------------------------------------------- /maths/greater_common_divisor.py: -------------------------------------------------------------------------------- 1 | # Greater Common Divisor - https://en.wikipedia.org/wiki/Greatest_common_divisor 2 | def gcd(a, b): 3 | return b if a == 0 else gcd(b % a, a) 4 | 5 | def main(): 6 | try: 7 | nums = input("Enter two Integers separated by comma (,): ").split(',') 8 | num1 = int(nums[0]); num2 = int(nums[1]) 9 | except (IndexError, UnboundLocalError, ValueError): 10 | print("Wrong Input") 11 | print(f"gcd({num1}, {num2}) = {gcd(num1, num2)}") 12 | 13 | if __name__ == '__main__': 14 | main() 15 | 16 | -------------------------------------------------------------------------------- /Maths/3n+1.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | def n31(a):# a = initial number 3 | c = 0 4 | l = [a] 5 | while a != 1: 6 | if a % 2 == 0:#if even divide it by 2 7 | a = a // 2 8 | elif a % 2 == 1:#if odd 3n+1 9 | a = 3*a +1 10 | c += 1#counter 11 | l += [a] 12 | 13 | return l , c 14 | print(n31(43)) 15 | print(n31(98)[0][-1])# = a 16 | print("It took {0} steps.".format(n31(13)[1]))#optional finish 17 | 18 | if __name__ == '__main__': 19 | main() 20 | -------------------------------------------------------------------------------- /data_structures/stacks/__init__.py: -------------------------------------------------------------------------------- 1 | class Stack: 2 | 3 | def __init__(self): 4 | self.stack = [] 5 | self.top = 0 6 | 7 | def is_empty(self): 8 | return (self.top == 0) 9 | 10 | def push(self, item): 11 | if self.top < len(self.stack): 12 | self.stack[self.top] = item 13 | else: 14 | self.stack.append(item) 15 | 16 | self.top += 1 17 | 18 | def pop(self): 19 | if self.is_empty(): 20 | return None 21 | else: 22 | self.top -= 1 23 | return self.stack[self.top] 24 | -------------------------------------------------------------------------------- /arithmetic_analysis/intersection.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | def intersection(function,x0,x1): #function is the f we want to find its root and x0 and x1 are two random starting points 4 | x_n = x0 5 | x_n1 = x1 6 | while True: 7 | x_n2 = x_n1-(function(x_n1)/((function(x_n1)-function(x_n))/(x_n1-x_n))) 8 | if abs(x_n2 - x_n1) < 10**-5: 9 | return x_n2 10 | x_n=x_n1 11 | x_n1=x_n2 12 | 13 | def f(x): 14 | return math.pow(x , 3) - (2 * x) -5 15 | 16 | if __name__ == "__main__": 17 | print(intersection(f,3,3.5)) 18 | -------------------------------------------------------------------------------- /project_euler/problem_01/sol5.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Problem Statement: 3 | If we list all the natural numbers below 10 that are multiples of 3 or 5, 4 | we get 3,5,6 and 9. The sum of these multiples is 23. 5 | Find the sum of all the multiples of 3 or 5 below N. 6 | ''' 7 | from __future__ import print_function 8 | try: 9 | input = raw_input #python3 10 | except NameError: 11 | pass #python 2 12 | 13 | """A straightforward pythonic solution using list comprehension""" 14 | n = int(input().strip()) 15 | print(sum([i for i in range(n) if i%3==0 or i%5==0])) 16 | 17 | -------------------------------------------------------------------------------- /sorts/merge_sort_fastest.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Python implementation of merge sort algorithm. 3 | Takes an average of 0.6 microseconds to sort a list of length 1000 items. 4 | Best Case Scenario : O(n) 5 | Worst Case Scenario : O(n) 6 | ''' 7 | def merge_sort(LIST): 8 | start = [] 9 | end = [] 10 | while len(LIST) > 1: 11 | a = min(LIST) 12 | b = max(LIST) 13 | start.append(a) 14 | end.append(b) 15 | LIST.remove(a) 16 | LIST.remove(b) 17 | if LIST: start.append(LIST[0]) 18 | end.reverse() 19 | return (start + end) 20 | -------------------------------------------------------------------------------- /project_euler/problem_07/sol2.py: -------------------------------------------------------------------------------- 1 | # By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. What is the Nth prime number? 2 | def isprime(number): 3 | for i in range(2,int(number**0.5)+1): 4 | if number%i==0: 5 | return False 6 | return True 7 | n = int(input('Enter The N\'th Prime Number You Want To Get: ')) # Ask For The N'th Prime Number Wanted 8 | primes = [] 9 | num = 2 10 | while len(primes) < n: 11 | if isprime(num): 12 | primes.append(num) 13 | num += 1 14 | else: 15 | num += 1 16 | print(primes[len(primes) - 1]) 17 | -------------------------------------------------------------------------------- /project_euler/problem_15/sol1.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from math import factorial 3 | 4 | def lattice_paths(n): 5 | n = 2*n #middle entry of odd rows starting at row 3 is the solution for n = 1, 2, 3,... 6 | k = n/2 7 | 8 | return factorial(n)/(factorial(k)*factorial(n-k)) 9 | 10 | if __name__ == '__main__': 11 | import sys 12 | 13 | if len(sys.argv) == 1: 14 | print(lattice_paths(20)) 15 | else: 16 | try: 17 | n = int(sys.argv[1]) 18 | print(lattice_paths(n)) 19 | except ValueError: 20 | print('Invalid entry - please enter a number.') 21 | -------------------------------------------------------------------------------- /simple_client/server.py: -------------------------------------------------------------------------------- 1 | # server.py 2 | 3 | import socket 4 | 5 | HOST, PORT = '127.0.0.1', 1400 6 | 7 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#refer to client.py 8 | s.bind((HOST, PORT)) 9 | s.listen(1)#listen for 1 connection 10 | 11 | conn, addr = s.accept()#start the actual data flow 12 | 13 | print('connected to:', addr) 14 | 15 | while 1: 16 | data = conn.recv(1024).decode('ascii')#receive 1024 bytes and decode using ascii 17 | if not data: 18 | break 19 | conn.send((data + ' [ addition by server ]').encode('ascii')) 20 | 21 | conn.close() 22 | -------------------------------------------------------------------------------- /other/euclidean_gcd.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | # https://en.wikipedia.org/wiki/Euclidean_algorithm 3 | 4 | def euclidean_gcd(a, b): 5 | while b: 6 | t = b 7 | b = a % b 8 | a = t 9 | return a 10 | 11 | def main(): 12 | print("GCD(3, 5) = " + str(euclidean_gcd(3, 5))) 13 | print("GCD(5, 3) = " + str(euclidean_gcd(5, 3))) 14 | print("GCD(1, 3) = " + str(euclidean_gcd(1, 3))) 15 | print("GCD(3, 6) = " + str(euclidean_gcd(3, 6))) 16 | print("GCD(6, 3) = " + str(euclidean_gcd(6, 3))) 17 | 18 | if __name__ == '__main__': 19 | main() 20 | -------------------------------------------------------------------------------- /project_euler/problem_09/sol1.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | # Program to find the product of a,b,c which are Pythagorean Triplet that satisfice the following: 3 | # 1. a < b < c 4 | # 2. a**2 + b**2 = c**2 5 | # 3. a + b + c = 1000 6 | 7 | print("Please Wait...") 8 | for a in range(300): 9 | for b in range(400): 10 | for c in range(500): 11 | if(a < b < c): 12 | if((a**2) + (b**2) == (c**2)): 13 | if((a+b+c) == 1000): 14 | print(("Product of",a,"*",b,"*",c,"=",(a*b*c))) 15 | break 16 | -------------------------------------------------------------------------------- /project_euler/problem_14/sol1.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | largest_number = 0 3 | pre_counter = 0 4 | 5 | for input1 in range(750000,1000000): 6 | counter = 1 7 | number = input1 8 | 9 | while number > 1: 10 | if number % 2 == 0: 11 | number /=2 12 | counter += 1 13 | else: 14 | number = (3*number)+1 15 | counter += 1 16 | 17 | if counter > pre_counter: 18 | largest_number = input1 19 | pre_counter = counter 20 | 21 | print(('Largest Number:',largest_number,'->',pre_counter,'digits')) 22 | -------------------------------------------------------------------------------- /data_structures/linked_list/__init__.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, item, next): 3 | self.item = item 4 | self.next = next 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def add(self, item): 11 | self.head = Node(item, self.head) 12 | 13 | def remove(self): 14 | if self.is_empty(): 15 | return None 16 | else: 17 | item = self.head.item 18 | self.head = self.head.next 19 | return item 20 | 21 | def is_empty(self): 22 | return self.head is None 23 | -------------------------------------------------------------------------------- /project_euler/problem_02/sol3.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Problem: 3 | Each new term in the Fibonacci sequence is generated by adding the previous two terms. 4 | 0,1,1,2,3,5,8,13,21,34,55,89,.. 5 | Every third term from 0 is even So using this I have written a simple code 6 | By considering the terms in the Fibonacci sequence whose values do not exceed n, find the sum of the even-valued terms. 7 | e.g. for n=10, we have {2,8}, sum is 10. 8 | ''' 9 | """Python 3""" 10 | n = int(input()) 11 | a=0 12 | b=2 13 | count=0 14 | while 4*b+a= 'A' and c <= 'Z': 6 | out += chr(ord('A') + (ord(c) - ord('A') + n) % 26) 7 | elif c >= 'a' and c <= 'z': 8 | out += chr(ord('a') + (ord(c) - ord('a') + n) % 26) 9 | else: 10 | out += c 11 | return out 12 | 13 | 14 | def main(): 15 | s0 = 'HELLO' 16 | 17 | s1 = dencrypt(s0, 13) 18 | print(s1) # URYYB 19 | 20 | s2 = dencrypt(s1, 13) 21 | print(s2) # HELLO 22 | 23 | 24 | if __name__ == '__main__': 25 | main() 26 | -------------------------------------------------------------------------------- /project_euler/problem_05/sol1.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Problem: 3 | 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. 4 | What is the smallest positive number that is evenly divisible(divisible with no remainder) by all of the numbers from 1 to N? 5 | ''' 6 | from __future__ import print_function 7 | 8 | n = int(input()) 9 | i = 0 10 | while 1: 11 | i+=n*(n-1) 12 | nfound=0 13 | for j in range(2,n): 14 | if (i%j != 0): 15 | nfound=1 16 | break 17 | if(nfound==0): 18 | if(i==0): 19 | i=1 20 | print(i) 21 | break 22 | -------------------------------------------------------------------------------- /.lgtm.yml: -------------------------------------------------------------------------------- 1 | extraction: 2 | python: 3 | python_setup: 4 | version: 3 5 | after_prepare: 6 | - python3 -m pip install --upgrade --user flake8 7 | before_index: 8 | - python3 -m flake8 --version # flake8 3.6.0 on CPython 3.6.5 on Linux 9 | # stop the build if there are Python syntax errors or undefined names 10 | - python3 -m flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics 11 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 12 | - python3 -m flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics 13 | -------------------------------------------------------------------------------- /project_euler/problem_04/sol2.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Problem: 3 | A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 x 99. 4 | Find the largest palindrome made from the product of two 3-digit numbers which is less than N. 5 | ''' 6 | from __future__ import print_function 7 | n = int(input().strip()) 8 | answer = 0 9 | for i in range(999,99,-1): #3 digit nimbers range from 999 down to 100 10 | for j in range(999,99,-1): 11 | t = str(i*j) 12 | if t == t[::-1] and i*j < n: 13 | answer = max(answer,i*j) 14 | print(answer) 15 | exit(0) 16 | 17 | 18 | -------------------------------------------------------------------------------- /project_euler/problem_05/sol2.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | ''' 3 | Problem: 4 | 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. 5 | What is the smallest positive number that is evenly divisible(divisible with no remainder) by all of the numbers from 1 to N? 6 | ''' 7 | 8 | """ Euclidean GCD Algorithm """ 9 | def gcd(x,y): 10 | return x if y==0 else gcd(y,x%y) 11 | 12 | """ Using the property lcm*gcd of two numbers = product of them """ 13 | def lcm(x,y): 14 | return (x*y)//gcd(x,y) 15 | 16 | n = int(input()) 17 | g=1 18 | for i in range(1,n+1): 19 | g=lcm(g,i) 20 | print(g) 21 | -------------------------------------------------------------------------------- /maths/sieve_of_eratosthenes.py: -------------------------------------------------------------------------------- 1 | import math 2 | n = int(input("Enter n: ")) 3 | 4 | def sieve(n): 5 | l = [True] * (n+1) 6 | prime = [] 7 | start = 2 8 | end = int(math.sqrt(n)) 9 | while(start <= end): 10 | if l[start] == True: 11 | prime.append(start) 12 | for i in range(start*start, n+1, start): 13 | if l[i] == True: 14 | l[i] = False 15 | start += 1 16 | 17 | for j in range(end+1,n+1): 18 | if l[j] == True: 19 | prime.append(j) 20 | 21 | return prime 22 | 23 | print(sieve(n)) 24 | 25 | -------------------------------------------------------------------------------- /project_euler/problem_28/sol1.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from math import ceil 3 | 4 | try: 5 | xrange #Python 2 6 | except NameError: 7 | xrange = range #Python 3 8 | 9 | def diagonal_sum(n): 10 | total = 1 11 | 12 | for i in xrange(1, int(ceil(n/2.0))): 13 | odd = 2*i+1 14 | even = 2*i 15 | total = total + 4*odd**2 - 6*even 16 | 17 | return total 18 | 19 | if __name__ == '__main__': 20 | import sys 21 | 22 | if len(sys.argv) == 1: 23 | print(diagonal_sum(1001)) 24 | else: 25 | try: 26 | n = int(sys.argv[1]) 27 | diagonal_sum(n) 28 | except ValueError: 29 | print('Invalid entry - please enter a number') -------------------------------------------------------------------------------- /sorts/wiggle_sort.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3].... 3 | For example: 4 | if input numbers = [3, 5, 2, 1, 6, 4] 5 | one possible Wiggle Sorted answer is [3, 5, 1, 6, 2, 4]. 6 | """ 7 | def wiggle_sort(nums): 8 | for i in range(len(nums)): 9 | if (i % 2 == 1) == (nums[i-1] > nums[i]): 10 | nums[i-1], nums[i] = nums[i], nums[i-1] 11 | 12 | 13 | print("Enter the array elements:\n") 14 | array=list(map(int,input().split())) 15 | print("The unsorted array is:\n") 16 | print(array) 17 | wiggle_sort(array) 18 | print("Array after Wiggle sort:\n") 19 | print(array) 20 | 21 | 22 | -------------------------------------------------------------------------------- /maths/fibonacci_sequence_recursion.py: -------------------------------------------------------------------------------- 1 | # Fibonacci Sequence Using Recursion 2 | 3 | def recur_fibo(n): 4 | if n <= 1: 5 | return n 6 | else: 7 | (recur_fibo(n-1) + recur_fibo(n-2)) 8 | 9 | def isPositiveInteger(limit): 10 | return limit >= 0 11 | 12 | def main(): 13 | limit = int(input("How many terms to include in fibonacci series: ")) 14 | if isPositiveInteger(limit): 15 | print("The first {limit} terms of the fibonacci series are as follows:") 16 | print([recur_fibo(n) for n in range(limit)]) 17 | else: 18 | print("Please enter a positive integer: ") 19 | 20 | if __name__ == '__main__': 21 | main() 22 | -------------------------------------------------------------------------------- /project_euler/problem_52/sol1.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | ''' 3 | Permuted multiples 4 | Problem 52 5 | 6 | It can be seen that the number, 125874, and its double, 251748, contain exactly the same digits, but in a different order. 7 | 8 | Find the smallest positive integer, x, such that 2x, 3x, 4x, 5x, and 6x, contain the same digits. 9 | ''' 10 | i = 1 11 | 12 | while True: 13 | if sorted(list(str(i))) == \ 14 | sorted(list(str(2*i))) == \ 15 | sorted(list(str(3*i))) == \ 16 | sorted(list(str(4*i))) == \ 17 | sorted(list(str(5*i))) == \ 18 | sorted(list(str(6*i))): 19 | break 20 | 21 | i += 1 22 | 23 | print(i) -------------------------------------------------------------------------------- /project_euler/problem_01/sol2.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Problem Statement: 3 | If we list all the natural numbers below 10 that are multiples of 3 or 5, 4 | we get 3,5,6 and 9. The sum of these multiples is 23. 5 | Find the sum of all the multiples of 3 or 5 below N. 6 | ''' 7 | from __future__ import print_function 8 | try: 9 | raw_input # Python 2 10 | except NameError: 11 | raw_input = input # Python 3 12 | n = int(raw_input().strip()) 13 | sum = 0 14 | terms = (n-1)//3 15 | sum+= ((terms)*(6+(terms-1)*3))//2 #sum of an A.P. 16 | terms = (n-1)//5 17 | sum+= ((terms)*(10+(terms-1)*5))//2 18 | terms = (n-1)//15 19 | sum-= ((terms)*(30+(terms-1)*15))//2 20 | print(sum) 21 | -------------------------------------------------------------------------------- /project_euler/problem_10/sol2.py: -------------------------------------------------------------------------------- 1 | #from Python.Math import prime_generator 2 | import math 3 | from itertools import takewhile 4 | 5 | def primeCheck(number): 6 | if number % 2 == 0 and number > 2: 7 | return False 8 | return all(number % i for i in range(3, int(math.sqrt(number)) + 1, 2)) 9 | 10 | def prime_generator(): 11 | num = 2 12 | while True: 13 | if primeCheck(num): 14 | yield num 15 | num+=1 16 | 17 | def main(): 18 | n = int(input('Enter The upper limit of prime numbers: ')) 19 | print(sum(takewhile(lambda x: x < n,prime_generator()))) 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Graphs/graph_matrix.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | 4 | class Graph: 5 | 6 | def __init__(self, vertex): 7 | self.vertex = vertex 8 | self.graph = [[0] * vertex for i in range(vertex) ] 9 | 10 | def add_edge(self, u, v): 11 | self.graph[u - 1][v - 1] = 1 12 | self.graph[v - 1][u - 1] = 1 13 | 14 | def show(self): 15 | 16 | for i in self.graph: 17 | for j in i: 18 | print(j, end=' ') 19 | print(' ') 20 | 21 | 22 | 23 | 24 | g = Graph(100) 25 | 26 | g.add_edge(1,4) 27 | g.add_edge(4,2) 28 | g.add_edge(4,5) 29 | g.add_edge(2,5) 30 | g.add_edge(5,3) 31 | g.show() 32 | 33 | -------------------------------------------------------------------------------- /project_euler/problem_09/sol2.py: -------------------------------------------------------------------------------- 1 | """A Pythagorean triplet is a set of three natural numbers, for which, 2 | a^2+b^2=c^2 3 | Given N, Check if there exists any Pythagorean triplet for which a+b+c=N 4 | Find maximum possible value of product of a,b,c among all such Pythagorean triplets, If there is no such Pythagorean triplet print -1.""" 5 | #!/bin/python3 6 | 7 | product=-1 8 | d=0 9 | N = int(input()) 10 | for a in range(1,N//3): 11 | """Solving the two equations a**2+b**2=c**2 and a+b+c=N eliminating c """ 12 | b=(N*N-2*a*N)//(2*N-2*a) 13 | c=N-a-b 14 | if c*c==(a*a+b*b): 15 | d=(a*b*c) 16 | if d>=product: 17 | product=d 18 | print(product) 19 | -------------------------------------------------------------------------------- /project_euler/problem_25/sol1.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | try: 4 | xrange #Python 2 5 | except NameError: 6 | xrange = range #Python 3 7 | 8 | def fibonacci(n): 9 | if n == 1 or type(n) is not int: 10 | return 0 11 | elif n == 2: 12 | return 1 13 | else: 14 | sequence = [0, 1] 15 | for i in xrange(2, n+1): 16 | sequence.append(sequence[i-1] + sequence[i-2]) 17 | 18 | return sequence[n] 19 | 20 | def fibonacci_digits_index(n): 21 | digits = 0 22 | index = 2 23 | 24 | while digits < n: 25 | index += 1 26 | digits = len(str(fibonacci(index))) 27 | 28 | return index 29 | 30 | if __name__ == '__main__': 31 | print(fibonacci_digits_index(1000)) -------------------------------------------------------------------------------- /sorts/radix_sort.py: -------------------------------------------------------------------------------- 1 | def radixsort(lst): 2 | RADIX = 10 3 | placement = 1 4 | 5 | # get the maximum number 6 | max_digit = max(lst) 7 | 8 | while placement < max_digit: 9 | # declare and initialize buckets 10 | buckets = [list() for _ in range( RADIX )] 11 | 12 | # split lst between lists 13 | for i in lst: 14 | tmp = int((i / placement) % RADIX) 15 | buckets[tmp].append(i) 16 | 17 | # empty lists into lst array 18 | a = 0 19 | for b in range( RADIX ): 20 | buck = buckets[b] 21 | for i in buck: 22 | lst[a] = i 23 | a += 1 24 | 25 | # move to next 26 | placement *= RADIX 27 | -------------------------------------------------------------------------------- /project_euler/problem_06/sol2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | ''' 3 | Problem: 4 | The sum of the squares of the first ten natural numbers is, 5 | 1^2 + 2^2 + ... + 10^2 = 385 6 | The square of the sum of the first ten natural numbers is, 7 | (1 + 2 + ... + 10)^2 = 552 = 3025 8 | Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 − 385 = 2640. 9 | Find the difference between the sum of the squares of the first N natural numbers and the square of the sum. 10 | ''' 11 | from __future__ import print_function 12 | n = int(input()) 13 | suma = n*(n+1)/2 14 | suma **= 2 15 | sumb = n*(n+1)*(2*n+1)/6 16 | print(suma-sumb) 17 | -------------------------------------------------------------------------------- /Graphs/graph_list.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | 4 | class Graph: 5 | def __init__(self, vertex): 6 | self.vertex = vertex 7 | self.graph = [[0] for i in range(vertex)] 8 | 9 | def add_edge(self, u, v): 10 | self.graph[u - 1].append(v - 1) 11 | 12 | def show(self): 13 | for i in range(self.vertex): 14 | print('%d: '% (i + 1), end=' ') 15 | for j in self.graph[i]: 16 | print('%d-> '% (j + 1), end=' ') 17 | print(' ') 18 | 19 | 20 | 21 | g = Graph(100) 22 | 23 | g.add_edge(1,3) 24 | g.add_edge(2,3) 25 | g.add_edge(3,4) 26 | g.add_edge(3,5) 27 | g.add_edge(4,5) 28 | 29 | 30 | g.show() 31 | 32 | -------------------------------------------------------------------------------- /project_euler/problem_02/sol1.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Problem: 3 | Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, 4 | the first 10 terms will be: 5 | 1,2,3,5,8,13,21,34,55,89,.. 6 | By considering the terms in the Fibonacci sequence whose values do not exceed n, find the sum of the even-valued terms. 7 | e.g. for n=10, we have {2,8}, sum is 10. 8 | ''' 9 | from __future__ import print_function 10 | 11 | try: 12 | raw_input # Python 2 13 | except NameError: 14 | raw_input = input # Python 3 15 | 16 | n = int(raw_input().strip()) 17 | i=1 18 | j=2 19 | sum=0 20 | while(j<=n): 21 | if j%2 == 0: 22 | sum+=j 23 | i , j = j, i+j 24 | print(sum) 25 | -------------------------------------------------------------------------------- /project_euler/problem_07/sol1.py: -------------------------------------------------------------------------------- 1 | ''' 2 | By listing the first six prime numbers: 3 | 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. 4 | What is the Nth prime number? 5 | ''' 6 | from __future__ import print_function 7 | from math import sqrt 8 | def isprime(n): 9 | if (n==2): 10 | return True 11 | elif (n%2==0): 12 | return False 13 | else: 14 | sq = int(sqrt(n))+1 15 | for i in range(3,sq,2): 16 | if(n%i==0): 17 | return False 18 | return True 19 | n = int(input()) 20 | i=0 21 | j=1 22 | while(i!=n and j<3): 23 | j+=1 24 | if (isprime(j)): 25 | i+=1 26 | while(i!=n): 27 | j+=2 28 | if(isprime(j)): 29 | i+=1 30 | print(j) 31 | -------------------------------------------------------------------------------- /searches/jump_search.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import math 3 | def jump_search(arr, x): 4 | n = len(arr) 5 | step = int(math.floor(math.sqrt(n))) 6 | prev = 0 7 | while arr[min(step, n)-1] < x: 8 | prev = step 9 | step += int(math.floor(math.sqrt(n))) 10 | if prev >= n: 11 | return -1 12 | 13 | while arr[prev] < x: 14 | prev = prev + 1 15 | if prev == min(step, n): 16 | return -1 17 | if arr[prev] == x: 18 | return prev 19 | return -1 20 | 21 | 22 | 23 | arr = [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610] 24 | x = 55 25 | index = jump_search(arr, x) 26 | print("\nNumber " + str(x) +" is at index " + str(index)); 27 | -------------------------------------------------------------------------------- /project_euler/problem_01/sol4.py: -------------------------------------------------------------------------------- 1 | def mulitples(limit): 2 | xmulti = [] 3 | zmulti = [] 4 | z = 3 5 | x = 5 6 | temp = 1 7 | while True: 8 | result = z * temp 9 | if (result < limit): 10 | zmulti.append(result) 11 | temp += 1 12 | else: 13 | temp = 1 14 | break 15 | while True: 16 | result = x * temp 17 | if (result < limit): 18 | xmulti.append(result) 19 | temp += 1 20 | else: 21 | break 22 | collection = list(set(xmulti+zmulti)) 23 | return (sum(collection)) 24 | 25 | 26 | 27 | 28 | 29 | 30 | print (mulitples(1000)) 31 | -------------------------------------------------------------------------------- /project_euler/problem_06/sol1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | ''' 3 | Problem: 4 | The sum of the squares of the first ten natural numbers is, 5 | 1^2 + 2^2 + ... + 10^2 = 385 6 | The square of the sum of the first ten natural numbers is, 7 | (1 + 2 + ... + 10)^2 = 552 = 3025 8 | Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 − 385 = 2640. 9 | Find the difference between the sum of the squares of the first N natural numbers and the square of the sum. 10 | ''' 11 | from __future__ import print_function 12 | 13 | suma = 0 14 | sumb = 0 15 | n = int(input()) 16 | for i in range(1,n+1): 17 | suma += i**2 18 | sumb += i 19 | sum = sumb**2 - suma 20 | print(sum) 21 | -------------------------------------------------------------------------------- /matrix/searching_in_sorted_matrix.py: -------------------------------------------------------------------------------- 1 | def search_in_a_sorted_matrix(mat, m, n, key): 2 | i, j = m - 1, 0 3 | while i >= 0 and j < n: 4 | if key == mat[i][j]: 5 | print('Key %s found at row- %s column- %s' % (key, i + 1, j + 1)) 6 | return 7 | if key < mat[i][j]: 8 | i -= 1 9 | else: 10 | j += 1 11 | print('Key %s not found' % (key)) 12 | 13 | 14 | def main(): 15 | mat = [ 16 | [2, 5, 7], 17 | [4, 8, 13], 18 | [9, 11, 15], 19 | [12, 17, 20] 20 | ] 21 | x = int(input("Enter the element to be searched:")) 22 | print(mat) 23 | search_in_a_sorted_matrix(mat, len(mat), len(mat[0]), x) 24 | 25 | 26 | if __name__ == '__main__': 27 | main() 28 | -------------------------------------------------------------------------------- /other/fischer_yates_shuffle.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # encoding=utf8 3 | """ 4 | The Fisher–Yates shuffle is an algorithm for generating a random permutation of a finite sequence. 5 | For more details visit 6 | wikipedia/Fischer-Yates-Shuffle. 7 | """ 8 | import random 9 | 10 | def FYshuffle(LIST): 11 | for i in range(len(LIST)): 12 | a = random.randint(0, len(LIST)-1) 13 | b = random.randint(0, len(LIST)-1) 14 | LIST[a], LIST[b] = LIST[b], LIST[a] 15 | return LIST 16 | 17 | if __name__ == '__main__': 18 | integers = [0,1,2,3,4,5,6,7] 19 | strings = ['python', 'says', 'hello', '!'] 20 | print ('Fisher-Yates Shuffle:') 21 | print ('List',integers, strings) 22 | print ('FY Shuffle',FYshuffle(integers), FYshuffle(strings)) 23 | -------------------------------------------------------------------------------- /project_euler/problem_14/sol2.py: -------------------------------------------------------------------------------- 1 | def collatz_sequence(n): 2 | """Collatz conjecture: start with any positive integer n.Next termis obtained from the previous term as follows: 3 | if the previous term is even, the next term is one half the previous term. 4 | If the previous term is odd, the next term is 3 times the previous term plus 1. 5 | The conjecture states the sequence will always reach 1 regaardess of starting n.""" 6 | sequence = [n] 7 | while n != 1: 8 | if n % 2 == 0:# even 9 | n //= 2 10 | else: 11 | n = 3*n +1 12 | sequence.append(n) 13 | return sequence 14 | 15 | answer = max([(len(collatz_sequence(i)), i) for i in range(1,1000000)]) 16 | print("Longest Collatz sequence under one million is %d with length %d" % (answer[1],answer[0])) -------------------------------------------------------------------------------- /dynamic_programming/minimum_partition.py: -------------------------------------------------------------------------------- 1 | """ 2 | Partition a set into two subsets such that the difference of subset sums is minimum 3 | """ 4 | def findMin(arr): 5 | n = len(arr) 6 | s = sum(arr) 7 | 8 | dp = [[False for x in range(s+1)]for y in range(n+1)] 9 | 10 | for i in range(1, n+1): 11 | dp[i][0] = True 12 | 13 | for i in range(1, s+1): 14 | dp[0][i] = False 15 | 16 | for i in range(1, n+1): 17 | for j in range(1, s+1): 18 | dp[i][j]= dp[i][j-1] 19 | 20 | if (arr[i-1] <= j): 21 | dp[i][j] = dp[i][j] or dp[i-1][j-arr[i-1]] 22 | 23 | for j in range(int(s/2), -1, -1): 24 | if dp[n][j] == True: 25 | diff = s-2*j 26 | break; 27 | 28 | return diff 29 | -------------------------------------------------------------------------------- /project_euler/problem_36/sol1.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | ''' 3 | Double-base palindromes 4 | Problem 36 5 | The decimal number, 585 = 10010010012 (binary), is palindromic in both bases. 6 | 7 | Find the sum of all numbers, less than one million, which are palindromic in base 10 and base 2. 8 | 9 | (Please note that the palindromic number, in either base, may not include leading zeros.) 10 | ''' 11 | try: 12 | xrange #Python 2 13 | except NameError: 14 | xrange = range #Python 3 15 | 16 | def is_palindrome(n): 17 | n = str(n) 18 | 19 | if n == n[::-1]: 20 | return True 21 | else: 22 | return False 23 | 24 | total = 0 25 | 26 | for i in xrange(1, 1000000): 27 | if is_palindrome(i) and is_palindrome(bin(i).split('b')[1]): 28 | total += i 29 | 30 | print(total) -------------------------------------------------------------------------------- /other/palindrome.py: -------------------------------------------------------------------------------- 1 | # Program to find whether given string is palindrome or not 2 | def is_palindrome(str): 3 | start_i = 0 4 | end_i = len(str) - 1 5 | while start_i < end_i: 6 | if str[start_i] == str[end_i]: 7 | start_i += 1 8 | end_i -= 1 9 | else: 10 | return False 11 | return True 12 | 13 | 14 | # Recursive method 15 | def recursive_palindrome(str): 16 | if len(str) <= 1: 17 | return True 18 | if str[0] == str[len(str) - 1]: 19 | return recursive_palindrome(str[1:-1]) 20 | else: 21 | return False 22 | 23 | 24 | def main(): 25 | str = 'ama' 26 | print(recursive_palindrome(str.lower())) 27 | print(is_palindrome(str.lower())) 28 | 29 | 30 | if __name__ == '__main__': 31 | main() 32 | -------------------------------------------------------------------------------- /project_euler/problem_10/sol1.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from math import sqrt 3 | 4 | try: 5 | xrange #Python 2 6 | except NameError: 7 | xrange = range #Python 3 8 | 9 | def is_prime(n): 10 | for i in xrange(2, int(sqrt(n))+1): 11 | if n%i == 0: 12 | return False 13 | 14 | return True 15 | 16 | def sum_of_primes(n): 17 | if n > 2: 18 | sumOfPrimes = 2 19 | else: 20 | return 0 21 | 22 | for i in xrange(3, n, 2): 23 | if is_prime(i): 24 | sumOfPrimes += i 25 | 26 | return sumOfPrimes 27 | 28 | if __name__ == '__main__': 29 | import sys 30 | 31 | if len(sys.argv) == 1: 32 | print(sum_of_primes(2000000)) 33 | else: 34 | try: 35 | n = int(sys.argv[1]) 36 | print(sum_of_primes(n)) 37 | except ValueError: 38 | print('Invalid entry - please enter a number.') 39 | -------------------------------------------------------------------------------- /project_euler/problem_20/sol1.py: -------------------------------------------------------------------------------- 1 | # Finding the factorial. 2 | def factorial(n): 3 | fact = 1 4 | for i in range(1,n+1): 5 | fact *= i 6 | return fact 7 | 8 | # Spliting the digits and adding it. 9 | def split_and_add(number): 10 | sum_of_digits = 0 11 | while(number>0): 12 | last_digit = number % 10 13 | sum_of_digits += last_digit 14 | number = int(number/10) # Removing the last_digit from the given number. 15 | return sum_of_digits 16 | 17 | # Taking the user input. 18 | number = int(input("Enter the Number: ")) 19 | 20 | # Assigning the factorial from the factorial function. 21 | factorial = factorial(number) 22 | 23 | # Spliting and adding the factorial into answer. 24 | answer = split_and_add(factorial) 25 | 26 | # Printing the answer. 27 | print(answer) 28 | -------------------------------------------------------------------------------- /other/tower_of_hanoi.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | def moveTower(height, fromPole, toPole, withPole): 3 | ''' 4 | >>> moveTower(3, 'A', 'B', 'C') 5 | moving disk from A to B 6 | moving disk from A to C 7 | moving disk from B to C 8 | moving disk from A to B 9 | moving disk from C to A 10 | moving disk from C to B 11 | moving disk from A to B 12 | ''' 13 | if height >= 1: 14 | moveTower(height-1, fromPole, withPole, toPole) 15 | moveDisk(fromPole, toPole) 16 | moveTower(height-1, withPole, toPole, fromPole) 17 | 18 | def moveDisk(fp,tp): 19 | print(('moving disk from', fp, 'to', tp)) 20 | 21 | def main(): 22 | height = int(input('Height of hanoi: ')) 23 | moveTower(height, 'A', 'B', 'C') 24 | 25 | if __name__ == '__main__': 26 | main() 27 | -------------------------------------------------------------------------------- /project_euler/problem_40/sol1.py: -------------------------------------------------------------------------------- 1 | #-.- coding: latin-1 -.- 2 | from __future__ import print_function 3 | ''' 4 | Champernowne's constant 5 | Problem 40 6 | An irrational decimal fraction is created by concatenating the positive integers: 7 | 8 | 0.123456789101112131415161718192021... 9 | 10 | It can be seen that the 12th digit of the fractional part is 1. 11 | 12 | If dn represents the nth digit of the fractional part, find the value of the following expression. 13 | 14 | d1 × d10 × d100 × d1000 × d10000 × d100000 × d1000000 15 | ''' 16 | 17 | constant = [] 18 | i = 1 19 | 20 | while len(constant) < 1e6: 21 | constant.append(str(i)) 22 | i += 1 23 | 24 | constant = ''.join(constant) 25 | 26 | print(int(constant[0])*int(constant[9])*int(constant[99])*int(constant[999])*int(constant[9999])*int(constant[99999])*int(constant[999999])) -------------------------------------------------------------------------------- /project_euler/problem_76/sol1.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | ''' 3 | Counting Summations 4 | Problem 76 5 | 6 | It is possible to write five as a sum in exactly six different ways: 7 | 8 | 4 + 1 9 | 3 + 2 10 | 3 + 1 + 1 11 | 2 + 2 + 1 12 | 2 + 1 + 1 + 1 13 | 1 + 1 + 1 + 1 + 1 14 | 15 | How many different ways can one hundred be written as a sum of at least two positive integers? 16 | ''' 17 | try: 18 | xrange #Python 2 19 | except NameError: 20 | xrange = range #Python 3 21 | 22 | def partition(m): 23 | memo = [[0 for _ in xrange(m)] for _ in xrange(m+1)] 24 | for i in xrange(m+1): 25 | memo[i][0] = 1 26 | 27 | for n in xrange(m+1): 28 | for k in xrange(1, m): 29 | memo[n][k] += memo[n][k-1] 30 | if n > k: 31 | memo[n][k] += memo[n-k-1][k] 32 | 33 | return (memo[m][m-1] - 1) 34 | 35 | print(partition(100)) -------------------------------------------------------------------------------- /data_structures/hashing/quadratic_probing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from .hash_table import HashTable 4 | 5 | 6 | class QuadraticProbing(HashTable): 7 | """ 8 | Basic Hash Table example with open addressing using Quadratic Probing 9 | """ 10 | def __init__(self, *args, **kwargs): 11 | super().__init__(*args, **kwargs) 12 | 13 | def _colision_resolution(self, key, data=None): 14 | i = 1 15 | new_key = self.hash_function(key + i*i) 16 | 17 | while self.values[new_key] is not None \ 18 | and self.values[new_key] != key: 19 | i += 1 20 | new_key = self.hash_function(key + i*i) if not \ 21 | self.balanced_factor() >= self.lim_charge else None 22 | 23 | if new_key is None: 24 | break 25 | 26 | return new_key 27 | -------------------------------------------------------------------------------- /other/two_sum.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array of integers, return indices of the two numbers such that they add up to a specific target. 3 | 4 | You may assume that each input would have exactly one solution, and you may not use the same element twice. 5 | 6 | Example: 7 | Given nums = [2, 7, 11, 15], target = 9, 8 | 9 | Because nums[0] + nums[1] = 2 + 7 = 9, 10 | return [0, 1]. 11 | """ 12 | from __future__ import print_function 13 | 14 | def twoSum(nums, target): 15 | """ 16 | :type nums: List[int] 17 | :type target: int 18 | :rtype: List[int] 19 | """ 20 | chk_map = {} 21 | for index, val in enumerate(nums): 22 | compl = target - val 23 | if compl in chk_map: 24 | indices = [chk_map[compl], index] 25 | print(indices) 26 | return [indices] 27 | else: 28 | chk_map[val] = index 29 | return False 30 | -------------------------------------------------------------------------------- /project_euler/problem_06/sol3.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Problem: 3 | The sum of the squares of the first ten natural numbers is, 4 | 1^2 + 2^2 + ... + 10^2 = 385 5 | The square of the sum of the first ten natural numbers is, 6 | (1 + 2 + ... + 10)^2 = 552 = 3025 7 | Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 − 385 = 2640. 8 | Find the difference between the sum of the squares of the first N natural numbers and the square of the sum. 9 | ''' 10 | from __future__ import print_function 11 | import math 12 | def problem6(number=100): 13 | sum_of_squares = sum([i*i for i in range(1,number+1)]) 14 | square_of_sum = int(math.pow(sum(range(1,number+1)),2)) 15 | return square_of_sum - sum_of_squares 16 | def main(): 17 | print(problem6()) 18 | 19 | if __name__ == '__main__': 20 | main() -------------------------------------------------------------------------------- /project_euler/problem_07/sol3.py: -------------------------------------------------------------------------------- 1 | ''' 2 | By listing the first six prime numbers: 3 | 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. 4 | What is the Nth prime number? 5 | ''' 6 | from __future__ import print_function 7 | # from Python.Math import PrimeCheck 8 | import math 9 | import itertools 10 | def primeCheck(number): 11 | if number % 2 == 0 and number > 2: 12 | return False 13 | return all(number % i for i in range(3, int(math.sqrt(number)) + 1, 2)) 14 | 15 | def prime_generator(): 16 | num = 2 17 | while True: 18 | if primeCheck(num): 19 | yield num 20 | num+=1 21 | 22 | def main(): 23 | n = int(input('Enter The N\'th Prime Number You Want To Get: ')) # Ask For The N'th Prime Number Wanted 24 | print(next(itertools.islice(prime_generator(),n-1,n))) 25 | 26 | 27 | if __name__ == '__main__': 28 | main() -------------------------------------------------------------------------------- /data_structures/stacks/balanced_parentheses.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from __future__ import absolute_import 3 | from stack import Stack 4 | 5 | __author__ = 'Omkar Pathak' 6 | 7 | 8 | def balanced_parentheses(parentheses): 9 | """ Use a stack to check if a string of parentheses is balanced.""" 10 | stack = Stack(len(parentheses)) 11 | for parenthesis in parentheses: 12 | if parenthesis == '(': 13 | stack.push(parenthesis) 14 | elif parenthesis == ')': 15 | if stack.is_empty(): 16 | return False 17 | stack.pop() 18 | return stack.is_empty() 19 | 20 | 21 | if __name__ == '__main__': 22 | examples = ['((()))', '((())', '(()))'] 23 | print('Balanced parentheses demonstration:\n') 24 | for example in examples: 25 | print(example + ': ' + str(balanced_parentheses(example))) 26 | -------------------------------------------------------------------------------- /data_structures/hashing/number_theory/prime_numbers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | module to operations with prime numbers 4 | """ 5 | 6 | 7 | def check_prime(number): 8 | """ 9 | it's not the best solution 10 | """ 11 | special_non_primes = [0,1,2] 12 | if number in special_non_primes[:2]: 13 | return 2 14 | elif number == special_non_primes[-1]: 15 | return 3 16 | 17 | return all([number % i for i in range(2, number)]) 18 | 19 | 20 | def next_prime(value, factor=1, **kwargs): 21 | value = factor * value 22 | first_value_val = value 23 | 24 | while not check_prime(value): 25 | value += 1 if not ("desc" in kwargs.keys() and kwargs["desc"] is True) else -1 26 | 27 | if value == first_value_val: 28 | return next_prime(value + 1, **kwargs) 29 | return value 30 | -------------------------------------------------------------------------------- /Graphs/kahns_algorithm_long.py: -------------------------------------------------------------------------------- 1 | # Finding longest distance in Directed Acyclic Graph using KahnsAlgorithm 2 | def longestDistance(l): 3 | indegree = [0] * len(l) 4 | queue = [] 5 | longDist = [1] * len(l) 6 | 7 | for key, values in l.items(): 8 | for i in values: 9 | indegree[i] += 1 10 | 11 | for i in range(len(indegree)): 12 | if indegree[i] == 0: 13 | queue.append(i) 14 | 15 | while(queue): 16 | vertex = queue.pop(0) 17 | for x in l[vertex]: 18 | indegree[x] -= 1 19 | 20 | if longDist[vertex] + 1 > longDist[x]: 21 | longDist[x] = longDist[vertex] + 1 22 | 23 | if indegree[x] == 0: 24 | queue.append(x) 25 | 26 | print(max(longDist)) 27 | 28 | # Adjacency list of Graph 29 | l = {0:[2,3,4], 1:[2,7], 2:[5], 3:[5,7], 4:[7], 5:[6], 6:[7], 7:[]} 30 | longestDistance(l) 31 | -------------------------------------------------------------------------------- /Graphs/kahns_algorithm_topo.py: -------------------------------------------------------------------------------- 1 | # Kahn's Algorithm is used to find Topological ordering of Directed Acyclic Graph using BFS 2 | def topologicalSort(l): 3 | indegree = [0] * len(l) 4 | queue = [] 5 | topo = [] 6 | cnt = 0 7 | 8 | for key, values in l.items(): 9 | for i in values: 10 | indegree[i] += 1 11 | 12 | for i in range(len(indegree)): 13 | if indegree[i] == 0: 14 | queue.append(i) 15 | 16 | while(queue): 17 | vertex = queue.pop(0) 18 | cnt += 1 19 | topo.append(vertex) 20 | for x in l[vertex]: 21 | indegree[x] -= 1 22 | if indegree[x] == 0: 23 | queue.append(x) 24 | 25 | if cnt != len(l): 26 | print("Cycle exists") 27 | else: 28 | print(topo) 29 | 30 | # Adjacency List of Graph 31 | l = {0:[1,2], 1:[3], 2:[3], 3:[4,5], 4:[], 5:[]} 32 | topologicalSort(l) 33 | -------------------------------------------------------------------------------- /sorts/gnome_sort.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | def gnome_sort(unsorted): 4 | """ 5 | Pure implementation of the gnome sort algorithm in Python. 6 | """ 7 | if len(unsorted) <= 1: 8 | return unsorted 9 | 10 | i = 1 11 | 12 | while i < len(unsorted): 13 | if unsorted[i-1] <= unsorted[i]: 14 | i += 1 15 | else: 16 | unsorted[i-1], unsorted[i] = unsorted[i], unsorted[i-1] 17 | i -= 1 18 | if (i == 0): 19 | i = 1 20 | 21 | if __name__ == '__main__': 22 | try: 23 | raw_input # Python 2 24 | except NameError: 25 | raw_input = input # Python 3 26 | 27 | user_input = raw_input('Enter numbers separated by a comma:\n').strip() 28 | unsorted = [int(item) for item in user_input.split(',')] 29 | gnome_sort(unsorted) 30 | print(unsorted) 31 | -------------------------------------------------------------------------------- /Graphs/minimum_spanning_tree_kruskal.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | num_nodes, num_edges = list(map(int,input().split())) 3 | 4 | edges = [] 5 | 6 | for i in range(num_edges): 7 | node1, node2, cost = list(map(int,input().split())) 8 | edges.append((i,node1,node2,cost)) 9 | 10 | edges = sorted(edges, key=lambda edge: edge[3]) 11 | 12 | parent = [i for i in range(num_nodes)] 13 | 14 | def find_parent(i): 15 | if(i != parent[i]): 16 | parent[i] = find_parent(parent[i]) 17 | return parent[i] 18 | 19 | minimum_spanning_tree_cost = 0 20 | minimum_spanning_tree = [] 21 | 22 | for edge in edges: 23 | parent_a = find_parent(edge[1]) 24 | parent_b = find_parent(edge[2]) 25 | if(parent_a != parent_b): 26 | minimum_spanning_tree_cost += edge[3] 27 | minimum_spanning_tree.append(edge) 28 | parent[parent_a] = parent_b 29 | 30 | print(minimum_spanning_tree_cost) 31 | for edge in minimum_spanning_tree: 32 | print(edge) 33 | -------------------------------------------------------------------------------- /data_structures/binary tree/fenwick_tree.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | class FenwickTree: 3 | 4 | def __init__(self, SIZE): # create fenwick tree with size SIZE 5 | self.Size = SIZE 6 | self.ft = [0 for i in range (0,SIZE)] 7 | 8 | def update(self, i, val): # update data (adding) in index i in O(lg N) 9 | while (i < self.Size): 10 | self.ft[i] += val 11 | i += i & (-i) 12 | 13 | def query(self, i): # query cumulative data from index 0 to i in O(lg N) 14 | ret = 0 15 | while (i > 0): 16 | ret += self.ft[i] 17 | i -= i & (-i) 18 | return ret 19 | 20 | if __name__ == '__main__': 21 | f = FenwickTree(100) 22 | f.update(1,20) 23 | f.update(4,4) 24 | print (f.query(1)) 25 | print (f.query(3)) 26 | print (f.query(4)) 27 | f.update(2,-5) 28 | print (f.query(1)) 29 | print (f.query(3)) 30 | -------------------------------------------------------------------------------- /strings/naiveStringSearch.py: -------------------------------------------------------------------------------- 1 | """ 2 | this algorithm tries to find the pattern from every position of 3 | the mainString if pattern is found from position i it add it to 4 | the answer and does the same for position i+1 5 | 6 | Complexity : O(n*m) 7 | n=length of main string 8 | m=length of pattern string 9 | """ 10 | def naivePatternSearch(mainString,pattern): 11 | patLen=len(pattern) 12 | strLen=len(mainString) 13 | position=[] 14 | for i in range(strLen-patLen+1): 15 | match_found=True 16 | for j in range(patLen): 17 | if mainString[i+j]!=pattern[j]: 18 | match_found=False 19 | break 20 | if match_found: 21 | position.append(i) 22 | return position 23 | 24 | mainString="ABAAABCDBBABCDDEBCABC" 25 | pattern="ABC" 26 | position=naivePatternSearch(mainString,pattern) 27 | print("Pattern found in position ") 28 | for x in position: 29 | print(x) -------------------------------------------------------------------------------- /data_structures/hashing/hash_table_with_linked_list.py: -------------------------------------------------------------------------------- 1 | from .hash_table import HashTable 2 | from collections import deque 3 | 4 | 5 | class HashTableWithLinkedList(HashTable): 6 | def __init__(self, *args, **kwargs): 7 | super().__init__(*args, **kwargs) 8 | 9 | def _set_value(self, key, data): 10 | self.values[key] = deque([]) if self.values[key] is None else self.values[key] 11 | self.values[key].appendleft(data) 12 | self._keys[key] = self.values[key] 13 | 14 | def balanced_factor(self): 15 | return sum([self.charge_factor - len(slot) for slot in self.values])\ 16 | / self.size_table * self.charge_factor 17 | 18 | def _colision_resolution(self, key, data=None): 19 | if not (len(self.values[key]) == self.charge_factor 20 | and self.values.count(None) == 0): 21 | return key 22 | return super()._colision_resolution(key, data) 23 | 24 | 25 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | cache: pip 3 | python: 4 | - 2.7 5 | - 3.6 6 | #- nightly 7 | #- pypy 8 | #- pypy3 9 | matrix: 10 | allow_failures: 11 | - python: nightly 12 | - python: pypy 13 | - python: pypy3 14 | install: 15 | #- pip install -r requirements.txt 16 | - pip install flake8 # pytest # add another testing frameworks later 17 | before_script: 18 | # stop the build if there are Python syntax errors or undefined names 19 | - flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics 20 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 21 | - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics 22 | script: 23 | - true # pytest --capture=sys # add other tests here 24 | notifications: 25 | on_success: change 26 | on_failure: change # `always` will be the setting once code changes slow down 27 | -------------------------------------------------------------------------------- /other/findingPrimes.py: -------------------------------------------------------------------------------- 1 | ''' 2 | -The sieve of Eratosthenes is an algorithm used to find prime numbers, less than or equal to a given value. 3 | -Illustration: https://upload.wikimedia.org/wikipedia/commons/b/b9/Sieve_of_Eratosthenes_animation.gif 4 | ''' 5 | from __future__ import print_function 6 | 7 | 8 | from math import sqrt 9 | def SOE(n): 10 | check = round(sqrt(n)) #Need not check for multiples past the square root of n 11 | 12 | sieve = [False if i <2 else True for i in range(n+1)] #Set every index to False except for index 0 and 1 13 | 14 | for i in range(2, check): 15 | if(sieve[i] == True): #If i is a prime 16 | for j in range(i+i, n+1, i): #Step through the list in increments of i(the multiples of the prime) 17 | sieve[j] = False #Sets every multiple of i to False 18 | 19 | for i in range(n+1): 20 | if(sieve[i] == True): 21 | print(i, end=" ") 22 | -------------------------------------------------------------------------------- /ciphers/onepad_cipher.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import random 4 | 5 | 6 | class Onepad: 7 | def encrypt(self, text): 8 | '''Function to encrypt text using psedo-random numbers''' 9 | plain = [ord(i) for i in text] 10 | key = [] 11 | cipher = [] 12 | for i in plain: 13 | k = random.randint(1, 300) 14 | c = (i+k)*k 15 | cipher.append(c) 16 | key.append(k) 17 | return cipher, key 18 | 19 | def decrypt(self, cipher, key): 20 | '''Function to decrypt text using psedo-random numbers.''' 21 | plain = [] 22 | for i in range(len(key)): 23 | p = int((cipher[i]-(key[i])**2)/key[i]) 24 | plain.append(chr(p)) 25 | plain = ''.join([i for i in plain]) 26 | return plain 27 | 28 | 29 | if __name__ == '__main__': 30 | c, k = Onepad().encrypt('Hello') 31 | print(c, k) 32 | print(Onepad().decrypt(c, k)) 33 | -------------------------------------------------------------------------------- /dynamic_programming/abbreviation.py: -------------------------------------------------------------------------------- 1 | """ 2 | https://www.hackerrank.com/challenges/abbr/problem 3 | You can perform the following operation on some string, : 4 | 5 | 1. Capitalize zero or more of 's lowercase letters at some index i 6 | (i.e., make them uppercase). 7 | 2. Delete all of the remaining lowercase letters in . 8 | 9 | Example: 10 | a=daBcd and b="ABC" 11 | daBcd -> capitalize a and c(dABCd) -> remove d (ABC) 12 | """ 13 | 14 | 15 | def abbr(a, b): 16 | n = len(a) 17 | m = len(b) 18 | dp = [[False for _ in range(m + 1)] for _ in range(n + 1)] 19 | dp[0][0] = True 20 | for i in range(n): 21 | for j in range(m + 1): 22 | if dp[i][j]: 23 | if j < m and a[i].upper() == b[j]: 24 | dp[i + 1][j + 1] = True 25 | if a[i].islower(): 26 | dp[i + 1][j] = True 27 | return dp[n][m] 28 | 29 | 30 | if __name__ == "__main__": 31 | print(abbr("daBcd", "ABC")) # expect True 32 | -------------------------------------------------------------------------------- /project_euler/problem_53/sol1.py: -------------------------------------------------------------------------------- 1 | #-.- coding: latin-1 -.- 2 | from __future__ import print_function 3 | from math import factorial 4 | ''' 5 | Combinatoric selections 6 | Problem 53 7 | 8 | There are exactly ten ways of selecting three from five, 12345: 9 | 10 | 123, 124, 125, 134, 135, 145, 234, 235, 245, and 345 11 | 12 | In combinatorics, we use the notation, 5C3 = 10. 13 | 14 | In general, 15 | 16 | nCr = n!/(r!(n−r)!),where r ≤ n, n! = n×(n−1)×...×3×2×1, and 0! = 1. 17 | It is not until n = 23, that a value exceeds one-million: 23C10 = 1144066. 18 | 19 | How many, not necessarily distinct, values of nCr, for 1 ≤ n ≤ 100, are greater than one-million? 20 | ''' 21 | try: 22 | xrange #Python 2 23 | except NameError: 24 | xrange = range #Python 3 25 | 26 | def combinations(n, r): 27 | return factorial(n)/(factorial(r)*factorial(n-r)) 28 | 29 | total = 0 30 | 31 | for i in xrange(1, 101): 32 | for j in xrange(1, i+1): 33 | if combinations(i, j) > 1e6: 34 | total += 1 35 | 36 | print(total) -------------------------------------------------------------------------------- /project_euler/problem_04/sol1.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Problem: 3 | A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 x 99. 4 | Find the largest palindrome made from the product of two 3-digit numbers which is less than N. 5 | ''' 6 | from __future__ import print_function 7 | limit = int(input("limit? ")) 8 | 9 | # fetchs the next number 10 | for number in range(limit-1,10000,-1): 11 | 12 | # converts number into string. 13 | strNumber = str(number) 14 | 15 | # checks whether 'strNumber' is a palindrome. 16 | if(strNumber == strNumber[::-1]): 17 | 18 | divisor = 999 19 | 20 | # if 'number' is a product of two 3-digit numbers 21 | # then number is the answer otherwise fetch next number. 22 | while(divisor != 99): 23 | 24 | if((number % divisor == 0) and (len(str(number / divisor)) == 3)): 25 | 26 | print(number) 27 | exit(0) 28 | 29 | divisor -=1 30 | -------------------------------------------------------------------------------- /project_euler/problem_11/sol2.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | with open ("grid.txt", "r") as f: 3 | l = [] 4 | for i in range(20): 5 | l.append([int(x) for x in f.readline().split()]) 6 | 7 | maximum = 0 8 | 9 | # right 10 | for i in range(20): 11 | for j in range(17): 12 | temp = l[i][j] * l[i][j+1] * l[i][j+2] * l[i][j+3] 13 | if temp > maximum: 14 | maximum = temp 15 | 16 | # down 17 | for i in range(17): 18 | for j in range(20): 19 | temp = l[i][j] * l[i+1][j] * l[i+2][j] * l[i+3][j] 20 | if temp > maximum: 21 | maximum = temp 22 | 23 | #diagonal 1 24 | for i in range(17): 25 | for j in range(17): 26 | temp = l[i][j] * l[i+1][j+1] * l[i+2][j+2] * l[i+3][j+3] 27 | if temp > maximum: 28 | maximum = temp 29 | 30 | #diagonal 2 31 | for i in range(17): 32 | for j in range(3, 20): 33 | temp = l[i][j] * l[i+1][j-1] * l[i+2][j-2] * l[i+3][j-3] 34 | if temp > maximum: 35 | maximum = temp 36 | print(maximum) 37 | 38 | if __name__ == '__main__': 39 | main() -------------------------------------------------------------------------------- /Graphs/BFS.py: -------------------------------------------------------------------------------- 1 | """pseudo-code""" 2 | 3 | """ 4 | BFS(graph G, start vertex s): 5 | // all nodes initially unexplored 6 | mark s as explored 7 | let Q = queue data structure, initialized with s 8 | while Q is non-empty: 9 | remove the first node of Q, call it v 10 | for each edge(v, w): // for w in graph[v] 11 | if w unexplored: 12 | mark w as explored 13 | add w to Q (at the end) 14 | 15 | """ 16 | 17 | import collections 18 | 19 | 20 | def bfs(graph, start): 21 | explored, queue = set(), [start] # collections.deque([start]) 22 | explored.add(start) 23 | while queue: 24 | v = queue.pop(0) # queue.popleft() 25 | for w in graph[v]: 26 | if w not in explored: 27 | explored.add(w) 28 | queue.append(w) 29 | return explored 30 | 31 | 32 | G = {'A': ['B', 'C'], 33 | 'B': ['A', 'D', 'E'], 34 | 'C': ['A', 'F'], 35 | 'D': ['B'], 36 | 'E': ['B', 'F'], 37 | 'F': ['C', 'E']} 38 | 39 | print(bfs(G, 'A')) 40 | -------------------------------------------------------------------------------- /other/anagrams.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import collections, pprint, time, os 3 | 4 | start_time = time.time() 5 | print('creating word list...') 6 | path = os.path.split(os.path.realpath(__file__)) 7 | with open(path[0] + '/words') as f: 8 | word_list = sorted(list(set([word.strip().lower() for word in f]))) 9 | 10 | def signature(word): 11 | return ''.join(sorted(word)) 12 | 13 | word_bysig = collections.defaultdict(list) 14 | for word in word_list: 15 | word_bysig[signature(word)].append(word) 16 | 17 | def anagram(myword): 18 | return word_bysig[signature(myword)] 19 | 20 | print('finding anagrams...') 21 | all_anagrams = {word: anagram(word) 22 | for word in word_list if len(anagram(word)) > 1} 23 | 24 | print('writing anagrams to file...') 25 | with open('anagrams.txt', 'w') as file: 26 | file.write('all_anagrams = ') 27 | file.write(pprint.pformat(all_anagrams)) 28 | 29 | total_time = round(time.time() - start_time, 2) 30 | print(('Done [', total_time, 'seconds ]')) 31 | -------------------------------------------------------------------------------- /Graphs/finding_bridges.py: -------------------------------------------------------------------------------- 1 | # Finding Bridges in Undirected Graph 2 | def computeBridges(l): 3 | id = 0 4 | n = len(l) # No of vertices in graph 5 | low = [0] * n 6 | visited = [False] * n 7 | 8 | def dfs(at, parent, bridges, id): 9 | visited[at] = True 10 | low[at] = id 11 | id += 1 12 | for to in l[at]: 13 | if to == parent: 14 | pass 15 | elif not visited[to]: 16 | dfs(to, at, bridges, id) 17 | low[at] = min(low[at], low[to]) 18 | if at < low[to]: 19 | bridges.append([at, to]) 20 | else: 21 | # This edge is a back edge and cannot be a bridge 22 | low[at] = min(low[at], to) 23 | 24 | bridges = [] 25 | for i in range(n): 26 | if (not visited[i]): 27 | dfs(i, -1, bridges, id) 28 | print(bridges) 29 | 30 | l = {0:[1,2], 1:[0,2], 2:[0,1,3,5], 3:[2,4], 4:[3], 5:[2,6,8], 6:[5,7], 7:[6,8], 8:[5,7]} 31 | computeBridges(l) 32 | -------------------------------------------------------------------------------- /dynamic_programming/longest_increasing_subsequence_O(nlogn).py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | ############################# 3 | # Author: Aravind Kashyap 4 | # File: lis.py 5 | # comments: This programme outputs the Longest Strictly Increasing Subsequence in O(NLogN) 6 | # Where N is the Number of elements in the list 7 | ############################# 8 | def CeilIndex(v,l,r,key): 9 | while r-l > 1: 10 | m = (l + r)/2 11 | if v[m] >= key: 12 | r = m 13 | else: 14 | l = m 15 | 16 | return r 17 | 18 | 19 | def LongestIncreasingSubsequenceLength(v): 20 | if(len(v) == 0): 21 | return 0 22 | 23 | tail = [0]*len(v) 24 | length = 1 25 | 26 | tail[0] = v[0] 27 | 28 | for i in range(1,len(v)): 29 | if v[i] < tail[0]: 30 | tail[0] = v[i] 31 | elif v[i] > tail[length-1]: 32 | tail[length] = v[i] 33 | length += 1 34 | else: 35 | tail[CeilIndex(tail,-1,length-1,v[i])] = v[i] 36 | 37 | return length 38 | 39 | 40 | v = [2, 5, 3, 7, 11, 8, 10, 13, 6] 41 | print(LongestIncreasingSubsequenceLength(v)) 42 | -------------------------------------------------------------------------------- /project_euler/problem_29/solution.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | """ 3 | Consider all integer combinations of ab for 2 <= a <= 5 and 2 <= b <= 5: 4 | 5 | 22=4, 23=8, 24=16, 25=32 6 | 32=9, 33=27, 34=81, 35=243 7 | 42=16, 43=64, 44=256, 45=1024 8 | 52=25, 53=125, 54=625, 55=3125 9 | If they are then placed in numerical order, with any repeats removed, 10 | we get the following sequence of 15 distinct terms: 11 | 12 | 4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125 13 | 14 | How many distinct terms are in the sequence generated by ab 15 | for 2 <= a <= 100 and 2 <= b <= 100? 16 | """ 17 | 18 | collectPowers = set() 19 | 20 | currentPow = 0 21 | 22 | N = 101 # maximum limit 23 | 24 | for a in range(2, N): 25 | for b in range(2, N): 26 | currentPow = a**b # calculates the current power 27 | collectPowers.add(currentPow) # adds the result to the set 28 | 29 | print("Number of terms ", len(collectPowers)) 30 | 31 | 32 | if __name__ == '__main__': 33 | main() 34 | -------------------------------------------------------------------------------- /sorts/quick_sort_3_partition.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | def quick_sort_3partition(sorting, left, right): 4 | if right <= left: 5 | return 6 | a = i = left 7 | b = right 8 | pivot = sorting[left] 9 | while i <= b: 10 | if sorting[i] < pivot: 11 | sorting[a], sorting[i] = sorting[i], sorting[a] 12 | a += 1 13 | i += 1 14 | elif sorting[i] > pivot: 15 | sorting[b], sorting[i] = sorting[i], sorting[b] 16 | b -= 1 17 | else: 18 | i += 1 19 | quick_sort_3partition(sorting, left, a - 1) 20 | quick_sort_3partition(sorting, b + 1, right) 21 | 22 | if __name__ == '__main__': 23 | try: 24 | raw_input # Python 2 25 | except NameError: 26 | raw_input = input # Python 3 27 | 28 | user_input = raw_input('Enter numbers separated by a comma:\n').strip() 29 | unsorted = [ int(item) for item in user_input.split(',') ] 30 | quick_sort_3partition(unsorted,0,len(unsorted)-1) 31 | print(unsorted) 32 | -------------------------------------------------------------------------------- /dynamic_programming/coin_change.py: -------------------------------------------------------------------------------- 1 | """ 2 | You have m types of coins available in infinite quantities 3 | where the value of each coins is given in the array S=[S0,... Sm-1] 4 | Can you determine number of ways of making change for n units using 5 | the given types of coins? 6 | https://www.hackerrank.com/challenges/coin-change/problem 7 | """ 8 | from __future__ import print_function 9 | 10 | 11 | def dp_count(S, m, n): 12 | 13 | # table[i] represents the number of ways to get to amount i 14 | table = [0] * (n + 1) 15 | 16 | # There is exactly 1 way to get to zero(You pick no coins). 17 | table[0] = 1 18 | 19 | # Pick all coins one by one and update table[] values 20 | # after the index greater than or equal to the value of the 21 | # picked coin 22 | for coin_val in S: 23 | for j in range(coin_val, n + 1): 24 | table[j] += table[j - coin_val] 25 | 26 | return table[n] 27 | 28 | 29 | if __name__ == '__main__': 30 | print(dp_count([1, 2, 3], 3, 4)) # answer 4 31 | print(dp_count([2, 5, 3, 6], 4, 10)) # answer 5 32 | -------------------------------------------------------------------------------- /project_euler/problem_03/sol1.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Problem: 3 | The prime factors of 13195 are 5,7,13 and 29. What is the largest prime factor of a given number N? 4 | e.g. for 10, largest prime factor = 5. For 17, largest prime factor = 17. 5 | ''' 6 | from __future__ import print_function, division 7 | 8 | import math 9 | 10 | def isprime(no): 11 | if(no==2): 12 | return True 13 | elif (no%2==0): 14 | return False 15 | sq = int(math.sqrt(no))+1 16 | for i in range(3,sq,2): 17 | if(no%i==0): 18 | return False 19 | return True 20 | 21 | maxNumber = 0 22 | n=int(input()) 23 | if(isprime(n)): 24 | print(n) 25 | else: 26 | while (n%2==0): 27 | n=n/2 28 | if(isprime(n)): 29 | print(n) 30 | else: 31 | n1 = int(math.sqrt(n))+1 32 | for i in range(3,n1,2): 33 | if(n%i==0): 34 | if(isprime(n/i)): 35 | maxNumber = n/i 36 | break 37 | elif(isprime(i)): 38 | maxNumber = i 39 | print(maxNumber) 40 | -------------------------------------------------------------------------------- /arithmetic_analysis/lu_decomposition.py: -------------------------------------------------------------------------------- 1 | # lower–upper (LU) decomposition - https://en.wikipedia.org/wiki/LU_decomposition 2 | import numpy 3 | 4 | def LUDecompose (table): 5 | # Table that contains our data 6 | # Table has to be a square array so we need to check first 7 | rows,columns=numpy.shape(table) 8 | L=numpy.zeros((rows,columns)) 9 | U=numpy.zeros((rows,columns)) 10 | if rows!=columns: 11 | return [] 12 | for i in range (columns): 13 | for j in range(i-1): 14 | sum=0 15 | for k in range (j-1): 16 | sum+=L[i][k]*U[k][j] 17 | L[i][j]=(table[i][j]-sum)/U[j][j] 18 | L[i][i]=1 19 | for j in range(i-1,columns): 20 | sum1=0 21 | for k in range(i-1): 22 | sum1+=L[i][k]*U[k][j] 23 | U[i][j]=table[i][j]-sum1 24 | return L,U 25 | 26 | if __name__ == "__main__": 27 | matrix =numpy.array([[2,-2,1], 28 | [0,1,2], 29 | [5,3,1]]) 30 | L,U = LUDecompose(matrix) 31 | print(L) 32 | print(U) 33 | -------------------------------------------------------------------------------- /arithmetic_analysis/newton_raphson_method.py: -------------------------------------------------------------------------------- 1 | # Implementing Newton Raphson method in Python 2 | # Author: Haseeb 3 | 4 | from sympy import diff 5 | from decimal import Decimal 6 | 7 | def NewtonRaphson(func, a): 8 | ''' Finds root from the point 'a' onwards by Newton-Raphson method ''' 9 | while True: 10 | c = Decimal(a) - ( Decimal(eval(func)) / Decimal(eval(str(diff(func)))) ) 11 | 12 | a = c 13 | 14 | # This number dictates the accuracy of the answer 15 | if abs(eval(func)) < 10**-15: 16 | return c 17 | 18 | 19 | # Let's Execute 20 | if __name__ == '__main__': 21 | # Find root of trigonometric function 22 | # Find value of pi 23 | print ('sin(x) = 0', NewtonRaphson('sin(x)', 2)) 24 | 25 | # Find root of polynomial 26 | print ('x**2 - 5*x +2 = 0', NewtonRaphson('x**2 - 5*x +2', 0.4)) 27 | 28 | # Find Square Root of 5 29 | print ('x**2 - 5 = 0', NewtonRaphson('x**2 - 5', 0.1)) 30 | 31 | # Exponential Roots 32 | print ('exp(x) - 1 = 0', NewtonRaphson('exp(x) - 1', 0)) 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /arithmetic_analysis/bisection.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | 4 | def bisection(function, a, b): # finds where the function becomes 0 in [a,b] using bolzano 5 | 6 | start = a 7 | end = b 8 | if function(a) == 0: # one of the a or b is a root for the function 9 | return a 10 | elif function(b) == 0: 11 | return b 12 | elif function(a) * function(b) > 0: # if none of these are root and they are both positive or negative, 13 | # then his algorithm can't find the root 14 | print("couldn't find root in [a,b]") 15 | return 16 | else: 17 | mid = (start + end) / 2 18 | while abs(start - mid) > 10**-7: # until we achieve precise equals to 10^-7 19 | if function(mid) == 0: 20 | return mid 21 | elif function(mid) * function(start) < 0: 22 | end = mid 23 | else: 24 | start = mid 25 | mid = (start + end) / 2 26 | return mid 27 | 28 | 29 | def f(x): 30 | return math.pow(x, 3) - 2*x - 5 31 | 32 | if __name__ == "__main__": 33 | print(bisection(f, 1, 1000)) 34 | -------------------------------------------------------------------------------- /simple_client/client.py: -------------------------------------------------------------------------------- 1 | # client.py 2 | 3 | import socket 4 | 5 | HOST, PORT = '127.0.0.1', 1400 6 | 7 | s = socket.socket( 8 | 9 | socket.AF_INET, # ADDRESS FAMILIES 10 | #Name Purpose 11 | #AF_UNIX, AF_LOCAL Local communication 12 | #AF_INET IPv4 Internet protocols 13 | #AF_INET6 IPv6 Internet protocols 14 | #AF_APPLETALK Appletalk 15 | #AF_BLUETOOTH Bluetooth 16 | 17 | 18 | socket.SOCK_STREAM # SOCKET TYPES 19 | #Name Way of Interaction 20 | #SOCK_STREAM TCP 21 | #SOCK_DGRAM UDP 22 | ) 23 | s.connect((HOST, PORT)) 24 | 25 | s.send('Hello World'.encode('ascii'))#in UDP use sendto() 26 | data = s.recv(1024)#in UDP use recvfrom() 27 | 28 | s.close()#end the connection 29 | print(repr(data.decode('ascii'))) 30 | -------------------------------------------------------------------------------- /sorts/topological_sort.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | # a 3 | # / \ 4 | # b c 5 | # / \ 6 | # d e 7 | edges = {'a': ['c', 'b'], 'b': ['d', 'e'], 'c': [], 'd': [], 'e': []} 8 | vertices = ['a', 'b', 'c', 'd', 'e'] 9 | 10 | 11 | def topological_sort(start, visited, sort): 12 | """Perform topolical sort on a directed acyclic graph.""" 13 | current = start 14 | # add current to visited 15 | visited.append(current) 16 | neighbors = edges[current] 17 | for neighbor in neighbors: 18 | # if neighbor not in visited, visit 19 | if neighbor not in visited: 20 | sort = topological_sort(neighbor, visited, sort) 21 | # if all neighbors visited add current to sort 22 | sort.append(current) 23 | # if all vertices haven't been visited select a new one to visit 24 | if len(visited) != len(vertices): 25 | for vertice in vertices: 26 | if vertice not in visited: 27 | sort = topological_sort(vertice, visited, sort) 28 | # return sort 29 | return sort 30 | 31 | 32 | sort = topological_sort('a', [], []) 33 | print(sort) 34 | -------------------------------------------------------------------------------- /data_structures/queue/deqeue.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | # Python code to demonstrate working of 3 | # extend(), extendleft(), rotate(), reverse() 4 | 5 | # importing "collections" for deque operations 6 | import collections 7 | 8 | # initializing deque 9 | de = collections.deque([1, 2, 3,]) 10 | 11 | # using extend() to add numbers to right end 12 | # adds 4,5,6 to right end 13 | de.extend([4,5,6]) 14 | 15 | # printing modified deque 16 | print ("The deque after extending deque at end is : ") 17 | print (de) 18 | 19 | # using extendleft() to add numbers to left end 20 | # adds 7,8,9 to right end 21 | de.extendleft([7,8,9]) 22 | 23 | # printing modified deque 24 | print ("The deque after extending deque at beginning is : ") 25 | print (de) 26 | 27 | # using rotate() to rotate the deque 28 | # rotates by 3 to left 29 | de.rotate(-3) 30 | 31 | # printing modified deque 32 | print ("The deque after rotating deque is : ") 33 | print (de) 34 | 35 | # using reverse() to reverse the deque 36 | de.reverse() 37 | 38 | # printing modified deque 39 | print ("The deque after reversing deque is : ") 40 | print (de) 41 | -------------------------------------------------------------------------------- /other/word_patterns.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import pprint, time 3 | 4 | def getWordPattern(word): 5 | word = word.upper() 6 | nextNum = 0 7 | letterNums = {} 8 | wordPattern = [] 9 | 10 | for letter in word: 11 | if letter not in letterNums: 12 | letterNums[letter] = str(nextNum) 13 | nextNum += 1 14 | wordPattern.append(letterNums[letter]) 15 | return '.'.join(wordPattern) 16 | 17 | def main(): 18 | startTime = time.time() 19 | allPatterns = {} 20 | 21 | with open('Dictionary.txt') as fo: 22 | wordList = fo.read().split('\n') 23 | 24 | for word in wordList: 25 | pattern = getWordPattern(word) 26 | 27 | if pattern not in allPatterns: 28 | allPatterns[pattern] = [word] 29 | else: 30 | allPatterns[pattern].append(word) 31 | 32 | with open('Word Patterns.txt', 'w') as fo: 33 | fo.write(pprint.pformat(allPatterns)) 34 | 35 | totalTime = round(time.time() - startTime, 2) 36 | print(('Done! [', totalTime, 'seconds ]')) 37 | 38 | if __name__ == '__main__': 39 | main() 40 | -------------------------------------------------------------------------------- /project_euler/problem_01/sol3.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | ''' 4 | Problem Statement: 5 | If we list all the natural numbers below 10 that are multiples of 3 or 5, 6 | we get 3,5,6 and 9. The sum of these multiples is 23. 7 | Find the sum of all the multiples of 3 or 5 below N. 8 | ''' 9 | ''' 10 | This solution is based on the pattern that the successive numbers in the series follow: 0+3,+2,+1,+3,+1,+2,+3. 11 | ''' 12 | 13 | try: 14 | raw_input # Python 2 15 | except NameError: 16 | raw_input = input # Python 3 17 | n = int(raw_input().strip()) 18 | sum=0 19 | num=0 20 | while(1): 21 | num+=3 22 | if(num>=n): 23 | break 24 | sum+=num 25 | num+=2 26 | if(num>=n): 27 | break 28 | sum+=num 29 | num+=1 30 | if(num>=n): 31 | break 32 | sum+=num 33 | num+=3 34 | if(num>=n): 35 | break 36 | sum+=num 37 | num+=1 38 | if(num>=n): 39 | break 40 | sum+=num 41 | num+=2 42 | if(num>=n): 43 | break 44 | sum+=num 45 | num+=3 46 | if(num>=n): 47 | break 48 | sum+=num 49 | 50 | print(sum); 51 | -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 The Algorithms 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /sorts/cocktail_shaker_sort.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | def cocktail_shaker_sort(unsorted): 4 | """ 5 | Pure implementation of the cocktail shaker sort algorithm in Python. 6 | """ 7 | for i in range(len(unsorted)-1, 0, -1): 8 | swapped = False 9 | 10 | for j in range(i, 0, -1): 11 | if unsorted[j] < unsorted[j-1]: 12 | unsorted[j], unsorted[j-1] = unsorted[j-1], unsorted[j] 13 | swapped = True 14 | 15 | for j in range(i): 16 | if unsorted[j] > unsorted[j+1]: 17 | unsorted[j], unsorted[j+1] = unsorted[j+1], unsorted[j] 18 | swapped = True 19 | 20 | if not swapped: 21 | return unsorted 22 | 23 | if __name__ == '__main__': 24 | try: 25 | raw_input # Python 2 26 | except NameError: 27 | raw_input = input # Python 3 28 | 29 | user_input = raw_input('Enter numbers separated by a comma:\n').strip() 30 | unsorted = [int(item) for item in user_input.split(',')] 31 | cocktail_shaker_sort(unsorted) 32 | print(unsorted) 33 | -------------------------------------------------------------------------------- /other/password_generator.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import string 3 | import random 4 | 5 | letters = [letter for letter in string.ascii_letters] 6 | digits = [digit for digit in string.digits] 7 | symbols = [symbol for symbol in string.punctuation] 8 | chars = letters + digits + symbols 9 | random.shuffle(chars) 10 | 11 | min_length = 8 12 | max_length = 16 13 | password = ''.join(random.choice(chars) for x in range(random.randint(min_length, max_length))) 14 | print('Password: ' + password) 15 | print('[ If you are thinking of using this passsword, You better save it. ]') 16 | 17 | 18 | # ALTERNATIVE METHODS 19 | # ctbi= characters that must be in password 20 | # i= how many letters or characters the password length will be 21 | def password_generator(ctbi, i): 22 | # Password generator = full boot with random_number, random_letters, and random_character FUNCTIONS 23 | pass # Put your code here... 24 | 25 | 26 | def random_number(ctbi, i): 27 | pass # Put your code here... 28 | 29 | 30 | def random_letters(ctbi, i): 31 | pass # Put your code here... 32 | 33 | 34 | def random_characters(ctbi, i): 35 | pass # Put your code here... 36 | -------------------------------------------------------------------------------- /Graphs/scc_kosaraju.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | # n - no of nodes, m - no of edges 3 | n, m = list(map(int,input().split())) 4 | 5 | g = [[] for i in range(n)] #graph 6 | r = [[] for i in range(n)] #reversed graph 7 | # input graph data (edges) 8 | for i in range(m): 9 | u, v = list(map(int,input().split())) 10 | g[u].append(v) 11 | r[v].append(u) 12 | 13 | stack = [] 14 | visit = [False]*n 15 | scc = [] 16 | component = [] 17 | 18 | def dfs(u): 19 | global g, r, scc, component, visit, stack 20 | if visit[u]: return 21 | visit[u] = True 22 | for v in g[u]: 23 | dfs(v) 24 | stack.append(u) 25 | 26 | def dfs2(u): 27 | global g, r, scc, component, visit, stack 28 | if visit[u]: return 29 | visit[u] = True 30 | component.append(u) 31 | for v in r[u]: 32 | dfs2(v) 33 | 34 | def kosaraju(): 35 | global g, r, scc, component, visit, stack 36 | for i in range(n): 37 | dfs(i) 38 | visit = [False]*n 39 | for i in stack[::-1]: 40 | if visit[i]: continue 41 | component = [] 42 | dfs2(i) 43 | scc.append(component) 44 | return scc 45 | 46 | print(kosaraju()) 47 | -------------------------------------------------------------------------------- /Graphs/graph.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # encoding=utf8 3 | 4 | from __future__ import print_function 5 | # Author: OMKAR PATHAK 6 | 7 | # We can use Python's dictionary for constructing the graph 8 | 9 | class AdjacencyList(object): 10 | def __init__(self): 11 | self.List = {} 12 | 13 | def addEdge(self, fromVertex, toVertex): 14 | # check if vertex is already present 15 | if fromVertex in self.List.keys(): 16 | self.List[fromVertex].append(toVertex) 17 | else: 18 | self.List[fromVertex] = [toVertex] 19 | 20 | def printList(self): 21 | for i in self.List: 22 | print((i,'->',' -> '.join([str(j) for j in self.List[i]]))) 23 | 24 | if __name__ == '__main__': 25 | al = AdjacencyList() 26 | al.addEdge(0, 1) 27 | al.addEdge(0, 4) 28 | al.addEdge(4, 1) 29 | al.addEdge(4, 3) 30 | al.addEdge(1, 0) 31 | al.addEdge(1, 4) 32 | al.addEdge(1, 3) 33 | al.addEdge(1, 2) 34 | al.addEdge(2, 3) 35 | al.addEdge(3, 4) 36 | 37 | al.printList() 38 | 39 | # OUTPUT: 40 | # 0 -> 1 -> 4 41 | # 1 -> 0 -> 4 -> 3 -> 2 42 | # 2 -> 3 43 | # 3 -> 4 44 | # 4 -> 1 -> 3 45 | -------------------------------------------------------------------------------- /maths/trapezoidal_rule.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Numerical integration or quadrature for a smooth function f with known values at x_i 3 | 4 | This method is the classical approch of suming 'Equally Spaced Abscissas' 5 | 6 | method 1: 7 | "extended trapezoidal rule" 8 | 9 | ''' 10 | from __future__ import print_function 11 | 12 | def method_1(boundary, steps): 13 | # "extended trapezoidal rule" 14 | # int(f) = dx/2 * (f1 + 2f2 + ... + fn) 15 | h = (boundary[1] - boundary[0]) / steps 16 | a = boundary[0] 17 | b = boundary[1] 18 | x_i = makePoints(a,b,h) 19 | y = 0.0 20 | y += (h/2.0)*f(a) 21 | for i in x_i: 22 | #print(i) 23 | y += h*f(i) 24 | y += (h/2.0)*f(b) 25 | return y 26 | 27 | def makePoints(a,b,h): 28 | x = a + h 29 | while x < (b-h): 30 | yield x 31 | x = x + h 32 | 33 | def f(x): #enter your function here 34 | y = (x-0)*(x-0) 35 | return y 36 | 37 | def main(): 38 | a = 0.0 #Lower bound of integration 39 | b = 1.0 #Upper bound of integration 40 | steps = 10.0 #define number of steps or resolution 41 | boundary = [a, b] #define boundary of integration 42 | y = method_1(boundary, steps) 43 | print('y = {0}'.format(y)) 44 | 45 | if __name__ == '__main__': 46 | main() 47 | -------------------------------------------------------------------------------- /project_euler/problem_21/sol1.py: -------------------------------------------------------------------------------- 1 | #-.- coding: latin-1 -.- 2 | from __future__ import print_function 3 | from math import sqrt 4 | ''' 5 | Amicable Numbers 6 | Problem 21 7 | 8 | Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n). 9 | If d(a) = b and d(b) = a, where a ≠ b, then a and b are an amicable pair and each of a and b are called amicable numbers. 10 | 11 | For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2, 4, 71 and 142; so d(284) = 220. 12 | 13 | Evaluate the sum of all the amicable numbers under 10000. 14 | ''' 15 | try: 16 | xrange #Python 2 17 | except NameError: 18 | xrange = range #Python 3 19 | 20 | def sum_of_divisors(n): 21 | total = 0 22 | for i in xrange(1, int(sqrt(n)+1)): 23 | if n%i == 0 and i != sqrt(n): 24 | total += i + n//i 25 | elif i == sqrt(n): 26 | total += i 27 | 28 | return total-n 29 | 30 | sums = [] 31 | total = 0 32 | 33 | for i in xrange(1, 10000): 34 | n = sum_of_divisors(i) 35 | 36 | if n < len(sums): 37 | if sums[n-1] == i: 38 | total += n + i 39 | 40 | sums.append(n) 41 | 42 | print(total) -------------------------------------------------------------------------------- /project_euler/problem_22/sol1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: latin-1 -*- 2 | from __future__ import print_function 3 | ''' 4 | Name scores 5 | Problem 22 6 | 7 | Using names.txt (right click and 'Save Link/Target As...'), a 46K text file containing over five-thousand first names, begin by sorting it 8 | into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list 9 | to obtain a name score. 10 | 11 | For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. 12 | So, COLIN would obtain a score of 938 × 53 = 49714. 13 | 14 | What is the total of all the name scores in the file? 15 | ''' 16 | try: 17 | xrange #Python 2 18 | except NameError: 19 | xrange = range #Python 3 20 | 21 | with open('p022_names.txt') as file: 22 | names = str(file.readlines()[0]) 23 | names = names.replace('"', '').split(',') 24 | 25 | names.sort() 26 | 27 | name_score = 0 28 | total_score = 0 29 | 30 | for i, name in enumerate(names): 31 | for letter in name: 32 | name_score += ord(letter) - 64 33 | 34 | total_score += (i+1)*name_score 35 | name_score = 0 36 | 37 | print(total_score) -------------------------------------------------------------------------------- /Graphs/DFS.py: -------------------------------------------------------------------------------- 1 | """pseudo-code""" 2 | 3 | """ 4 | DFS(graph G, start vertex s): 5 | // all nodes initially unexplored 6 | mark s as explored 7 | for every edge (s, v): 8 | if v unexplored: 9 | DFS(G, v) 10 | """ 11 | 12 | 13 | def dfs(graph, start): 14 | """The DFS function simply calls itself recursively for every unvisited child of its argument. We can emulate that 15 | behaviour precisely using a stack of iterators. Instead of recursively calling with a node, we'll push an iterator 16 | to the node's children onto the iterator stack. When the iterator at the top of the stack terminates, we'll pop 17 | it off the stack.""" 18 | explored, stack = set(), [start] 19 | explored.add(start) 20 | while stack: 21 | v = stack.pop() # the only difference from BFS is to pop last element here instead of first one 22 | for w in graph[v]: 23 | if w not in explored: 24 | explored.add(w) 25 | stack.append(w) 26 | return explored 27 | 28 | 29 | G = {'A': ['B', 'C'], 30 | 'B': ['A', 'D', 'E'], 31 | 'C': ['A', 'F'], 32 | 'D': ['B'], 33 | 'E': ['B', 'F'], 34 | 'F': ['C', 'E']} 35 | 36 | print(dfs(G, 'A')) 37 | -------------------------------------------------------------------------------- /dynamic_programming/longest_sub_array.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Auther : Yvonne 3 | 4 | This is a pure Python implementation of Dynamic Programming solution to the longest_sub_array problem. 5 | 6 | The problem is : 7 | Given an array, to find the longest and continuous sub array and get the max sum of the sub array in the given array. 8 | ''' 9 | from __future__ import print_function 10 | 11 | 12 | class SubArray: 13 | 14 | def __init__(self, arr): 15 | # we need a list not a string, so do something to change the type 16 | self.array = arr.split(',') 17 | print(("the input array is:", self.array)) 18 | 19 | def solve_sub_array(self): 20 | rear = [int(self.array[0])]*len(self.array) 21 | sum_value = [int(self.array[0])]*len(self.array) 22 | for i in range(1, len(self.array)): 23 | sum_value[i] = max(int(self.array[i]) + sum_value[i-1], int(self.array[i])) 24 | rear[i] = max(sum_value[i], rear[i-1]) 25 | return rear[len(self.array)-1] 26 | 27 | 28 | if __name__ == '__main__': 29 | whole_array = input("please input some numbers:") 30 | array = SubArray(whole_array) 31 | re = array.solve_sub_array() 32 | print(("the results is:", re)) 33 | 34 | -------------------------------------------------------------------------------- /maths/simpson_rule.py: -------------------------------------------------------------------------------- 1 | 2 | ''' 3 | Numerical integration or quadrature for a smooth function f with known values at x_i 4 | 5 | This method is the classical approch of suming 'Equally Spaced Abscissas' 6 | 7 | method 2: 8 | "Simpson Rule" 9 | 10 | ''' 11 | from __future__ import print_function 12 | 13 | 14 | def method_2(boundary, steps): 15 | # "Simpson Rule" 16 | # int(f) = delta_x/2 * (b-a)/3*(f1 + 4f2 + 2f_3 + ... + fn) 17 | h = (boundary[1] - boundary[0]) / steps 18 | a = boundary[0] 19 | b = boundary[1] 20 | x_i = makePoints(a,b,h) 21 | y = 0.0 22 | y += (h/3.0)*f(a) 23 | cnt = 2 24 | for i in x_i: 25 | y += (h/3)*(4-2*(cnt%2))*f(i) 26 | cnt += 1 27 | y += (h/3.0)*f(b) 28 | return y 29 | 30 | def makePoints(a,b,h): 31 | x = a + h 32 | while x < (b-h): 33 | yield x 34 | x = x + h 35 | 36 | def f(x): #enter your function here 37 | y = (x-0)*(x-0) 38 | return y 39 | 40 | def main(): 41 | a = 0.0 #Lower bound of integration 42 | b = 1.0 #Upper bound of integration 43 | steps = 10.0 #define number of steps or resolution 44 | boundary = [a, b] #define boundary of integration 45 | y = method_2(boundary, steps) 46 | print('y = {0}'.format(y)) 47 | 48 | if __name__ == '__main__': 49 | main() 50 | -------------------------------------------------------------------------------- /project_euler/problem_12/sol1.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from math import sqrt 3 | ''' 4 | Highly divisible triangular numbers 5 | Problem 12 6 | The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be: 7 | 8 | 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ... 9 | 10 | Let us list the factors of the first seven triangle numbers: 11 | 12 | 1: 1 13 | 3: 1,3 14 | 6: 1,2,3,6 15 | 10: 1,2,5,10 16 | 15: 1,3,5,15 17 | 21: 1,3,7,21 18 | 28: 1,2,4,7,14,28 19 | We can see that 28 is the first triangle number to have over five divisors. 20 | 21 | What is the value of the first triangle number to have over five hundred divisors? 22 | ''' 23 | try: 24 | xrange #Python 2 25 | except NameError: 26 | xrange = range #Python 3 27 | 28 | def count_divisors(n): 29 | nDivisors = 0 30 | for i in xrange(1, int(sqrt(n))+1): 31 | if n%i == 0: 32 | nDivisors += 2 33 | #check if n is perfect square 34 | if n**0.5 == int(n**0.5): 35 | nDivisors -= 1 36 | return nDivisors 37 | 38 | tNum = 1 39 | i = 1 40 | 41 | while True: 42 | i += 1 43 | tNum += i 44 | 45 | if count_divisors(tNum) > 500: 46 | break 47 | 48 | print(tNum) 49 | -------------------------------------------------------------------------------- /dynamic_programming/longest_common_subsequence.py: -------------------------------------------------------------------------------- 1 | """ 2 | LCS Problem Statement: Given two sequences, find the length of longest subsequence present in both of them. 3 | A subsequence is a sequence that appears in the same relative order, but not necessarily continious. 4 | Example:"abc", "abg" are subsequences of "abcdefgh". 5 | """ 6 | from __future__ import print_function 7 | 8 | try: 9 | xrange # Python 2 10 | except NameError: 11 | xrange = range # Python 3 12 | 13 | def lcs_dp(x, y): 14 | # find the length of strings 15 | m = len(x) 16 | n = len(y) 17 | 18 | # declaring the array for storing the dp values 19 | L = [[None] * (n + 1) for i in xrange(m + 1)] 20 | seq = [] 21 | 22 | for i in range(m + 1): 23 | for j in range(n + 1): 24 | if i == 0 or j == 0: 25 | L[i][j] = 0 26 | elif x[i - 1] == y[ j - 1]: 27 | L[i][j] = L[i - 1][j - 1] + 1 28 | seq.append(x[i -1]) 29 | else: 30 | L[i][j] = max(L[i - 1][j], L[i][j - 1]) 31 | # L[m][n] contains the length of LCS of X[0..n-1] & Y[0..m-1] 32 | return L[m][n], seq 33 | 34 | if __name__=='__main__': 35 | x = 'AGGTAB' 36 | y = 'GXTXAYB' 37 | print(lcs_dp(x, y)) 38 | -------------------------------------------------------------------------------- /project_euler/problem_11/grid.txt: -------------------------------------------------------------------------------- 1 | 08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 2 | 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 3 | 81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 4 | 52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 5 | 22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 6 | 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 7 | 32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 8 | 67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 9 | 24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 10 | 21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 11 | 78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 12 | 16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 13 | 86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 14 | 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 15 | 04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 16 | 88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 17 | 04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 18 | 20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 19 | 20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 20 | 01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48 -------------------------------------------------------------------------------- /sorts/tree_sort.py: -------------------------------------------------------------------------------- 1 | # Tree_sort algorithm 2 | # Build a BST and in order traverse. 3 | 4 | class node(): 5 | # BST data structure 6 | def __init__(self, val): 7 | self.val = val 8 | self.left = None 9 | self.right = None 10 | 11 | def insert(self,val): 12 | if self.val: 13 | if val < self.val: 14 | if self.left is None: 15 | self.left = node(val) 16 | else: 17 | self.left.insert(val) 18 | elif val > self.val: 19 | if self.right is None: 20 | self.right = node(val) 21 | else: 22 | self.right.insert(val) 23 | else: 24 | self.val = val 25 | 26 | def inorder(root, res): 27 | # Recursive travesal 28 | if root: 29 | inorder(root.left,res) 30 | res.append(root.val) 31 | inorder(root.right,res) 32 | 33 | def treesort(arr): 34 | # Build BST 35 | if len(arr) == 0: 36 | return arr 37 | root = node(arr[0]) 38 | for i in range(1,len(arr)): 39 | root.insert(arr[i]) 40 | # Traverse BST in order. 41 | res = [] 42 | inorder(root,res) 43 | return res 44 | 45 | print(treesort([10,1,3,2,9,14,13])) -------------------------------------------------------------------------------- /dynamic_programming/floyd_warshall.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | class Graph: 4 | 5 | def __init__(self, N = 0): # a graph with Node 0,1,...,N-1 6 | self.N = N 7 | self.W = [[math.inf for j in range(0,N)] for i in range(0,N)] # adjacency matrix for weight 8 | self.dp = [[math.inf for j in range(0,N)] for i in range(0,N)] # dp[i][j] stores minimum distance from i to j 9 | 10 | def addEdge(self, u, v, w): 11 | self.dp[u][v] = w 12 | 13 | def floyd_warshall(self): 14 | for k in range(0,self.N): 15 | for i in range(0,self.N): 16 | for j in range(0,self.N): 17 | self.dp[i][j] = min(self.dp[i][j], self.dp[i][k] + self.dp[k][j]) 18 | 19 | def showMin(self, u, v): 20 | return self.dp[u][v] 21 | 22 | if __name__ == '__main__': 23 | graph = Graph(5) 24 | graph.addEdge(0,2,9) 25 | graph.addEdge(0,4,10) 26 | graph.addEdge(1,3,5) 27 | graph.addEdge(2,3,7) 28 | graph.addEdge(3,0,10) 29 | graph.addEdge(3,1,2) 30 | graph.addEdge(3,2,1) 31 | graph.addEdge(3,4,6) 32 | graph.addEdge(4,1,3) 33 | graph.addEdge(4,2,4) 34 | graph.addEdge(4,3,9) 35 | graph.floyd_warshall() 36 | graph.showMin(1,4) 37 | graph.showMin(0,3) 38 | -------------------------------------------------------------------------------- /Maths/extended_euclidean_algorithm.py: -------------------------------------------------------------------------------- 1 | # @Author: S. Sharma 2 | # @Date: 2019-02-25T12:08:53-06:00 3 | # @Email: silentcat@protonmail.com 4 | # @Last modified by: silentcat 5 | # @Last modified time: 2019-02-26T07:07:38-06:00 6 | 7 | import sys 8 | 9 | # Finds 2 numbers a and b such that it satisfies 10 | # the equation am + bn = gcd(m, n) (a.k.a Bezout's Identity) 11 | def extended_euclidean_algorithm(m, n): 12 | a = 0; aprime = 1; b = 1; bprime = 0 13 | q = 0; r = 0 14 | if m > n: 15 | c = m; d = n 16 | else: 17 | c = n; d = m 18 | 19 | while True: 20 | q = int(c / d) 21 | r = c % d 22 | if r == 0: 23 | break 24 | c = d 25 | d = r 26 | 27 | t = aprime 28 | aprime = a 29 | a = t - q*a 30 | 31 | t = bprime 32 | bprime = b 33 | b = t - q*b 34 | 35 | pair = None 36 | if m > n: 37 | pair = (a,b) 38 | else: 39 | pair = (b,a) 40 | return pair 41 | 42 | def main(): 43 | if len(sys.argv) < 3: 44 | print('2 integer arguments required') 45 | exit(1) 46 | m = int(sys.argv[1]) 47 | n = int(sys.argv[2]) 48 | print(extended_euclidean_algorithm(m, n)) 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /data_structures/hashing/double_hash.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from .hash_table import HashTable 4 | from number_theory.prime_numbers import next_prime, check_prime 5 | 6 | 7 | class DoubleHash(HashTable): 8 | """ 9 | Hash Table example with open addressing and Double Hash 10 | """ 11 | def __init__(self, *args, **kwargs): 12 | super().__init__(*args, **kwargs) 13 | 14 | def __hash_function_2(self, value, data): 15 | 16 | next_prime_gt = next_prime(value % self.size_table) \ 17 | if not check_prime(value % self.size_table) else value % self.size_table #gt = bigger than 18 | return next_prime_gt - (data % next_prime_gt) 19 | 20 | def __hash_double_function(self, key, data, increment): 21 | return (increment * self.__hash_function_2(key, data)) % self.size_table 22 | 23 | def _colision_resolution(self, key, data=None): 24 | i = 1 25 | new_key = self.hash_function(data) 26 | 27 | while self.values[new_key] is not None and self.values[new_key] != key: 28 | new_key = self.__hash_double_function(key, data, i) if \ 29 | self.balanced_factor() >= self.lim_charge else None 30 | if new_key is None: break 31 | else: i += 1 32 | 33 | return new_key 34 | -------------------------------------------------------------------------------- /dynamic_programming/integer_partition.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | try: 4 | xrange #Python 2 5 | except NameError: 6 | xrange = range #Python 3 7 | 8 | try: 9 | raw_input #Python 2 10 | except NameError: 11 | raw_input = input #Python 3 12 | 13 | ''' 14 | The number of partitions of a number n into at least k parts equals the number of partitions into exactly k parts 15 | plus the number of partitions into at least k-1 parts. Subtracting 1 from each part of a partition of n into k parts 16 | gives a partition of n-k into k parts. These two facts together are used for this algorithm. 17 | ''' 18 | def partition(m): 19 | memo = [[0 for _ in xrange(m)] for _ in xrange(m+1)] 20 | for i in xrange(m+1): 21 | memo[i][0] = 1 22 | 23 | for n in xrange(m+1): 24 | for k in xrange(1, m): 25 | memo[n][k] += memo[n][k-1] 26 | if n-k > 0: 27 | memo[n][k] += memo[n-k-1][k] 28 | 29 | return memo[m][m-1] 30 | 31 | if __name__ == '__main__': 32 | import sys 33 | 34 | if len(sys.argv) == 1: 35 | try: 36 | n = int(raw_input('Enter a number: ')) 37 | print(partition(n)) 38 | except ValueError: 39 | print('Please enter a number.') 40 | else: 41 | try: 42 | n = int(sys.argv[1]) 43 | print(partition(n)) 44 | except ValueError: 45 | print('Please pass a number.') -------------------------------------------------------------------------------- /other/linear_congruential_generator.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | __author__ = "Tobias Carryer" 3 | 4 | from time import time 5 | 6 | class LinearCongruentialGenerator(object): 7 | """ 8 | A pseudorandom number generator. 9 | """ 10 | 11 | def __init__( self, multiplier, increment, modulo, seed=int(time()) ): 12 | """ 13 | These parameters are saved and used when nextNumber() is called. 14 | 15 | modulo is the largest number that can be generated (exclusive). The most 16 | efficent values are powers of 2. 2^32 is a common value. 17 | """ 18 | self.multiplier = multiplier 19 | self.increment = increment 20 | self.modulo = modulo 21 | self.seed = seed 22 | 23 | def next_number( self ): 24 | """ 25 | The smallest number that can be generated is zero. 26 | The largest number that can be generated is modulo-1. modulo is set in the constructor. 27 | """ 28 | self.seed = (self.multiplier * self.seed + self.increment) % self.modulo 29 | return self.seed 30 | 31 | if __name__ == "__main__": 32 | # Show the LCG in action. 33 | lcg = LinearCongruentialGenerator(1664525, 1013904223, 2<<31) 34 | while True : 35 | print(lcg.next_number()) -------------------------------------------------------------------------------- /Graphs/floyd_warshall.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | def printDist(dist, V): 4 | print("\nThe shortest path matrix using Floyd Warshall algorithm\n") 5 | for i in range(V): 6 | for j in range(V): 7 | if dist[i][j] != float('inf') : 8 | print(int(dist[i][j]),end = "\t") 9 | else: 10 | print("INF",end="\t") 11 | print() 12 | 13 | 14 | 15 | def FloydWarshall(graph, V): 16 | dist=[[float('inf') for i in range(V)] for j in range(V)] 17 | 18 | for i in range(V): 19 | for j in range(V): 20 | dist[i][j] = graph[i][j] 21 | 22 | for k in range(V): 23 | for i in range(V): 24 | for j in range(V): 25 | if dist[i][k]!=float('inf') and dist[k][j]!=float('inf') and dist[i][k]+dist[k][j] < dist[i][j]: 26 | dist[i][j] = dist[i][k] + dist[k][j] 27 | 28 | printDist(dist, V) 29 | 30 | 31 | 32 | #MAIN 33 | V = int(input("Enter number of vertices: ")) 34 | E = int(input("Enter number of edges: ")) 35 | 36 | graph = [[float('inf') for i in range(V)] for j in range(V)] 37 | 38 | for i in range(V): 39 | graph[i][i] = 0.0 40 | 41 | for i in range(E): 42 | print("\nEdge ",i+1) 43 | src = int(input("Enter source:")) 44 | dst = int(input("Enter destination:")) 45 | weight = float(input("Enter weight:")) 46 | graph[src][dst] = weight 47 | 48 | FloydWarshall(graph, V) 49 | -------------------------------------------------------------------------------- /maths/segmented_sieve.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | def sieve(n): 4 | in_prime = [] 5 | start = 2 6 | end = int(math.sqrt(n)) # Size of every segment 7 | temp = [True] * (end + 1) 8 | prime = [] 9 | 10 | while(start <= end): 11 | if temp[start] == True: 12 | in_prime.append(start) 13 | for i in range(start*start, end+1, start): 14 | if temp[i] == True: 15 | temp[i] = False 16 | start += 1 17 | prime += in_prime 18 | 19 | low = end + 1 20 | high = low + end - 1 21 | if high > n: 22 | high = n 23 | 24 | while(low <= n): 25 | temp = [True] * (high-low+1) 26 | for each in in_prime: 27 | 28 | t = math.floor(low / each) * each 29 | if t < low: 30 | t += each 31 | 32 | for j in range(t, high+1, each): 33 | temp[j - low] = False 34 | 35 | for j in range(len(temp)): 36 | if temp[j] == True: 37 | prime.append(j+low) 38 | 39 | low = high + 1 40 | high = low + end - 1 41 | if high > n: 42 | high = n 43 | 44 | return prime 45 | 46 | print(sieve(10**6)) -------------------------------------------------------------------------------- /file_transfer_protocol/ftp_send_receive.py: -------------------------------------------------------------------------------- 1 | """ 2 | File transfer protocol used to send and receive files using FTP server. 3 | Use credentials to provide access to the FTP client 4 | 5 | Note: Do not use root username & password for security reasons 6 | Create a seperate user and provide access to a home directory of the user 7 | Use login id and password of the user created 8 | cwd here stands for current working directory 9 | """ 10 | 11 | from ftplib import FTP 12 | ftp = FTP('xxx.xxx.x.x') # Enter the ip address or the domain name here 13 | ftp.login(user='username', passwd='password') 14 | ftp.cwd('/Enter the directory here/') 15 | 16 | """ 17 | The file which will be received via the FTP server 18 | Enter the location of the file where the file is received 19 | """ 20 | 21 | def ReceiveFile(): 22 | FileName = 'example.txt' """ Enter the location of the file """ 23 | with open(FileName, 'wb') as LocalFile: 24 | ftp.retrbinary('RETR ' + FileName, LocalFile.write, 1024) 25 | ftp.quit() 26 | 27 | """ 28 | The file which will be sent via the FTP server 29 | The file send will be send to the current working directory 30 | """ 31 | 32 | def SendFile(): 33 | FileName = 'example.txt' """ Enter the name of the file """ 34 | with open(FileName, 'rb') as LocalFile: 35 | ftp.storbinary('STOR ' + FileName, LocalFile) 36 | ftp.quit() 37 | -------------------------------------------------------------------------------- /dynamic_programming/fastfibonacci.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # encoding=utf8 3 | 4 | """ 5 | This program calculates the nth Fibonacci number in O(log(n)). 6 | It's possible to calculate F(1000000) in less than a second. 7 | """ 8 | from __future__ import print_function 9 | import sys 10 | 11 | 12 | # returns F(n) 13 | def fibonacci(n: int): # noqa: E999 This syntax is Python 3 only 14 | if n < 0: 15 | raise ValueError("Negative arguments are not supported") 16 | return _fib(n)[0] 17 | 18 | 19 | # returns (F(n), F(n-1)) 20 | def _fib(n: int): # noqa: E999 This syntax is Python 3 only 21 | if n == 0: 22 | # (F(0), F(1)) 23 | return (0, 1) 24 | else: 25 | # F(2n) = F(n)[2F(n+1) − F(n)] 26 | # F(2n+1) = F(n+1)^2+F(n)^2 27 | a, b = _fib(n // 2) 28 | c = a * (b * 2 - a) 29 | d = a * a + b * b 30 | if n % 2 == 0: 31 | return (c, d) 32 | else: 33 | return (d, c + d) 34 | 35 | 36 | if __name__ == "__main__": 37 | args = sys.argv[1:] 38 | if len(args) != 1: 39 | print("Too few or too much parameters given.") 40 | exit(1) 41 | try: 42 | n = int(args[0]) 43 | except ValueError: 44 | print("Could not convert data to an integer.") 45 | exit(1) 46 | print("F(%d) = %d" % (n, fibonacci(n))) 47 | -------------------------------------------------------------------------------- /ciphers/transposition_cipher_encrypt_decrypt_file.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import time, os, sys 3 | import transposition_cipher as transCipher 4 | 5 | def main(): 6 | inputFile = 'Prehistoric Men.txt' 7 | outputFile = 'Output.txt' 8 | key = int(input('Enter key: ')) 9 | mode = input('Encrypt/Decrypt [e/d]: ') 10 | 11 | if not os.path.exists(inputFile): 12 | print('File %s does not exist. Quitting...' % inputFile) 13 | sys.exit() 14 | if os.path.exists(outputFile): 15 | print('Overwrite %s? [y/n]' % outputFile) 16 | response = input('> ') 17 | if not response.lower().startswith('y'): 18 | sys.exit() 19 | 20 | startTime = time.time() 21 | if mode.lower().startswith('e'): 22 | with open(inputFile) as f: 23 | content = f.read() 24 | translated = transCipher.encryptMessage(key, content) 25 | elif mode.lower().startswith('d'): 26 | with open(outputFile) as f: 27 | content = f.read() 28 | translated =transCipher .decryptMessage(key, content) 29 | 30 | with open(outputFile, 'w') as outputObj: 31 | outputObj.write(translated) 32 | 33 | totalTime = round(time.time() - startTime, 2) 34 | print(('Done (', totalTime, 'seconds )')) 35 | 36 | if __name__ == '__main__': 37 | main() 38 | -------------------------------------------------------------------------------- /project_euler/problem_19/sol1.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | ''' 3 | Counting Sundays 4 | Problem 19 5 | 6 | You are given the following information, but you may prefer to do some research for yourself. 7 | 8 | 1 Jan 1900 was a Monday. 9 | Thirty days has September, 10 | April, June and November. 11 | All the rest have thirty-one, 12 | Saving February alone, 13 | Which has twenty-eight, rain or shine. 14 | And on leap years, twenty-nine. 15 | 16 | A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400. 17 | 18 | How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)? 19 | ''' 20 | 21 | days_per_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 22 | 23 | day = 6 24 | month = 1 25 | year = 1901 26 | 27 | sundays = 0 28 | 29 | while year < 2001: 30 | day += 7 31 | 32 | if (year%4 == 0 and not year%100 == 0) or (year%400 == 0): 33 | if day > days_per_month[month-1] and month is not 2: 34 | month += 1 35 | day = day-days_per_month[month-2] 36 | elif day > 29 and month is 2: 37 | month += 1 38 | day = day-29 39 | else: 40 | if day > days_per_month[month-1]: 41 | month += 1 42 | day = day-days_per_month[month-2] 43 | 44 | if month > 12: 45 | year += 1 46 | month = 1 47 | 48 | if year < 2001 and day is 1: 49 | sundays += 1 50 | 51 | print(sundays) -------------------------------------------------------------------------------- /project_euler/problem_31/sol1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import print_function 3 | try: 4 | raw_input # Python 2 5 | except NameError: 6 | raw_input = input # Python 3 7 | ''' 8 | Coin sums 9 | Problem 31 10 | In England the currency is made up of pound, £, and pence, p, and there are 11 | eight coins in general circulation: 12 | 13 | 1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p). 14 | It is possible to make £2 in the following way: 15 | 16 | 1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p 17 | How many different ways can £2 be made using any number of coins? 18 | ''' 19 | 20 | 21 | def one_pence(): 22 | return 1 23 | 24 | 25 | def two_pence(x): 26 | return 0 if x < 0 else two_pence(x - 2) + one_pence() 27 | 28 | 29 | def five_pence(x): 30 | return 0 if x < 0 else five_pence(x - 5) + two_pence(x) 31 | 32 | 33 | def ten_pence(x): 34 | return 0 if x < 0 else ten_pence(x - 10) + five_pence(x) 35 | 36 | 37 | def twenty_pence(x): 38 | return 0 if x < 0 else twenty_pence(x - 20) + ten_pence(x) 39 | 40 | 41 | def fifty_pence(x): 42 | return 0 if x < 0 else fifty_pence(x - 50) + twenty_pence(x) 43 | 44 | 45 | def one_pound(x): 46 | return 0 if x < 0 else one_pound(x - 100) + fifty_pence(x) 47 | 48 | 49 | def two_pound(x): 50 | return 0 if x < 0 else two_pound(x - 200) + one_pound(x) 51 | 52 | 53 | print(two_pound(200)) 54 | -------------------------------------------------------------------------------- /sorts/bubble_sort.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | 4 | def bubble_sort(collection): 5 | """Pure implementation of bubble sort algorithm in Python 6 | 7 | :param collection: some mutable ordered collection with heterogeneous 8 | comparable items inside 9 | :return: the same collection ordered by ascending 10 | 11 | Examples: 12 | >>> bubble_sort([0, 5, 3, 2, 2]) 13 | [0, 2, 2, 3, 5] 14 | 15 | >>> bubble_sort([]) 16 | [] 17 | 18 | >>> bubble_sort([-2, -5, -45]) 19 | [-45, -5, -2] 20 | 21 | >>> bubble_sort([-23,0,6,-4,34]) 22 | [-23,-4,0,6,34] 23 | """ 24 | length = len(collection) 25 | for i in range(length-1): 26 | swapped = False 27 | for j in range(length-1-i): 28 | if collection[j] > collection[j+1]: 29 | swapped = True 30 | collection[j], collection[j+1] = collection[j+1], collection[j] 31 | if not swapped: break # Stop iteration if the collection is sorted. 32 | return collection 33 | 34 | 35 | if __name__ == '__main__': 36 | try: 37 | raw_input # Python 2 38 | except NameError: 39 | raw_input = input # Python 3 40 | user_input = raw_input('Enter numbers separated by a comma:').strip() 41 | unsorted = [int(item) for item in user_input.split(',')] 42 | print(*bubble_sort(unsorted), sep=',') 43 | -------------------------------------------------------------------------------- /analysis/compression_analysis/psnr.py: -------------------------------------------------------------------------------- 1 | """ 2 | Peak signal-to-noise ratio - PSNR - https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio 3 | Soruce: https://tutorials.techonical.com/how-to-calculate-psnr-value-of-two-images-using-python/ 4 | """ 5 | 6 | import math 7 | import os 8 | 9 | import cv2 10 | import numpy as np 11 | 12 | def psnr(original, contrast): 13 | mse = np.mean((original - contrast) ** 2) 14 | if mse == 0: 15 | return 100 16 | PIXEL_MAX = 255.0 17 | PSNR = 20 * math.log10(PIXEL_MAX / math.sqrt(mse)) 18 | return PSNR 19 | 20 | 21 | def main(): 22 | dir_path = os.path.dirname(os.path.realpath(__file__)) 23 | # Loading images (original image and compressed image) 24 | original = cv2.imread(os.path.join(dir_path, 'original_image.png')) 25 | contrast = cv2.imread(os.path.join(dir_path, 'compressed_image.png'), 1) 26 | 27 | original2 = cv2.imread(os.path.join(dir_path, 'PSNR-example-base.png')) 28 | contrast2 = cv2.imread(os.path.join(dir_path, 'PSNR-example-comp-10.jpg'), 1) 29 | 30 | # Value expected: 29.73dB 31 | print("-- First Test --") 32 | print(f"PSNR value is {psnr(original, contrast)} dB") 33 | 34 | # # Value expected: 31.53dB (Wikipedia Example) 35 | print("\n-- Second Test --") 36 | print(f"PSNR value is {psnr(original2, contrast2)} dB") 37 | 38 | 39 | if __name__ == '__main__': 40 | main() 41 | -------------------------------------------------------------------------------- /data_structures/queue/queue_on_list.py: -------------------------------------------------------------------------------- 1 | """Queue represented by a python list""" 2 | class Queue(): 3 | def __init__(self): 4 | self.entries = [] 5 | self.length = 0 6 | self.front=0 7 | 8 | def __str__(self): 9 | printed = '<' + str(self.entries)[1:-1] + '>' 10 | return printed 11 | 12 | """Enqueues {@code item} 13 | @param item 14 | item to enqueue""" 15 | def put(self, item): 16 | self.entries.append(item) 17 | self.length = self.length + 1 18 | 19 | 20 | """Dequeues {@code item} 21 | @requirement: |self.length| > 0 22 | @return dequeued 23 | item that was dequeued""" 24 | def get(self): 25 | self.length = self.length - 1 26 | dequeued = self.entries[self.front] 27 | self.front-=1 28 | self.entries = self.entries[self.front:] 29 | return dequeued 30 | 31 | """Rotates the queue {@code rotation} times 32 | @param rotation 33 | number of times to rotate queue""" 34 | def rotate(self, rotation): 35 | for i in range(rotation): 36 | self.put(self.get()) 37 | 38 | """Enqueues {@code item} 39 | @return item at front of self.entries""" 40 | def front(self): 41 | return self.entries[0] 42 | 43 | """Returns the length of this.entries""" 44 | def size(self): 45 | return self.length 46 | -------------------------------------------------------------------------------- /Graphs/articulation_points.py: -------------------------------------------------------------------------------- 1 | # Finding Articulation Points in Undirected Graph 2 | def computeAP(l): 3 | n = len(l) 4 | outEdgeCount = 0 5 | low = [0] * n 6 | visited = [False] * n 7 | isArt = [False] * n 8 | 9 | def dfs(root, at, parent, outEdgeCount): 10 | if parent == root: 11 | outEdgeCount += 1 12 | visited[at] = True 13 | low[at] = at 14 | 15 | for to in l[at]: 16 | if to == parent: 17 | pass 18 | elif not visited[to]: 19 | outEdgeCount = dfs(root, to, at, outEdgeCount) 20 | low[at] = min(low[at], low[to]) 21 | 22 | # AP found via bridge 23 | if at < low[to]: 24 | isArt[at] = True 25 | # AP found via cycle 26 | if at == low[to]: 27 | isArt[at] = True 28 | else: 29 | low[at] = min(low[at], to) 30 | return outEdgeCount 31 | 32 | for i in range(n): 33 | if not visited[i]: 34 | outEdgeCount = 0 35 | outEdgeCount = dfs(i, i, -1, outEdgeCount) 36 | isArt[i] = (outEdgeCount > 1) 37 | 38 | for x in range(len(isArt)): 39 | if isArt[x] == True: 40 | print(x) 41 | 42 | # Adjacency list of graph 43 | l = {0:[1,2], 1:[0,2], 2:[0,1,3,5], 3:[2,4], 4:[3], 5:[2,6,8], 6:[5,7], 7:[6,8], 8:[5,7]} 44 | computeAP(l) 45 | -------------------------------------------------------------------------------- /Graphs/check_bipartite_graph_bfs.py: -------------------------------------------------------------------------------- 1 | # Check whether Graph is Bipartite or Not using BFS 2 | 3 | # A Bipartite Graph is a graph whose vertices can be divided into two independent sets, 4 | # U and V such that every edge (u, v) either connects a vertex from U to V or a vertex 5 | # from V to U. In other words, for every edge (u, v), either u belongs to U and v to V, 6 | # or u belongs to V and v to U. We can also say that there is no edge that connects 7 | # vertices of same set. 8 | def checkBipartite(l): 9 | queue = [] 10 | visited = [False] * len(l) 11 | color = [-1] * len(l) 12 | 13 | def bfs(): 14 | while(queue): 15 | u = queue.pop(0) 16 | visited[u] = True 17 | 18 | for neighbour in l[u]: 19 | 20 | if neighbour == u: 21 | return False 22 | 23 | if color[neighbour] == -1: 24 | color[neighbour] = 1 - color[u] 25 | queue.append(neighbour) 26 | 27 | elif color[neighbour] == color[u]: 28 | return False 29 | 30 | return True 31 | 32 | for i in range(len(l)): 33 | if not visited[i]: 34 | queue.append(i) 35 | color[i] = 0 36 | if bfs() == False: 37 | return False 38 | 39 | return True 40 | 41 | # Adjacency List of graph 42 | l = {0:[1,3], 1:[0,2], 2:[1,3], 3:[0,2]} 43 | print(checkBipartite(l)) 44 | -------------------------------------------------------------------------------- /other/binary_exponentiation.py: -------------------------------------------------------------------------------- 1 | """ 2 | * Binary Exponentiation for Powers 3 | * This is a method to find a^b in a time complexity of O(log b) 4 | * This is one of the most commonly used methods of finding powers. 5 | * Also useful in cases where solution to (a^b)%c is required, 6 | * where a,b,c can be numbers over the computers calculation limits. 7 | * Done using iteration, can also be done using recursion 8 | 9 | * @author chinmoy159 10 | * @version 1.0 dated 10/08/2017 11 | """ 12 | 13 | 14 | def b_expo(a, b): 15 | res = 1 16 | while b > 0: 17 | if b&1: 18 | res *= a 19 | 20 | a *= a 21 | b >>= 1 22 | 23 | return res 24 | 25 | 26 | def b_expo_mod(a, b, c): 27 | res = 1 28 | while b > 0: 29 | if b&1: 30 | res = ((res%c) * (a%c)) % c 31 | 32 | a *= a 33 | b >>= 1 34 | 35 | return res 36 | 37 | """ 38 | * Wondering how this method works ! 39 | * It's pretty simple. 40 | * Let's say you need to calculate a ^ b 41 | * RULE 1 : a ^ b = (a*a) ^ (b/2) ---- example : 4 ^ 4 = (4*4) ^ (4/2) = 16 ^ 2 42 | * RULE 2 : IF b is ODD, then ---- a ^ b = a * (a ^ (b - 1)) :: where (b - 1) is even. 43 | * Once b is even, repeat the process to get a ^ b 44 | * Repeat the process till b = 1 OR b = 0, because a^1 = a AND a^0 = 1 45 | * 46 | * As far as the modulo is concerned, 47 | * the fact : (a*b) % c = ((a%c) * (b%c)) % c 48 | * Now apply RULE 1 OR 2 whichever is required. 49 | """ 50 | -------------------------------------------------------------------------------- /digital_image_processing/filters/median_filter.py: -------------------------------------------------------------------------------- 1 | """ 2 | Implementation of median filter algorithm 3 | """ 4 | 5 | from cv2 import imread, cvtColor, COLOR_BGR2GRAY, imshow, waitKey 6 | from numpy import zeros_like, ravel, sort, multiply, divide, int8 7 | 8 | 9 | def median_filter(gray_img, mask=3): 10 | """ 11 | :param gray_img: gray image 12 | :param mask: mask size 13 | :return: image with median filter 14 | """ 15 | # set image borders 16 | bd = int(mask / 2) 17 | # copy image size 18 | median_img = zeros_like(gray) 19 | for i in range(bd, gray_img.shape[0] - bd): 20 | for j in range(bd, gray_img.shape[1] - bd): 21 | # get mask according with mask 22 | kernel = ravel(gray_img[i - bd:i + bd + 1, j - bd:j + bd + 1]) 23 | # calculate mask median 24 | median = sort(kernel)[int8(divide((multiply(mask, mask)), 2) + 1)] 25 | median_img[i, j] = median 26 | return median_img 27 | 28 | 29 | if __name__ == '__main__': 30 | # read original image 31 | img = imread('lena.jpg') 32 | # turn image in gray scale value 33 | gray = cvtColor(img, COLOR_BGR2GRAY) 34 | 35 | # get values with two different mask size 36 | median3x3 = median_filter(gray, 3) 37 | median5x5 = median_filter(gray, 5) 38 | 39 | # show result images 40 | imshow('median filter with 3x3 mask', median3x3) 41 | imshow('median filter with 5x5 mask', median5x5) 42 | waitKey(0) 43 | -------------------------------------------------------------------------------- /dynamic_programming/knapsack.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given weights and values of n items, put these items in a knapsack of capacity W to get the maximum total value in the knapsack. 3 | """ 4 | def MF_knapsack(i,wt,val,j): 5 | ''' 6 | This code involves the concept of memory functions. Here we solve the subproblems which are needed 7 | unlike the below example 8 | F is a 2D array with -1s filled up 9 | ''' 10 | global F # a global dp table for knapsack 11 | if F[i][j] < 0: 12 | if j < wt[i - 1]: 13 | val = MF_knapsack(i - 1,wt,val,j) 14 | else: 15 | val = max(MF_knapsack(i - 1,wt,val,j),MF_knapsack(i - 1,wt,val,j - wt[i - 1]) + val[i - 1]) 16 | F[i][j] = val 17 | return F[i][j] 18 | 19 | def knapsack(W, wt, val, n): 20 | dp = [[0 for i in range(W+1)]for j in range(n+1)] 21 | 22 | for i in range(1,n+1): 23 | for w in range(1,W+1): 24 | if(wt[i-1]<=w): 25 | dp[i][w] = max(val[i-1]+dp[i-1][w-wt[i-1]],dp[i-1][w]) 26 | else: 27 | dp[i][w] = dp[i-1][w] 28 | 29 | return dp[n][w] 30 | 31 | if __name__ == '__main__': 32 | ''' 33 | Adding test case for knapsack 34 | ''' 35 | val = [3,2,4,4] 36 | wt = [4,3,2,3] 37 | n = 4 38 | w = 6 39 | F = [[0]*(w + 1)] + [[0] + [-1 for i in range(w + 1)] for j in range(n + 1)] 40 | print(knapsack(w,wt,val,n)) 41 | print(MF_knapsack(n,wt,val,w)) # switched the n and w 42 | 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .vscode/ 11 | .Python 12 | env/ 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *,cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # IPython Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # dotenv 80 | .env 81 | 82 | # virtualenv 83 | venv/ 84 | ENV/ 85 | 86 | # Spyder project settings 87 | .spyderproject 88 | 89 | # Rope project settings 90 | .ropeproject 91 | .idea 92 | .DS_Store -------------------------------------------------------------------------------- /Graphs/bellman_ford.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | def printDist(dist, V): 4 | print("\nVertex Distance") 5 | for i in range(V): 6 | if dist[i] != float('inf') : 7 | print(i,"\t",int(dist[i]),end = "\t") 8 | else: 9 | print(i,"\t","INF",end="\t") 10 | print() 11 | 12 | def BellmanFord(graph, V, E, src): 13 | mdist=[float('inf') for i in range(V)] 14 | mdist[src] = 0.0 15 | 16 | for i in range(V-1): 17 | for j in range(V): 18 | u = graph[j]["src"] 19 | v = graph[j]["dst"] 20 | w = graph[j]["weight"] 21 | 22 | if mdist[u] != float('inf') and mdist[u] + w < mdist[v]: 23 | mdist[v] = mdist[u] + w 24 | for j in range(V): 25 | u = graph[j]["src"] 26 | v = graph[j]["dst"] 27 | w = graph[j]["weight"] 28 | 29 | if mdist[u] != float('inf') and mdist[u] + w < mdist[v]: 30 | print("Negative cycle found. Solution not possible.") 31 | return 32 | 33 | printDist(mdist, V) 34 | 35 | 36 | 37 | #MAIN 38 | V = int(input("Enter number of vertices: ")) 39 | E = int(input("Enter number of edges: ")) 40 | 41 | graph = [dict() for j in range(E)] 42 | 43 | for i in range(V): 44 | graph[i][i] = 0.0 45 | 46 | for i in range(E): 47 | print("\nEdge ",i+1) 48 | src = int(input("Enter source:")) 49 | dst = int(input("Enter destination:")) 50 | weight = float(input("Enter weight:")) 51 | graph[i] = {"src": src,"dst": dst, "weight": weight} 52 | 53 | gsrc = int(input("\nEnter shortest path source:")) 54 | BellmanFord(graph, V, E, gsrc) 55 | -------------------------------------------------------------------------------- /other/binary_exponentiation_2.py: -------------------------------------------------------------------------------- 1 | """ 2 | * Binary Exponentiation with Multiplication 3 | * This is a method to find a*b in a time complexity of O(log b) 4 | * This is one of the most commonly used methods of finding result of multiplication. 5 | * Also useful in cases where solution to (a*b)%c is required, 6 | * where a,b,c can be numbers over the computers calculation limits. 7 | * Done using iteration, can also be done using recursion 8 | 9 | * @author chinmoy159 10 | * @version 1.0 dated 10/08/2017 11 | """ 12 | 13 | 14 | def b_expo(a, b): 15 | res = 0 16 | while b > 0: 17 | if b&1: 18 | res += a 19 | 20 | a += a 21 | b >>= 1 22 | 23 | return res 24 | 25 | 26 | def b_expo_mod(a, b, c): 27 | res = 0 28 | while b > 0: 29 | if b&1: 30 | res = ((res%c) + (a%c)) % c 31 | 32 | a += a 33 | b >>= 1 34 | 35 | return res 36 | 37 | 38 | """ 39 | * Wondering how this method works ! 40 | * It's pretty simple. 41 | * Let's say you need to calculate a ^ b 42 | * RULE 1 : a * b = (a+a) * (b/2) ---- example : 4 * 4 = (4+4) * (4/2) = 8 * 2 43 | * RULE 2 : IF b is ODD, then ---- a * b = a + (a * (b - 1)) :: where (b - 1) is even. 44 | * Once b is even, repeat the process to get a * b 45 | * Repeat the process till b = 1 OR b = 0, because a*1 = a AND a*0 = 0 46 | * 47 | * As far as the modulo is concerned, 48 | * the fact : (a+b) % c = ((a%c) + (b%c)) % c 49 | * Now apply RULE 1 OR 2, whichever is required. 50 | """ 51 | -------------------------------------------------------------------------------- /Graphs/dijkstra_2.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | def printDist(dist, V): 4 | print("\nVertex Distance") 5 | for i in range(V): 6 | if dist[i] != float('inf') : 7 | print(i,"\t",int(dist[i]),end = "\t") 8 | else: 9 | print(i,"\t","INF",end="\t") 10 | print() 11 | 12 | def minDist(mdist, vset, V): 13 | minVal = float('inf') 14 | minInd = -1 15 | for i in range(V): 16 | if (not vset[i]) and mdist[i] < minVal : 17 | minInd = i 18 | minVal = mdist[i] 19 | return minInd 20 | 21 | def Dijkstra(graph, V, src): 22 | mdist=[float('inf') for i in range(V)] 23 | vset = [False for i in range(V)] 24 | mdist[src] = 0.0 25 | 26 | for i in range(V-1): 27 | u = minDist(mdist, vset, V) 28 | vset[u] = True 29 | 30 | for v in range(V): 31 | if (not vset[v]) and graph[u][v]!=float('inf') and mdist[u] + graph[u][v] < mdist[v]: 32 | mdist[v] = mdist[u] + graph[u][v] 33 | 34 | 35 | 36 | printDist(mdist, V) 37 | 38 | 39 | 40 | #MAIN 41 | V = int(input("Enter number of vertices: ")) 42 | E = int(input("Enter number of edges: ")) 43 | 44 | graph = [[float('inf') for i in range(V)] for j in range(V)] 45 | 46 | for i in range(V): 47 | graph[i][i] = 0.0 48 | 49 | for i in range(E): 50 | print("\nEdge ",i+1) 51 | src = int(input("Enter source:")) 52 | dst = int(input("Enter destination:")) 53 | weight = float(input("Enter weight:")) 54 | graph[src][dst] = weight 55 | 56 | gsrc = int(input("\nEnter shortest path source:")) 57 | Dijkstra(graph, V, gsrc) 58 | -------------------------------------------------------------------------------- /sorts/insertion_sort.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a pure python implementation of the insertion sort algorithm 3 | 4 | For doctests run following command: 5 | python -m doctest -v insertion_sort.py 6 | or 7 | python3 -m doctest -v insertion_sort.py 8 | 9 | For manual testing run: 10 | python insertion_sort.py 11 | """ 12 | from __future__ import print_function 13 | 14 | 15 | def insertion_sort(collection): 16 | """Pure implementation of the insertion sort algorithm in Python 17 | 18 | :param collection: some mutable ordered collection with heterogeneous 19 | comparable items inside 20 | :return: the same collection ordered by ascending 21 | 22 | Examples: 23 | >>> insertion_sort([0, 5, 3, 2, 2]) 24 | [0, 2, 2, 3, 5] 25 | 26 | >>> insertion_sort([]) 27 | [] 28 | 29 | >>> insertion_sort([-2, -5, -45]) 30 | [-45, -5, -2] 31 | """ 32 | for index in range(1, len(collection)): 33 | while index > 0 and collection[index - 1] > collection[index]: 34 | collection[index], collection[index - 1] = collection[index - 1], collection[index] 35 | index -= 1 36 | 37 | return collection 38 | 39 | 40 | if __name__ == '__main__': 41 | try: 42 | raw_input # Python 2 43 | except NameError: 44 | raw_input = input # Python 3 45 | 46 | user_input = raw_input('Enter numbers separated by a comma:\n').strip() 47 | unsorted = [int(item) for item in user_input.split(',')] 48 | print(insertion_sort(unsorted)) 49 | -------------------------------------------------------------------------------- /Graphs/dijkstra.py: -------------------------------------------------------------------------------- 1 | """pseudo-code""" 2 | 3 | """ 4 | DIJKSTRA(graph G, start vertex s,destination vertex d): 5 | // all nodes initially unexplored 6 | let H = min heap data structure, initialized with 0 and s [here 0 indicates the distance from start vertex] 7 | while H is non-empty: 8 | remove the first node and cost of H, call it U and cost 9 | if U is not explored 10 | mark U as explored 11 | if U is d: 12 | return cost // total cost from start to destination vertex 13 | for each edge(U, V): c=cost of edge(u,V) // for V in graph[U] 14 | if V unexplored: 15 | next=cost+c 16 | add next,V to H (at the end) 17 | """ 18 | import heapq 19 | 20 | 21 | def dijkstra(graph, start, end): 22 | heap = [(0, start)] # cost from start node,end node 23 | visited = [] 24 | while heap: 25 | (cost, u) = heapq.heappop(heap) 26 | if u in visited: 27 | continue 28 | visited.append(u) 29 | if u == end: 30 | return cost 31 | for v, c in G[u]: 32 | if v in visited: 33 | continue 34 | next = cost + c 35 | heapq.heappush(heap, (next, v)) 36 | return (-1, -1) 37 | 38 | 39 | G = {'A': [['B', 2], ['C', 5]], 40 | 'B': [['A', 2], ['D', 3], ['E', 1]], 41 | 'C': [['A', 5], ['F', 3]], 42 | 'D': [['B', 3]], 43 | 'E': [['B', 1], ['F', 3]], 44 | 'F': [['C', 3], ['E', 3]]} 45 | 46 | shortDistance = dijkstra(G, 'E', 'C') 47 | print(shortDistance) 48 | -------------------------------------------------------------------------------- /other/nested_brackets.py: -------------------------------------------------------------------------------- 1 | ''' 2 | The nested brackets problem is a problem that determines if a sequence of 3 | brackets are properly nested. A sequence of brackets s is considered properly nested 4 | if any of the following conditions are true: 5 | 6 | - s is empty 7 | - s has the form (U) or [U] or {U} where U is a properly nested string 8 | - s has the form VW where V and W are properly nested strings 9 | 10 | For example, the string "()()[()]" is properly nested but "[(()]" is not. 11 | 12 | The function called is_balanced takes as input a string S which is a sequence of brackets and 13 | returns true if S is nested and false otherwise. 14 | 15 | ''' 16 | from __future__ import print_function 17 | 18 | 19 | def is_balanced(S): 20 | 21 | stack = [] 22 | open_brackets = set({'(', '[', '{'}) 23 | closed_brackets = set({')', ']', '}'}) 24 | open_to_closed = dict({'{':'}', '[':']', '(':')'}) 25 | 26 | for i in range(len(S)): 27 | 28 | if S[i] in open_brackets: 29 | stack.append(S[i]) 30 | 31 | elif S[i] in closed_brackets: 32 | if len(stack) == 0 or (len(stack) > 0 and open_to_closed[stack.pop()] != S[i]): 33 | return False 34 | 35 | return len(stack) == 0 36 | 37 | 38 | def main(): 39 | 40 | S = input("Enter sequence of brackets: ") 41 | 42 | if is_balanced(S): 43 | print((S, "is balanced")) 44 | 45 | else: 46 | print((S, "is not balanced")) 47 | 48 | 49 | if __name__ == "__main__": 50 | main() 51 | -------------------------------------------------------------------------------- /sorts/bogosort.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a pure python implementation of the bogosort algorithm 3 | For doctests run following command: 4 | python -m doctest -v bogosort.py 5 | or 6 | python3 -m doctest -v bogosort.py 7 | For manual testing run: 8 | python bogosort.py 9 | """ 10 | 11 | from __future__ import print_function 12 | import random 13 | 14 | 15 | def bogosort(collection): 16 | """Pure implementation of the bogosort algorithm in Python 17 | :param collection: some mutable ordered collection with heterogeneous 18 | comparable items inside 19 | :return: the same collection ordered by ascending 20 | Examples: 21 | >>> bogosort([0, 5, 3, 2, 2]) 22 | [0, 2, 2, 3, 5] 23 | >>> bogosort([]) 24 | [] 25 | >>> bogosort([-2, -5, -45]) 26 | [-45, -5, -2] 27 | """ 28 | 29 | def isSorted(collection): 30 | if len(collection) < 2: 31 | return True 32 | for i in range(len(collection) - 1): 33 | if collection[i] > collection[i + 1]: 34 | return False 35 | return True 36 | 37 | while not isSorted(collection): 38 | random.shuffle(collection) 39 | return collection 40 | 41 | if __name__ == '__main__': 42 | try: 43 | raw_input # Python 2 44 | except NameError: 45 | raw_input = input # Python 3 46 | 47 | user_input = raw_input('Enter numbers separated by a comma:\n').strip() 48 | unsorted = [int(item) for item in user_input.split(',')] 49 | print(bogosort(unsorted)) 50 | -------------------------------------------------------------------------------- /sorts/quick_sort.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a pure python implementation of the quick sort algorithm 3 | 4 | For doctests run following command: 5 | python -m doctest -v quick_sort.py 6 | or 7 | python3 -m doctest -v quick_sort.py 8 | 9 | For manual testing run: 10 | python quick_sort.py 11 | """ 12 | from __future__ import print_function 13 | 14 | 15 | def quick_sort(ARRAY): 16 | """Pure implementation of quick sort algorithm in Python 17 | 18 | :param collection: some mutable ordered collection with heterogeneous 19 | comparable items inside 20 | :return: the same collection ordered by ascending 21 | 22 | Examples: 23 | >>> quick_sort([0, 5, 3, 2, 2]) 24 | [0, 2, 2, 3, 5] 25 | 26 | >>> quick_sort([]) 27 | [] 28 | 29 | >>> quick_sort([-2, -5, -45]) 30 | [-45, -5, -2] 31 | """ 32 | ARRAY_LENGTH = len(ARRAY) 33 | if( ARRAY_LENGTH <= 1): 34 | return ARRAY 35 | else: 36 | PIVOT = ARRAY[0] 37 | GREATER = [ element for element in ARRAY[1:] if element > PIVOT ] 38 | LESSER = [ element for element in ARRAY[1:] if element <= PIVOT ] 39 | return quick_sort(LESSER) + [PIVOT] + quick_sort(GREATER) 40 | 41 | 42 | if __name__ == '__main__': 43 | try: 44 | raw_input # Python 2 45 | except NameError: 46 | raw_input = input # Python 3 47 | 48 | user_input = raw_input('Enter numbers separated by a comma:\n').strip() 49 | unsorted = [ int(item) for item in user_input.split(',') ] 50 | print( quick_sort(unsorted) ) 51 | -------------------------------------------------------------------------------- /machine_learning/Random Forest Regression/random_forest_regression.py: -------------------------------------------------------------------------------- 1 | # Random Forest Regression 2 | 3 | # Importing the libraries 4 | import numpy as np 5 | import matplotlib.pyplot as plt 6 | import pandas as pd 7 | 8 | # Importing the dataset 9 | dataset = pd.read_csv('Position_Salaries.csv') 10 | X = dataset.iloc[:, 1:2].values 11 | y = dataset.iloc[:, 2].values 12 | 13 | # Splitting the dataset into the Training set and Test set 14 | """from sklearn.cross_validation import train_test_split 15 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)""" 16 | 17 | # Feature Scaling 18 | """from sklearn.preprocessing import StandardScaler 19 | sc_X = StandardScaler() 20 | X_train = sc_X.fit_transform(X_train) 21 | X_test = sc_X.transform(X_test) 22 | sc_y = StandardScaler() 23 | y_train = sc_y.fit_transform(y_train)""" 24 | 25 | # Fitting Random Forest Regression to the dataset 26 | from sklearn.ensemble import RandomForestRegressor 27 | regressor = RandomForestRegressor(n_estimators = 10, random_state = 0) 28 | regressor.fit(X, y) 29 | 30 | # Predicting a new result 31 | y_pred = regressor.predict(6.5) 32 | 33 | # Visualising the Random Forest Regression results (higher resolution) 34 | X_grid = np.arange(min(X), max(X), 0.01) 35 | X_grid = X_grid.reshape((len(X_grid), 1)) 36 | plt.scatter(X, y, color = 'red') 37 | plt.plot(X_grid, regressor.predict(X_grid), color = 'blue') 38 | plt.title('Truth or Bluff (Random Forest Regression)') 39 | plt.xlabel('Position level') 40 | plt.ylabel('Salary') 41 | plt.show() -------------------------------------------------------------------------------- /dynamic_programming/longest_increasing_subsequence.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Author : Mehdi ALAOUI 3 | 4 | This is a pure Python implementation of Dynamic Programming solution to the longest increasing subsequence of a given sequence. 5 | 6 | The problem is : 7 | Given an ARRAY, to find the longest and increasing sub ARRAY in that given ARRAY and return it. 8 | Example: [10, 22, 9, 33, 21, 50, 41, 60, 80] as input will return [10, 22, 33, 41, 60, 80] as output 9 | ''' 10 | from __future__ import print_function 11 | 12 | def longestSub(ARRAY): #This function is recursive 13 | 14 | ARRAY_LENGTH = len(ARRAY) 15 | if(ARRAY_LENGTH <= 1): #If the array contains only one element, we return it (it's the stop condition of recursion) 16 | return ARRAY 17 | #Else 18 | PIVOT=ARRAY[0] 19 | isFound=False 20 | i=1 21 | LONGEST_SUB=[] 22 | while(not isFound and i= ARRAY[i] ] 26 | TEMPORARY_ARRAY = longestSub(TEMPORARY_ARRAY) 27 | if ( len(TEMPORARY_ARRAY) > len(LONGEST_SUB) ): 28 | LONGEST_SUB = TEMPORARY_ARRAY 29 | else: 30 | i+=1 31 | 32 | TEMPORARY_ARRAY = [ element for element in ARRAY[1:] if element >= PIVOT ] 33 | TEMPORARY_ARRAY = [PIVOT] + longestSub(TEMPORARY_ARRAY) 34 | if ( len(TEMPORARY_ARRAY) > len(LONGEST_SUB) ): 35 | return TEMPORARY_ARRAY 36 | else: 37 | return LONGEST_SUB 38 | 39 | #Some examples 40 | 41 | print(longestSub([4,8,7,5,1,12,2,3,9])) 42 | print(longestSub([9,8,7,6,5,7])) -------------------------------------------------------------------------------- /sorts/selection_sort.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a pure python implementation of the selection sort algorithm 3 | 4 | For doctests run following command: 5 | python -m doctest -v selection_sort.py 6 | or 7 | python3 -m doctest -v selection_sort.py 8 | 9 | For manual testing run: 10 | python selection_sort.py 11 | """ 12 | from __future__ import print_function 13 | 14 | 15 | def selection_sort(collection): 16 | """Pure implementation of the selection sort algorithm in Python 17 | :param collection: some mutable ordered collection with heterogeneous 18 | comparable items inside 19 | :return: the same collection ordered by ascending 20 | 21 | 22 | Examples: 23 | >>> selection_sort([0, 5, 3, 2, 2]) 24 | [0, 2, 2, 3, 5] 25 | 26 | >>> selection_sort([]) 27 | [] 28 | 29 | >>> selection_sort([-2, -5, -45]) 30 | [-45, -5, -2] 31 | """ 32 | 33 | length = len(collection) 34 | for i in range(length - 1): 35 | least = i 36 | for k in range(i + 1, length): 37 | if collection[k] < collection[least]: 38 | least = k 39 | collection[least], collection[i] = ( 40 | collection[i], collection[least] 41 | ) 42 | return collection 43 | 44 | 45 | if __name__ == '__main__': 46 | try: 47 | raw_input # Python 2 48 | except NameError: 49 | raw_input = input # Python 3 50 | 51 | user_input = raw_input('Enter numbers separated by a comma:\n').strip() 52 | unsorted = [int(item) for item in user_input.split(',')] 53 | print(selection_sort(unsorted)) 54 | -------------------------------------------------------------------------------- /binary_tree/basic_binary_tree.py: -------------------------------------------------------------------------------- 1 | class Node: # This is the Class Node with constructor that contains data variable to type data and left,right pointers. 2 | def __init__(self, data): 3 | self.data = data 4 | self.left = None 5 | self.right = None 6 | 7 | 8 | def depth_of_tree(tree): #This is the recursive function to find the depth of binary tree. 9 | if tree is None: 10 | return 0 11 | else: 12 | depth_l_tree = depth_of_tree(tree.left) 13 | depth_r_tree = depth_of_tree(tree.right) 14 | if depth_l_tree > depth_r_tree: 15 | return 1 + depth_l_tree 16 | else: 17 | return 1 + depth_r_tree 18 | 19 | 20 | def is_full_binary_tree(tree): # This functions returns that is it full binary tree or not? 21 | if tree is None: 22 | return True 23 | if (tree.left is None) and (tree.right is None): 24 | return True 25 | if (tree.left is not None) and (tree.right is not None): 26 | return (is_full_binary_tree(tree.left) and is_full_binary_tree(tree.right)) 27 | else: 28 | return False 29 | 30 | 31 | def main(): # Main func for testing. 32 | tree = Node(1) 33 | tree.left = Node(2) 34 | tree.right = Node(3) 35 | tree.left.left = Node(4) 36 | tree.left.right = Node(5) 37 | tree.left.right.left = Node(6) 38 | tree.right.left = Node(7) 39 | tree.right.left.left = Node(8) 40 | tree.right.left.left.right = Node(9) 41 | 42 | print(is_full_binary_tree(tree)) 43 | print(depth_of_tree(tree)) 44 | 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /sorts/shell_sort.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a pure python implementation of the shell sort algorithm 3 | 4 | For doctests run following command: 5 | python -m doctest -v shell_sort.py 6 | or 7 | python3 -m doctest -v shell_sort.py 8 | 9 | For manual testing run: 10 | python shell_sort.py 11 | """ 12 | from __future__ import print_function 13 | 14 | 15 | def shell_sort(collection): 16 | """Pure implementation of shell sort algorithm in Python 17 | :param collection: Some mutable ordered collection with heterogeneous 18 | comparable items inside 19 | :return: the same collection ordered by ascending 20 | 21 | >>> shell_sort([0, 5, 3, 2, 2]) 22 | [0, 2, 2, 3, 5] 23 | 24 | >>> shell_sort([]) 25 | [] 26 | 27 | >>> shell_sort([-2, -5, -45]) 28 | [-45, -5, -2] 29 | """ 30 | # Marcin Ciura's gap sequence 31 | gaps = [701, 301, 132, 57, 23, 10, 4, 1] 32 | 33 | for gap in gaps: 34 | i = gap 35 | while i < len(collection): 36 | temp = collection[i] 37 | j = i 38 | while j >= gap and collection[j - gap] > temp: 39 | collection[j] = collection[j - gap] 40 | j -= gap 41 | collection[j] = temp 42 | i += 1 43 | 44 | return collection 45 | 46 | if __name__ == '__main__': 47 | try: 48 | raw_input # Python 2 49 | except NameError: 50 | raw_input = input # Python 3 51 | 52 | user_input = raw_input('Enter numbers separated by a comma:\n').strip() 53 | unsorted = [int(item) for item in user_input.split(',')] 54 | print(shell_sort(unsorted)) 55 | -------------------------------------------------------------------------------- /searches/quick_select.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | """ 4 | A python implementation of the quick select algorithm, which is efficient for calculating the value that would appear in the index of a list if it would be sorted, even if it is not already sorted 5 | https://en.wikipedia.org/wiki/Quickselect 6 | """ 7 | def _partition(data, pivot): 8 | """ 9 | Three way partition the data into smaller, equal and greater lists, 10 | in relationship to the pivot 11 | :param data: The data to be sorted (a list) 12 | :param pivot: The value to partition the data on 13 | :return: Three list: smaller, equal and greater 14 | """ 15 | less, equal, greater = [], [], [] 16 | for element in data: 17 | if element.address < pivot.address: 18 | less.append(element) 19 | elif element.address > pivot.address: 20 | greater.append(element) 21 | else: 22 | equal.append(element) 23 | return less, equal, greater 24 | 25 | def quickSelect(list, k): 26 | #k = len(list) // 2 when trying to find the median (index that value would be when list is sorted) 27 | smaller = [] 28 | larger = [] 29 | pivot = random.randint(0, len(list) - 1) 30 | pivot = list[pivot] 31 | count = 0 32 | smaller, equal, larger =_partition(list, pivot) 33 | count = len(equal) 34 | m = len(smaller) 35 | 36 | #k is the pivot 37 | if m <= k < m + count: 38 | return pivot 39 | # must be in smaller 40 | elif m > k: 41 | return quickSelect(smaller, k) 42 | #must be in larger 43 | else: 44 | return quickSelect(larger, k - (m + count)) 45 | -------------------------------------------------------------------------------- /dynamic_programming/matrix_chain_order.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import sys 4 | ''' 5 | Dynamic Programming 6 | Implementation of Matrix Chain Multiplication 7 | Time Complexity: O(n^3) 8 | Space Complexity: O(n^2) 9 | ''' 10 | def MatrixChainOrder(array): 11 | N=len(array) 12 | Matrix=[[0 for x in range(N)] for x in range(N)] 13 | Sol=[[0 for x in range(N)] for x in range(N)] 14 | 15 | for ChainLength in range(2,N): 16 | for a in range(1,N-ChainLength+1): 17 | b = a+ChainLength-1 18 | 19 | Matrix[a][b] = sys.maxsize 20 | for c in range(a , b): 21 | cost = Matrix[a][c] + Matrix[c+1][b] + array[a-1]*array[c]*array[b] 22 | if cost < Matrix[a][b]: 23 | Matrix[a][b] = cost 24 | Sol[a][b] = c 25 | return Matrix , Sol 26 | #Print order of matrix with Ai as Matrix 27 | def PrintOptimalSolution(OptimalSolution,i,j): 28 | if i==j: 29 | print("A" + str(i),end = " ") 30 | else: 31 | print("(",end = " ") 32 | PrintOptimalSolution(OptimalSolution,i,OptimalSolution[i][j]) 33 | PrintOptimalSolution(OptimalSolution,OptimalSolution[i][j]+1,j) 34 | print(")",end = " ") 35 | 36 | def main(): 37 | array=[30,35,15,5,10,20,25] 38 | n=len(array) 39 | #Size of matrix created from above array will be 40 | # 30*35 35*15 15*5 5*10 10*20 20*25 41 | Matrix , OptimalSolution = MatrixChainOrder(array) 42 | 43 | print("No. of Operation required: "+str((Matrix[1][n-1]))) 44 | PrintOptimalSolution(OptimalSolution,1,n-1) 45 | if __name__ == '__main__': 46 | main() 47 | -------------------------------------------------------------------------------- /project_euler/problem_17/sol1.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | ''' 3 | Number letter counts 4 | Problem 17 5 | 6 | If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total. 7 | 8 | If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used? 9 | 10 | 11 | NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) 12 | contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage. 13 | ''' 14 | 15 | ones_counts = [0, 3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8] #number of letters in zero, one, two, ..., nineteen (0 for zero since it's never said aloud) 16 | tens_counts = [0, 0, 6, 6, 5, 5, 5, 7, 6, 6] #number of letters in twenty, thirty, ..., ninety (0 for numbers less than 20 due to inconsistency in teens) 17 | 18 | count = 0 19 | 20 | for i in range(1, 1001): 21 | if i < 1000: 22 | if i >= 100: 23 | count += ones_counts[i/100] + 7 #add number of letters for "n hundred" 24 | 25 | if i%100 is not 0: 26 | count += 3 #add number of letters for "and" if number is not multiple of 100 27 | 28 | if 0 < i%100 < 20: 29 | count += ones_counts[i%100] #add number of letters for one, two, three, ..., nineteen (could be combined with below if not for inconsistency in teens) 30 | else: 31 | count += ones_counts[i%10] + tens_counts[(i%100-i%10)/10] #add number of letters for twenty, twenty one, ..., ninety nine 32 | else: 33 | count += ones_counts[i/1000] + 8 34 | 35 | print(count) -------------------------------------------------------------------------------- /searches/linear_search.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is pure python implementation of linear search algorithm 3 | 4 | For doctests run following command: 5 | python -m doctest -v linear_search.py 6 | or 7 | python3 -m doctest -v linear_search.py 8 | 9 | For manual testing run: 10 | python linear_search.py 11 | """ 12 | from __future__ import print_function 13 | 14 | try: 15 | raw_input # Python 2 16 | except NameError: 17 | raw_input = input # Python 3 18 | 19 | def linear_search(sequence, target): 20 | """Pure implementation of linear search algorithm in Python 21 | 22 | :param sequence: some sorted collection with comparable items 23 | :param target: item value to search 24 | :return: index of found item or None if item is not found 25 | 26 | Examples: 27 | >>> linear_search([0, 5, 7, 10, 15], 0) 28 | 0 29 | 30 | >>> linear_search([0, 5, 7, 10, 15], 15) 31 | 4 32 | 33 | >>> linear_search([0, 5, 7, 10, 15], 5) 34 | 1 35 | 36 | >>> linear_search([0, 5, 7, 10, 15], 6) 37 | 38 | """ 39 | for index, item in enumerate(sequence): 40 | if item == target: 41 | return index 42 | return None 43 | 44 | 45 | if __name__ == '__main__': 46 | user_input = raw_input('Enter numbers separated by comma:\n').strip() 47 | sequence = [int(item) for item in user_input.split(',')] 48 | 49 | target_input = raw_input('Enter a single number to be found in the list:\n') 50 | target = int(target_input) 51 | result = linear_search(sequence, target) 52 | if result is not None: 53 | print('{} found at positions: {}'.format(target, result)) 54 | else: 55 | print('Not found') 56 | -------------------------------------------------------------------------------- /ciphers/transposition_cipher.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import math 3 | 4 | def main(): 5 | message = input('Enter message: ') 6 | key = int(input('Enter key [2-%s]: ' % (len(message) - 1))) 7 | mode = input('Encryption/Decryption [e/d]: ') 8 | 9 | if mode.lower().startswith('e'): 10 | text = encryptMessage(key, message) 11 | elif mode.lower().startswith('d'): 12 | text = decryptMessage(key, message) 13 | 14 | # Append pipe symbol (vertical bar) to identify spaces at the end. 15 | print('Output:\n%s' %(text + '|')) 16 | 17 | def encryptMessage(key, message): 18 | """ 19 | >>> encryptMessage(6, 'Harshil Darji') 20 | 'Hlia rDsahrij' 21 | """ 22 | cipherText = [''] * key 23 | for col in range(key): 24 | pointer = col 25 | while pointer < len(message): 26 | cipherText[col] += message[pointer] 27 | pointer += key 28 | return ''.join(cipherText) 29 | 30 | def decryptMessage(key, message): 31 | """ 32 | >>> decryptMessage(6, 'Hlia rDsahrij') 33 | 'Harshil Darji' 34 | """ 35 | numCols = math.ceil(len(message) / key) 36 | numRows = key 37 | numShadedBoxes = (numCols * numRows) - len(message) 38 | plainText = [""] * numCols 39 | col = 0; row = 0; 40 | 41 | for symbol in message: 42 | plainText[col] += symbol 43 | col += 1 44 | 45 | if (col == numCols) or (col == numCols - 1) and (row >= numRows - numShadedBoxes): 46 | col = 0 47 | row += 1 48 | 49 | return "".join(plainText) 50 | 51 | if __name__ == '__main__': 52 | import doctest 53 | doctest.testmod() 54 | main() 55 | -------------------------------------------------------------------------------- /data_structures/queue/queue_on_pseudo_stack.py: -------------------------------------------------------------------------------- 1 | """Queue represented by a pseudo stack (represented by a list with pop and append)""" 2 | class Queue(): 3 | def __init__(self): 4 | self.stack = [] 5 | self.length = 0 6 | 7 | def __str__(self): 8 | printed = '<' + str(self.stack)[1:-1] + '>' 9 | return printed 10 | 11 | """Enqueues {@code item} 12 | @param item 13 | item to enqueue""" 14 | def put(self, item): 15 | self.stack.append(item) 16 | self.length = self.length + 1 17 | 18 | """Dequeues {@code item} 19 | @requirement: |self.length| > 0 20 | @return dequeued 21 | item that was dequeued""" 22 | def get(self): 23 | self.rotate(1) 24 | dequeued = self.stack[self.length-1] 25 | self.stack = self.stack[:-1] 26 | self.rotate(self.length-1) 27 | self.length = self.length -1 28 | return dequeued 29 | 30 | """Rotates the queue {@code rotation} times 31 | @param rotation 32 | number of times to rotate queue""" 33 | def rotate(self, rotation): 34 | for i in range(rotation): 35 | temp = self.stack[0] 36 | self.stack = self.stack[1:] 37 | self.put(temp) 38 | self.length = self.length - 1 39 | 40 | """Reports item at the front of self 41 | @return item at front of self.stack""" 42 | def front(self): 43 | front = self.get() 44 | self.put(front) 45 | self.rotate(self.length-1) 46 | return front 47 | 48 | """Returns the length of this.stack""" 49 | def size(self): 50 | return self.length 51 | -------------------------------------------------------------------------------- /other/detecting_english_programmatically.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | UPPERLETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 4 | LETTERS_AND_SPACE = UPPERLETTERS + UPPERLETTERS.lower() + ' \t\n' 5 | 6 | def loadDictionary(): 7 | path = os.path.split(os.path.realpath(__file__)) 8 | englishWords = {} 9 | with open(path[0] + '/Dictionary.txt') as dictionaryFile: 10 | for word in dictionaryFile.read().split('\n'): 11 | englishWords[word] = None 12 | return englishWords 13 | 14 | ENGLISH_WORDS = loadDictionary() 15 | 16 | def getEnglishCount(message): 17 | message = message.upper() 18 | message = removeNonLetters(message) 19 | possibleWords = message.split() 20 | 21 | if possibleWords == []: 22 | return 0.0 23 | 24 | matches = 0 25 | for word in possibleWords: 26 | if word in ENGLISH_WORDS: 27 | matches += 1 28 | 29 | return float(matches) / len(possibleWords) 30 | 31 | def removeNonLetters(message): 32 | lettersOnly = [] 33 | for symbol in message: 34 | if symbol in LETTERS_AND_SPACE: 35 | lettersOnly.append(symbol) 36 | return ''.join(lettersOnly) 37 | 38 | def isEnglish(message, wordPercentage = 20, letterPercentage = 85): 39 | """ 40 | >>> isEnglish('Hello World') 41 | True 42 | 43 | >>> isEnglish('llold HorWd') 44 | False 45 | """ 46 | wordsMatch = getEnglishCount(message) * 100 >= wordPercentage 47 | numLetters = len(removeNonLetters(message)) 48 | messageLettersPercentage = (float(numLetters) / len(message)) * 100 49 | lettersMatch = messageLettersPercentage >= letterPercentage 50 | return wordsMatch and lettersMatch 51 | 52 | 53 | import doctest 54 | doctest.testmod() 55 | -------------------------------------------------------------------------------- /Graphs/even_tree.py: -------------------------------------------------------------------------------- 1 | """ 2 | You are given a tree(a simple connected graph with no cycles). The tree has N 3 | nodes numbered from 1 to N and is rooted at node 1. 4 | 5 | Find the maximum number of edges you can remove from the tree to get a forest 6 | such that each connected component of the forest contains an even number of 7 | nodes. 8 | 9 | Constraints 10 | 2 <= 2 <= 100 11 | 12 | Note: The tree input will be such that it can always be decomposed into 13 | components containing an even number of nodes. 14 | """ 15 | from __future__ import print_function 16 | # pylint: disable=invalid-name 17 | from collections import defaultdict 18 | 19 | 20 | def dfs(start): 21 | """DFS traversal""" 22 | # pylint: disable=redefined-outer-name 23 | ret = 1 24 | visited[start] = True 25 | for v in tree.get(start): 26 | if v not in visited: 27 | ret += dfs(v) 28 | if ret % 2 == 0: 29 | cuts.append(start) 30 | return ret 31 | 32 | 33 | def even_tree(): 34 | """ 35 | 2 1 36 | 3 1 37 | 4 3 38 | 5 2 39 | 6 1 40 | 7 2 41 | 8 6 42 | 9 8 43 | 10 8 44 | On removing edges (1,3) and (1,6), we can get the desired result 2. 45 | """ 46 | dfs(1) 47 | 48 | 49 | if __name__ == '__main__': 50 | n, m = 10, 9 51 | tree = defaultdict(list) 52 | visited = {} 53 | cuts = [] 54 | count = 0 55 | edges = [ 56 | (2, 1), 57 | (3, 1), 58 | (4, 3), 59 | (5, 2), 60 | (6, 1), 61 | (7, 2), 62 | (8, 6), 63 | (9, 8), 64 | (10, 8), 65 | ] 66 | for u, v in edges: 67 | tree[u].append(v) 68 | tree[v].append(u) 69 | even_tree() 70 | print(len(cuts) - 1) 71 | -------------------------------------------------------------------------------- /maths/basic_maths.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | def primeFactors(n): 4 | pf = [] 5 | while n % 2 == 0: 6 | pf.append(2) 7 | n = int(n / 2) 8 | 9 | for i in range(3, int(math.sqrt(n))+1, 2): 10 | while n % i == 0: 11 | pf.append(i) 12 | n = int(n / i) 13 | 14 | if n > 2: 15 | pf.append(n) 16 | 17 | return pf 18 | 19 | def numberOfDivisors(n): 20 | div = 1 21 | 22 | temp = 1 23 | while n % 2 == 0: 24 | temp += 1 25 | n = int(n / 2) 26 | div = div * (temp) 27 | 28 | for i in range(3, int(math.sqrt(n))+1, 2): 29 | temp = 1 30 | while n % i == 0: 31 | temp += 1 32 | n = int(n / i) 33 | div = div * (temp) 34 | 35 | return div 36 | 37 | def sumOfDivisors(n): 38 | s = 1 39 | 40 | temp = 1 41 | while n % 2 == 0: 42 | temp += 1 43 | n = int(n / 2) 44 | if temp > 1: 45 | s *= (2**temp - 1) / (2 - 1) 46 | 47 | for i in range(3, int(math.sqrt(n))+1, 2): 48 | temp = 1 49 | while n % i == 0: 50 | temp += 1 51 | n = int(n / i) 52 | if temp > 1: 53 | s *= (i**temp - 1) / (i - 1) 54 | 55 | return s 56 | 57 | def eulerPhi(n): 58 | l = primeFactors(n) 59 | l = set(l) 60 | s = n 61 | for x in l: 62 | s *= (x - 1)/x 63 | return s 64 | 65 | def main(): 66 | print(primeFactors(100)) 67 | print(numberOfDivisors(100)) 68 | print(sumOfDivisors(100)) 69 | print(eulerPhi(100)) 70 | 71 | if __name__ == '__main__': 72 | main() 73 | 74 | -------------------------------------------------------------------------------- /sorts/random_normal_distribution_quicksort.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from random import randint 3 | from tempfile import TemporaryFile 4 | import numpy as np 5 | 6 | 7 | 8 | def _inPlaceQuickSort(A,start,end): 9 | count = 0 10 | if start 0: 19 | queue.append(ind) 20 | visited[ind] = True 21 | parent[ind] = u 22 | 23 | return True if visited[t] else False 24 | 25 | def FordFulkerson(graph, source, sink): 26 | # This array is filled by BFS and to store path 27 | parent = [-1]*(len(graph)) 28 | max_flow = 0 29 | while BFS(graph, source, sink, parent) : 30 | path_flow = float("Inf") 31 | s = sink 32 | 33 | while(s != source): 34 | # Find the minimum value in select path 35 | path_flow = min (path_flow, graph[parent[s]][s]) 36 | s = parent[s] 37 | 38 | max_flow += path_flow 39 | v = sink 40 | 41 | while(v != source): 42 | u = parent[v] 43 | graph[u][v] -= path_flow 44 | graph[v][u] += path_flow 45 | v = parent[v] 46 | return max_flow 47 | 48 | graph = [[0, 16, 13, 0, 0, 0], 49 | [0, 0, 10 ,12, 0, 0], 50 | [0, 4, 0, 0, 14, 0], 51 | [0, 0, 9, 0, 0, 20], 52 | [0, 0, 0, 7, 0, 4], 53 | [0, 0, 0, 0, 0, 0]] 54 | 55 | source, sink = 0, 5 56 | print(FordFulkerson(graph, source, sink)) -------------------------------------------------------------------------------- /file_transfer_protocol/ftp_client_server.py: -------------------------------------------------------------------------------- 1 | # server 2 | 3 | import socket # Import socket module 4 | 5 | port = 60000 # Reserve a port for your service. 6 | s = socket.socket() # Create a socket object 7 | host = socket.gethostname() # Get local machine name 8 | s.bind((host, port)) # Bind to the port 9 | s.listen(5) # Now wait for client connection. 10 | 11 | print('Server listening....') 12 | 13 | while True: 14 | conn, addr = s.accept() # Establish connection with client. 15 | print('Got connection from', addr) 16 | data = conn.recv(1024) 17 | print('Server received', repr(data)) 18 | 19 | filename = 'mytext.txt' 20 | with open(filename, 'rb') as f: 21 | in_data = f.read(1024) 22 | while in_data: 23 | conn.send(in_data) 24 | print('Sent ', repr(in_data)) 25 | in_data = f.read(1024) 26 | 27 | print('Done sending') 28 | conn.send('Thank you for connecting') 29 | conn.close() 30 | 31 | 32 | # client side server 33 | 34 | import socket # Import socket module 35 | 36 | s = socket.socket() # Create a socket object 37 | host = socket.gethostname() # Get local machine name 38 | port = 60000 # Reserve a port for your service. 39 | 40 | s.connect((host, port)) 41 | s.send("Hello server!") 42 | 43 | with open('received_file', 'wb') as f: 44 | print('file opened') 45 | while True: 46 | print('receiving data...') 47 | data = s.recv(1024) 48 | print('data=%s', (data)) 49 | if not data: 50 | break 51 | # write data to a file 52 | f.write(data) 53 | 54 | f.close() 55 | print('Successfully get the file') 56 | s.close() 57 | print('connection closed') 58 | -------------------------------------------------------------------------------- /searches/sentinel_linear_search.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is pure python implementation of sentinel linear search algorithm 3 | 4 | For doctests run following command: 5 | python -m doctest -v sentinel_linear_search.py 6 | or 7 | python3 -m doctest -v sentinel_linear_search.py 8 | 9 | For manual testing run: 10 | python sentinel_linear_search.py 11 | """ 12 | 13 | def sentinel_linear_search(sequence, target): 14 | """Pure implementation of sentinel linear search algorithm in Python 15 | 16 | :param sequence: some sequence with comparable items 17 | :param target: item value to search 18 | :return: index of found item or None if item is not found 19 | 20 | Examples: 21 | >>> sentinel_linear_search([0, 5, 7, 10, 15], 0) 22 | 0 23 | 24 | >>> sentinel_linear_search([0, 5, 7, 10, 15], 15) 25 | 4 26 | 27 | >>> sentinel_linear_search([0, 5, 7, 10, 15], 5) 28 | 1 29 | 30 | >>> sentinel_linear_search([0, 5, 7, 10, 15], 6) 31 | 32 | """ 33 | sequence.append(target) 34 | 35 | index = 0 36 | while sequence[index] != target: 37 | index += 1 38 | 39 | sequence.pop() 40 | 41 | if index == len(sequence): 42 | return None 43 | 44 | return index 45 | 46 | 47 | if __name__ == '__main__': 48 | try: 49 | raw_input # Python 2 50 | except NameError: 51 | raw_input = input # Python 3 52 | 53 | user_input = raw_input('Enter numbers separated by comma:\n').strip() 54 | sequence = [int(item) for item in user_input.split(',')] 55 | 56 | target_input = raw_input('Enter a single number to be found in the list:\n') 57 | target = int(target_input) 58 | result = sentinel_linear_search(sequence, target) 59 | if result is not None: 60 | print('{} found at positions: {}'.format(target, result)) 61 | else: 62 | print('Not found') -------------------------------------------------------------------------------- /sorts/comb_sort.py: -------------------------------------------------------------------------------- 1 | """ 2 | Comb sort is a relatively simple sorting algorithm originally designed by Wlodzimierz Dobosiewicz in 1980. 3 | Later it was rediscovered by Stephen Lacey and Richard Box in 1991. Comb sort improves on bubble sort. 4 | 5 | This is pure python implementation of comb sort algorithm 6 | For doctests run following command: 7 | python -m doctest -v comb_sort.py 8 | or 9 | python3 -m doctest -v comb_sort.py 10 | 11 | For manual testing run: 12 | python comb_sort.py 13 | """ 14 | 15 | def comb_sort(data): 16 | """Pure implementation of comb sort algorithm in Python 17 | :param collection: some mutable ordered collection with heterogeneous 18 | comparable items inside 19 | :return: the same collection ordered by ascending 20 | Examples: 21 | >>> comb_sort([0, 5, 3, 2, 2]) 22 | [0, 2, 2, 3, 5] 23 | >>> comb_sort([]) 24 | [] 25 | >>> comb_sort([-2, -5, -45]) 26 | [-45, -5, -2] 27 | """ 28 | shrink_factor = 1.3 29 | gap = len(data) 30 | swapped = True 31 | i = 0 32 | 33 | while gap > 1 or swapped: 34 | # Update the gap value for a next comb 35 | gap = int(float(gap) / shrink_factor) 36 | 37 | swapped = False 38 | i = 0 39 | 40 | while gap + i < len(data): 41 | if data[i] > data[i+gap]: 42 | # Swap values 43 | data[i], data[i+gap] = data[i+gap], data[i] 44 | swapped = True 45 | i += 1 46 | 47 | return data 48 | 49 | 50 | if __name__ == '__main__': 51 | try: 52 | raw_input # Python 2 53 | except NameError: 54 | raw_input = input # Python 3 55 | 56 | user_input = raw_input('Enter numbers separated by a comma:\n').strip() 57 | unsorted = [int(item) for item in user_input.split(',')] 58 | print(comb_sort(unsorted)) 59 | -------------------------------------------------------------------------------- /sorts/BitonicSort.py: -------------------------------------------------------------------------------- 1 | # Python program for Bitonic Sort. Note that this program 2 | # works only when size of input is a power of 2. 3 | 4 | # The parameter dir indicates the sorting direction, ASCENDING 5 | # or DESCENDING; if (a[i] > a[j]) agrees with the direction, 6 | # then a[i] and a[j] are interchanged.*/ 7 | def compAndSwap(a, i, j, dire): 8 | if (dire == 1 and a[i] > a[j]) or (dire == 0 and a[i] < a[j]): 9 | a[i], a[j] = a[j], a[i] 10 | 11 | # It recursively sorts a bitonic sequence in ascending order, 12 | 13 | 14 | # if dir = 1, and in descending order otherwise (means dir=0). 15 | # The sequence to be sorted starts at index position low, 16 | # the parameter cnt is the number of elements to be sorted. 17 | def bitonicMerge(a, low, cnt, dire): 18 | if cnt > 1: 19 | k = int(cnt / 2) 20 | for i in range(low, low + k): 21 | compAndSwap(a, i, i + k, dire) 22 | bitonicMerge(a, low, k, dire) 23 | bitonicMerge(a, low + k, k, dire) 24 | 25 | # This funcion first produces a bitonic sequence by recursively 26 | 27 | 28 | # sorting its two halves in opposite sorting orders, and then 29 | # calls bitonicMerge to make them in the same order 30 | def bitonicSort(a, low, cnt, dire): 31 | if cnt > 1: 32 | k = int(cnt / 2) 33 | bitonicSort(a, low, k, 1) 34 | bitonicSort(a, low + k, k, 0) 35 | bitonicMerge(a, low, cnt, dire) 36 | 37 | # Caller of bitonicSort for sorting the entire array of length N 38 | 39 | 40 | # in ASCENDING order 41 | def sort(a, N, up): 42 | bitonicSort(a, 0, N, up) 43 | 44 | 45 | # Driver code to test above 46 | a = [] 47 | 48 | n = int(input()) 49 | for i in range(n): 50 | a.append(int(input())) 51 | up = 1 52 | 53 | sort(a, n, up) 54 | print("\n\nSorted array is") 55 | for i in range(n): 56 | print("%d" % a[i]) 57 | -------------------------------------------------------------------------------- /ciphers/rsa_key_generator.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import random, sys, os 3 | import rabin_miller as rabinMiller, cryptomath_module as cryptoMath 4 | 5 | def main(): 6 | print('Making key files...') 7 | makeKeyFiles('rsa', 1024) 8 | print('Key files generation successful.') 9 | 10 | def generateKey(keySize): 11 | print('Generating prime p...') 12 | p = rabinMiller.generateLargePrime(keySize) 13 | print('Generating prime q...') 14 | q = rabinMiller.generateLargePrime(keySize) 15 | n = p * q 16 | 17 | print('Generating e that is relatively prime to (p - 1) * (q - 1)...') 18 | while True: 19 | e = random.randrange(2 ** (keySize - 1), 2 ** (keySize)) 20 | if cryptoMath.gcd(e, (p - 1) * (q - 1)) == 1: 21 | break 22 | 23 | print('Calculating d that is mod inverse of e...') 24 | d = cryptoMath.findModInverse(e, (p - 1) * (q - 1)) 25 | 26 | publicKey = (n, e) 27 | privateKey = (n, d) 28 | return (publicKey, privateKey) 29 | 30 | def makeKeyFiles(name, keySize): 31 | if os.path.exists('%s_pubkey.txt' % (name)) or os.path.exists('%s_privkey.txt' % (name)): 32 | print('\nWARNING:') 33 | print('"%s_pubkey.txt" or "%s_privkey.txt" already exists. \nUse a different name or delete these files and re-run this program.' % (name, name)) 34 | sys.exit() 35 | 36 | publicKey, privateKey = generateKey(keySize) 37 | print('\nWriting public key to file %s_pubkey.txt...' % name) 38 | with open('%s_pubkey.txt' % name, 'w') as fo: 39 | fo.write('%s,%s,%s' % (keySize, publicKey[0], publicKey[1])) 40 | 41 | print('Writing private key to file %s_privkey.txt...' % name) 42 | with open('%s_privkey.txt' % name, 'w') as fo: 43 | fo.write('%s,%s,%s' % (keySize, privateKey[0], privateKey[1])) 44 | 45 | if __name__ == '__main__': 46 | main() 47 | -------------------------------------------------------------------------------- /networking_flow/minimum_cut.py: -------------------------------------------------------------------------------- 1 | # Minimum cut on Ford_Fulkerson algorithm. 2 | 3 | def BFS(graph, s, t, parent): 4 | # Return True if there is node that has not iterated. 5 | visited = [False]*len(graph) 6 | queue=[] 7 | queue.append(s) 8 | visited[s] = True 9 | 10 | while queue: 11 | u = queue.pop(0) 12 | for ind in range(len(graph[u])): 13 | if visited[ind] == False and graph[u][ind] > 0: 14 | queue.append(ind) 15 | visited[ind] = True 16 | parent[ind] = u 17 | 18 | return True if visited[t] else False 19 | 20 | def mincut(graph, source, sink): 21 | # This array is filled by BFS and to store path 22 | parent = [-1]*(len(graph)) 23 | max_flow = 0 24 | res = [] 25 | temp = [i[:] for i in graph] # Record orignial cut, copy. 26 | while BFS(graph, source, sink, parent) : 27 | path_flow = float("Inf") 28 | s = sink 29 | 30 | while(s != source): 31 | # Find the minimum value in select path 32 | path_flow = min (path_flow, graph[parent[s]][s]) 33 | s = parent[s] 34 | 35 | max_flow += path_flow 36 | v = sink 37 | 38 | while(v != source): 39 | u = parent[v] 40 | graph[u][v] -= path_flow 41 | graph[v][u] += path_flow 42 | v = parent[v] 43 | 44 | for i in range(len(graph)): 45 | for j in range(len(graph[0])): 46 | if graph[i][j] == 0 and temp[i][j] > 0: 47 | res.append((i,j)) 48 | 49 | return res 50 | 51 | graph = [[0, 16, 13, 0, 0, 0], 52 | [0, 0, 10 ,12, 0, 0], 53 | [0, 4, 0, 0, 14, 0], 54 | [0, 0, 9, 0, 0, 20], 55 | [0, 0, 0, 7, 0, 4], 56 | [0, 0, 0, 0, 0, 0]] 57 | 58 | source, sink = 0, 5 59 | print(mincut(graph, source, sink)) -------------------------------------------------------------------------------- /sorts/cyclesort.py: -------------------------------------------------------------------------------- 1 | # Code contributed by Honey Sharma 2 | from __future__ import print_function 3 | 4 | 5 | def cycle_sort(array): 6 | ans = 0 7 | 8 | # Pass through the array to find cycles to rotate. 9 | for cycleStart in range(0, len(array) - 1): 10 | item = array[cycleStart] 11 | 12 | # finding the position for putting the item. 13 | pos = cycleStart 14 | for i in range(cycleStart + 1, len(array)): 15 | if array[i] < item: 16 | pos += 1 17 | 18 | # If the item is already present-not a cycle. 19 | if pos == cycleStart: 20 | continue 21 | 22 | # Otherwise, put the item there or right after any duplicates. 23 | while item == array[pos]: 24 | pos += 1 25 | array[pos], item = item, array[pos] 26 | ans += 1 27 | 28 | # Rotate the rest of the cycle. 29 | while pos != cycleStart: 30 | 31 | # Find where to put the item. 32 | pos = cycleStart 33 | for i in range(cycleStart + 1, len(array)): 34 | if array[i] < item: 35 | pos += 1 36 | 37 | # Put the item there or right after any duplicates. 38 | while item == array[pos]: 39 | pos += 1 40 | array[pos], item = item, array[pos] 41 | ans += 1 42 | 43 | return ans 44 | 45 | 46 | # Main Code starts here 47 | if __name__ == '__main__': 48 | try: 49 | raw_input # Python 2 50 | except NameError: 51 | raw_input = input # Python 3 52 | 53 | user_input = raw_input('Enter numbers separated by a comma:\n') 54 | unsorted = [int(item) for item in user_input.split(',')] 55 | n = len(unsorted) 56 | cycle_sort(unsorted) 57 | 58 | print("After sort : ") 59 | for i in range(0, n): 60 | print(unsorted[i], end=' ') 61 | -------------------------------------------------------------------------------- /ciphers/base64_cipher.py: -------------------------------------------------------------------------------- 1 | def encodeBase64(text): 2 | base64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" 3 | 4 | r = "" #the result 5 | c = 3 - len(text) % 3 #the length of padding 6 | p = "=" * c #the padding 7 | s = text + "\0" * c #the text to encode 8 | 9 | i = 0 10 | while i < len(s): 11 | if i > 0 and ((i / 3 * 4) % 76) == 0: 12 | r = r + "\r\n" 13 | 14 | n = (ord(s[i]) << 16) + (ord(s[i+1]) << 8 ) + ord(s[i+2]) 15 | 16 | n1 = (n >> 18) & 63 17 | n2 = (n >> 12) & 63 18 | n3 = (n >> 6) & 63 19 | n4 = n & 63 20 | 21 | r += base64chars[n1] + base64chars[n2] + base64chars[n3] + base64chars[n4] 22 | i += 3 23 | 24 | return r[0: len(r)-len(p)] + p 25 | 26 | def decodeBase64(text): 27 | base64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" 28 | s = "" 29 | 30 | for i in text: 31 | if i in base64chars: 32 | s += i 33 | c = "" 34 | else: 35 | if i == '=': 36 | c += '=' 37 | 38 | p = "" 39 | if c == "=": 40 | p = 'A' 41 | else: 42 | if c == "==": 43 | p = "AA" 44 | 45 | r = "" 46 | s = s + p 47 | 48 | i = 0 49 | while i < len(s): 50 | n = (base64chars.index(s[i]) << 18) + (base64chars.index(s[i+1]) << 12) + (base64chars.index(s[i+2]) << 6) +base64chars.index(s[i+3]) 51 | 52 | r += chr((n >> 16) & 255) + chr((n >> 8) & 255) + chr(n & 255) 53 | 54 | i += 4 55 | 56 | return r[0: len(r) - len(p)] 57 | 58 | def main(): 59 | print(encodeBase64("WELCOME to base64 encoding")) 60 | print(decodeBase64(encodeBase64("WELCOME to base64 encoding"))) 61 | 62 | 63 | if __name__ == '__main__': 64 | main() 65 | -------------------------------------------------------------------------------- /data_structures/stacks/stock_span_problem.py: -------------------------------------------------------------------------------- 1 | ''' 2 | The stock span problem is a financial problem where we have a series of n daily 3 | price quotes for a stock and we need to calculate span of stock's price for all n days. 4 | 5 | The span Si of the stock's price on a given day i is defined as the maximum 6 | number of consecutive days just before the given day, for which the price of the stock 7 | on the current day is less than or equal to its price on the given day. 8 | ''' 9 | from __future__ import print_function 10 | def calculateSpan(price, S): 11 | 12 | n = len(price) 13 | # Create a stack and push index of fist element to it 14 | st = [] 15 | st.append(0) 16 | 17 | # Span value of first element is always 1 18 | S[0] = 1 19 | 20 | # Calculate span values for rest of the elements 21 | for i in range(1, n): 22 | 23 | # Pop elements from stack whlie stack is not 24 | # empty and top of stack is smaller than price[i] 25 | while( len(st) > 0 and price[st[0]] <= price[i]): 26 | st.pop() 27 | 28 | # If stack becomes empty, then price[i] is greater 29 | # than all elements on left of it, i.e. price[0], 30 | # price[1], ..price[i-1]. Else the price[i] is 31 | # greater than elements after top of stack 32 | S[i] = i+1 if len(st) <= 0 else (i - st[0]) 33 | 34 | # Push this element to stack 35 | st.append(i) 36 | 37 | 38 | # A utility function to print elements of array 39 | def printArray(arr, n): 40 | for i in range(0,n): 41 | print (arr[i],end =" ") 42 | 43 | 44 | # Driver program to test above function 45 | price = [10, 4, 5, 90, 120, 80] 46 | S = [0 for i in range(len(price)+1)] 47 | 48 | # Fill the span values in array S[] 49 | calculateSpan(price, S) 50 | 51 | # Print the calculated span values 52 | printArray(S, len(price)) 53 | -------------------------------------------------------------------------------- /Graphs/depth_first_search.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # encoding=utf8 3 | 4 | """ Author: OMKAR PATHAK """ 5 | from __future__ import print_function 6 | 7 | 8 | class Graph(): 9 | def __init__(self): 10 | self.vertex = {} 11 | 12 | # for printing the Graph vertexes 13 | def printGraph(self): 14 | print(self.vertex) 15 | for i in self.vertex.keys(): 16 | print(i,' -> ', ' -> '.join([str(j) for j in self.vertex[i]])) 17 | 18 | # for adding the edge beween two vertexes 19 | def addEdge(self, fromVertex, toVertex): 20 | # check if vertex is already present, 21 | if fromVertex in self.vertex.keys(): 22 | self.vertex[fromVertex].append(toVertex) 23 | else: 24 | # else make a new vertex 25 | self.vertex[fromVertex] = [toVertex] 26 | 27 | def DFS(self): 28 | # visited array for storing already visited nodes 29 | visited = [False] * len(self.vertex) 30 | 31 | # call the recursive helper function 32 | for i in range(len(self.vertex)): 33 | if visited[i] == False: 34 | self.DFSRec(i, visited) 35 | 36 | def DFSRec(self, startVertex, visited): 37 | # mark start vertex as visited 38 | visited[startVertex] = True 39 | 40 | print(startVertex, end = ' ') 41 | 42 | # Recur for all the vertexes that are adjacent to this node 43 | for i in self.vertex.keys(): 44 | if visited[i] == False: 45 | self.DFSRec(i, visited) 46 | 47 | if __name__ == '__main__': 48 | g = Graph() 49 | g.addEdge(0, 1) 50 | g.addEdge(0, 2) 51 | g.addEdge(1, 2) 52 | g.addEdge(2, 0) 53 | g.addEdge(2, 3) 54 | g.addEdge(3, 3) 55 | 56 | g.printGraph() 57 | print('DFS:') 58 | g.DFS() 59 | 60 | # OUTPUT: 61 | # 0  ->  1 -> 2 62 | # 1  ->  2 63 | # 2  ->  0 -> 3 64 | # 3  ->  3 65 | # DFS: 66 | # 0 1 2 3 67 | -------------------------------------------------------------------------------- /Graphs/breadth_first_search.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # encoding=utf8 3 | 4 | """ Author: OMKAR PATHAK """ 5 | 6 | from __future__ import print_function 7 | 8 | 9 | class Graph(): 10 | def __init__(self): 11 | self.vertex = {} 12 | 13 | # for printing the Graph vertexes 14 | def printGraph(self): 15 | for i in self.vertex.keys(): 16 | print(i,' -> ', ' -> '.join([str(j) for j in self.vertex[i]])) 17 | 18 | # for adding the edge beween two vertexes 19 | def addEdge(self, fromVertex, toVertex): 20 | # check if vertex is already present, 21 | if fromVertex in self.vertex.keys(): 22 | self.vertex[fromVertex].append(toVertex) 23 | else: 24 | # else make a new vertex 25 | self.vertex[fromVertex] = [toVertex] 26 | 27 | def BFS(self, startVertex): 28 | # Take a list for stoting already visited vertexes 29 | visited = [False] * len(self.vertex) 30 | 31 | # create a list to store all the vertexes for BFS 32 | queue = [] 33 | 34 | # mark the source node as visited and enqueue it 35 | visited[startVertex] = True 36 | queue.append(startVertex) 37 | 38 | while queue: 39 | startVertex = queue.pop(0) 40 | print(startVertex, end = ' ') 41 | 42 | # mark all adjacent nodes as visited and print them 43 | for i in self.vertex[startVertex]: 44 | if visited[i] == False: 45 | queue.append(i) 46 | visited[i] = True 47 | 48 | if __name__ == '__main__': 49 | g = Graph() 50 | g.addEdge(0, 1) 51 | g.addEdge(0, 2) 52 | g.addEdge(1, 2) 53 | g.addEdge(2, 0) 54 | g.addEdge(2, 3) 55 | g.addEdge(3, 3) 56 | 57 | g.printGraph() 58 | print('BFS:') 59 | g.BFS(2) 60 | 61 | # OUTPUT: 62 | # 0  ->  1 -> 2 63 | # 1  ->  2 64 | # 2  ->  0 -> 3 65 | # 3  ->  3 66 | # BFS: 67 | # 2 0 3 1 68 | -------------------------------------------------------------------------------- /maths/newton_raphson.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Author: P Shreyas Shetty 3 | Implementation of Newton-Raphson method for solving equations of kind 4 | f(x) = 0. It is an iterative method where solution is found by the expression 5 | x[n+1] = x[n] + f(x[n])/f'(x[n]) 6 | If no solution exists, then either the solution will not be found when iteration 7 | limit is reached or the gradient f'(x[n]) approaches zero. In both cases, exception 8 | is raised. If iteration limit is reached, try increasing maxiter. 9 | ''' 10 | 11 | import math as m 12 | 13 | def calc_derivative(f, a, h=0.001): 14 | ''' 15 | Calculates derivative at point a for function f using finite difference 16 | method 17 | ''' 18 | return (f(a+h)-f(a-h))/(2*h) 19 | 20 | def newton_raphson(f, x0=0, maxiter=100, step=0.0001, maxerror=1e-6,logsteps=False): 21 | 22 | a = x0 #set the initial guess 23 | steps = [a] 24 | error = abs(f(a)) 25 | f1 = lambda x:calc_derivative(f, x, h=step) #Derivative of f(x) 26 | for _ in range(maxiter): 27 | if f1(a) == 0: 28 | raise ValueError("No converging solution found") 29 | a = a - f(a)/f1(a) #Calculate the next estimate 30 | if logsteps: 31 | steps.append(a) 32 | error = abs(f(a)) 33 | if error < maxerror: 34 | break 35 | else: 36 | raise ValueError("Itheration limit reached, no converging solution found") 37 | if logsteps: 38 | #If logstep is true, then log intermediate steps 39 | return a, error, steps 40 | return a, error 41 | 42 | if __name__ == '__main__': 43 | import matplotlib.pyplot as plt 44 | f = lambda x:m.tanh(x)**2-m.exp(3*x) 45 | solution, error, steps = newton_raphson(f, x0=10, maxiter=1000, step=1e-6, logsteps=True) 46 | plt.plot([abs(f(x)) for x in steps]) 47 | plt.xlabel("step") 48 | plt.ylabel("error") 49 | plt.show() 50 | print("solution = {%f}, error = {%f}" % (solution, error)) -------------------------------------------------------------------------------- /sorts/heap_sort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This is a pure python implementation of the heap sort algorithm. 3 | 4 | For doctests run following command: 5 | python -m doctest -v heap_sort.py 6 | or 7 | python3 -m doctest -v heap_sort.py 8 | 9 | For manual testing run: 10 | python heap_sort.py 11 | ''' 12 | 13 | from __future__ import print_function 14 | 15 | 16 | def heapify(unsorted, index, heap_size): 17 | largest = index 18 | left_index = 2 * index + 1 19 | right_index = 2 * index + 2 20 | if left_index < heap_size and unsorted[left_index] > unsorted[largest]: 21 | largest = left_index 22 | 23 | if right_index < heap_size and unsorted[right_index] > unsorted[largest]: 24 | largest = right_index 25 | 26 | if largest != index: 27 | unsorted[largest], unsorted[index] = unsorted[index], unsorted[largest] 28 | heapify(unsorted, largest, heap_size) 29 | 30 | 31 | def heap_sort(unsorted): 32 | ''' 33 | Pure implementation of the heap sort algorithm in Python 34 | :param collection: some mutable ordered collection with heterogeneous 35 | comparable items inside 36 | :return: the same collection ordered by ascending 37 | 38 | Examples: 39 | >>> heap_sort([0, 5, 3, 2, 2]) 40 | [0, 2, 2, 3, 5] 41 | 42 | >>> heap_sort([]) 43 | [] 44 | 45 | >>> heap_sort([-2, -5, -45]) 46 | [-45, -5, -2] 47 | ''' 48 | n = len(unsorted) 49 | for i in range(n // 2 - 1, -1, -1): 50 | heapify(unsorted, i, n) 51 | for i in range(n - 1, 0, -1): 52 | unsorted[0], unsorted[i] = unsorted[i], unsorted[0] 53 | heapify(unsorted, 0, i) 54 | return unsorted 55 | 56 | if __name__ == '__main__': 57 | try: 58 | raw_input # Python 2 59 | except NameError: 60 | raw_input = input # Python 3 61 | 62 | user_input = raw_input('Enter numbers separated by a comma:\n').strip() 63 | unsorted = [int(item) for item in user_input.split(',')] 64 | print(heap_sort(unsorted)) 65 | -------------------------------------------------------------------------------- /ciphers/vigenere_cipher.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 3 | 4 | def main(): 5 | message = input('Enter message: ') 6 | key = input('Enter key [alphanumeric]: ') 7 | mode = input('Encrypt/Decrypt [e/d]: ') 8 | 9 | if mode.lower().startswith('e'): 10 | mode = 'encrypt' 11 | translated = encryptMessage(key, message) 12 | elif mode.lower().startswith('d'): 13 | mode = 'decrypt' 14 | translated = decryptMessage(key, message) 15 | 16 | print('\n%sed message:' % mode.title()) 17 | print(translated) 18 | 19 | def encryptMessage(key, message): 20 | ''' 21 | >>> encryptMessage('HDarji', 'This is Harshil Darji from Dharmaj.') 22 | 'Akij ra Odrjqqs Gaisq muod Mphumrs.' 23 | ''' 24 | return translateMessage(key, message, 'encrypt') 25 | 26 | def decryptMessage(key, message): 27 | ''' 28 | >>> decryptMessage('HDarji', 'Akij ra Odrjqqs Gaisq muod Mphumrs.') 29 | 'This is Harshil Darji from Dharmaj.' 30 | ''' 31 | return translateMessage(key, message, 'decrypt') 32 | 33 | def translateMessage(key, message, mode): 34 | translated = [] 35 | keyIndex = 0 36 | key = key.upper() 37 | 38 | for symbol in message: 39 | num = LETTERS.find(symbol.upper()) 40 | if num != -1: 41 | if mode == 'encrypt': 42 | num += LETTERS.find(key[keyIndex]) 43 | elif mode == 'decrypt': 44 | num -= LETTERS.find(key[keyIndex]) 45 | 46 | num %= len(LETTERS) 47 | 48 | if symbol.isupper(): 49 | translated.append(LETTERS[num]) 50 | elif symbol.islower(): 51 | translated.append(LETTERS[num].lower()) 52 | 53 | keyIndex += 1 54 | if keyIndex == len(key): 55 | keyIndex = 0 56 | else: 57 | translated.append(symbol) 58 | return ''.join(translated) 59 | 60 | if __name__ == '__main__': 61 | main() 62 | -------------------------------------------------------------------------------- /dynamic_programming/fibonacci.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a pure Python implementation of Dynamic Programming solution to the fibonacci sequence problem. 3 | """ 4 | from __future__ import print_function 5 | 6 | 7 | class Fibonacci: 8 | 9 | def __init__(self, N=None): 10 | self.fib_array = [] 11 | if N: 12 | N = int(N) 13 | self.fib_array.append(0) 14 | self.fib_array.append(1) 15 | for i in range(2, N + 1): 16 | self.fib_array.append(self.fib_array[i - 1] + self.fib_array[i - 2]) 17 | elif N == 0: 18 | self.fib_array.append(0) 19 | 20 | def get(self, sequence_no=None): 21 | if sequence_no != None: 22 | if sequence_no < len(self.fib_array): 23 | return print(self.fib_array[:sequence_no + 1]) 24 | else: 25 | print("Out of bound.") 26 | else: 27 | print("Please specify a value") 28 | 29 | 30 | if __name__ == '__main__': 31 | print("\n********* Fibonacci Series Using Dynamic Programming ************\n") 32 | try: 33 | raw_input # Python 2 34 | except NameError: 35 | raw_input = input # Python 3 36 | 37 | print("\n Enter the upper limit for the fibonacci sequence: ", end="") 38 | try: 39 | N = eval(raw_input().strip()) 40 | fib = Fibonacci(N) 41 | print( 42 | "\n********* Enter different values to get the corresponding fibonacci sequence, enter any negative number to exit. ************\n") 43 | while True: 44 | print("Enter value: ", end=" ") 45 | try: 46 | i = eval(raw_input().strip()) 47 | if i < 0: 48 | print("\n********* Good Bye!! ************\n") 49 | break 50 | fib.get(i) 51 | except NameError: 52 | print("\nInvalid input, please try again.") 53 | except NameError: 54 | print("\n********* Invalid input, good bye!! ************\n") 55 | -------------------------------------------------------------------------------- /data_structures/linked_list/swapNodes.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, data): 3 | self.data = data; 4 | self.next = None 5 | 6 | 7 | class Linkedlist: 8 | def __init__(self): 9 | self.head = None 10 | 11 | def print_list(self): 12 | temp = self.head 13 | while temp is not None: 14 | print(temp.data) 15 | temp = temp.next 16 | 17 | # adding nodes 18 | def push(self, new_data): 19 | new_node = Node(new_data) 20 | new_node.next = self.head 21 | self.head = new_node 22 | 23 | # swapping nodes 24 | def swapNodes(self, d1, d2): 25 | prevD1 = None 26 | prevD2 = None 27 | if d1 == d2: 28 | return 29 | else: 30 | # find d1 31 | D1 = self.head 32 | while D1 is not None and D1.data != d1: 33 | prevD1 = D1 34 | D1 = D1.next 35 | # find d2 36 | D2 = self.head 37 | while D2 is not None and D2.data != d2: 38 | prevD2 = D2 39 | D2 = D2.next 40 | if D1 is None and D2 is None: 41 | return 42 | # if D1 is head 43 | if prevD1 is not None: 44 | prevD1.next = D2 45 | else: 46 | self.head = D2 47 | # if D2 is head 48 | if prevD2 is not None: 49 | prevD2.next = D1 50 | else: 51 | self.head = D1 52 | temp = D1.next 53 | D1.next = D2.next 54 | D2.next = temp 55 | 56 | # swapping code ends here 57 | 58 | 59 | 60 | if __name__ == '__main__': 61 | list = Linkedlist() 62 | list.push(5) 63 | list.push(4) 64 | list.push(3) 65 | list.push(2) 66 | list.push(1) 67 | 68 | list.print_list() 69 | 70 | list.swapNodes(1, 4) 71 | print("After swapping") 72 | list.print_list() 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /data_structures/stacks/postfix_evaluation.py: -------------------------------------------------------------------------------- 1 | """ 2 | Output: 3 | 4 | Enter a Postfix Equation (space separated) = 5 6 9 * + 5 | Symbol | Action | Stack 6 | ----------------------------------- 7 | 5 | push(5) | 5 8 | 6 | push(6) | 5,6 9 | 9 | push(9) | 5,6,9 10 | | pop(9) | 5,6 11 | | pop(6) | 5 12 | * | push(6*9) | 5,54 13 | | pop(54) | 5 14 | | pop(5) | 15 | + | push(5+54) | 59 16 | 17 | Result = 59 18 | """ 19 | 20 | import operator as op 21 | 22 | def Solve(Postfix): 23 | Stack = [] 24 | Div = lambda x, y: int(x/y) # integer division operation 25 | Opr = {'^':op.pow, '*':op.mul, '/':Div, '+':op.add, '-':op.sub} # operators & their respective operation 26 | 27 | # print table header 28 | print('Symbol'.center(8), 'Action'.center(12), 'Stack', sep = " | ") 29 | print('-'*(30+len(Postfix))) 30 | 31 | for x in Postfix: 32 | if( x.isdigit() ): # if x in digit 33 | Stack.append(x) # append x to stack 34 | print(x.rjust(8), ('push('+x+')').ljust(12), ','.join(Stack), sep = " | ") # output in tabular format 35 | else: 36 | B = Stack.pop() # pop stack 37 | print("".rjust(8), ('pop('+B+')').ljust(12), ','.join(Stack), sep = " | ") # output in tabular format 38 | 39 | A = Stack.pop() # pop stack 40 | print("".rjust(8), ('pop('+A+')').ljust(12), ','.join(Stack), sep = " | ") # output in tabular format 41 | 42 | Stack.append( str(Opr[x](int(A), int(B))) ) # evaluate the 2 values poped from stack & push result to stack 43 | print(x.rjust(8), ('push('+A+x+B+')').ljust(12), ','.join(Stack), sep = " | ") # output in tabular format 44 | 45 | return int(Stack[0]) 46 | 47 | 48 | if __name__ == "__main__": 49 | Postfix = input("\n\nEnter a Postfix Equation (space separated) = ").split(' ') 50 | print("\n\tResult = ", Solve(Postfix)) 51 | --------------------------------------------------------------------------------