Merge branch 'master' into revert-22-patch-1

This commit is contained in:
Harshil 2018-01-20 16:27:17 +05:30 committed by GitHub
commit 1611f40c51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
155 changed files with 244843 additions and 185 deletions

1
.gitignore vendored
View File

@ -88,3 +88,4 @@ ENV/
# Rope project settings
.ropeproject
.idea
.DS_Store

View File

@ -1,11 +1,26 @@
language: python
cache: pip
python:
- "3.2"
- "3.3"
- "3.4"
- "3.5"
install:
- if [ "$TRAVIS_PYTHON_VERSION" == "3.2" ]; then travis_retry pip install coverage==3.7.1; fi
- if [ "$TRAVIS_PYTHON_VERSION" != "3.2" ]; then travis_retry pip install coverage; fi
- "pip install pytest pytest-cov"
script: py.test --doctest-modules --cov ./
- 2.7
- 3.6
#- nightly
#- pypy
#- pypy3
matrix:
allow_failures:
- python: nightly
- python: pypy
- python: pypy3
install:
#- pip install -r requirements.txt
- pip install flake8 # pytest # add another testing frameworks later
before_script:
# stop the build if there are Python syntax errors or undefined names
- flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
script:
- true # pytest --capture=sys # add other tests here
notifications:
on_success: change
on_failure: change # `always` will be the setting once code changes slow down

33
Bisection.py Normal file
View File

@ -0,0 +1,33 @@
import math
def bisection(function, a, b): # finds where the function becomes 0 in [a,b] using bolzano
start = a
end = b
if function(a) == 0: # one of the a or b is a root for the function
return a
elif function(b) == 0:
return b
elif function(a) * function(b) > 0: # if none of these are root and they are both positive or negative,
# then his algorithm can't find the root
print("couldn't find root in [a,b]")
return
else:
mid = (start + end) / 2
while abs(start - mid) > 0.0000001: # until we achieve precise equals to 10^-7
if function(mid) == 0:
return mid
elif function(mid) * function(start) < 0:
end = mid
else:
start = mid
mid = (start + end) / 2
return mid
def f(x):
return math.pow(x, 3) - 2*x - 5
print(bisection(f, 1, 1000))

View File

@ -0,0 +1,58 @@
# server
import socket # Import socket module
port = 60000 # Reserve a port for your service.
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
print 'Server listening....'
while True:
conn, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
data = conn.recv(1024)
print('Server received', repr(data))
filename='mytext.txt'
f = open(filename,'rb')
l = f.read(1024)
while (l):
conn.send(l)
print('Sent ',repr(l))
l = f.read(1024)
f.close()
print('Done sending')
conn.send('Thank you for connecting')
conn.close()
# client side server
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 60000 # Reserve a port for your service.
s.connect((host, port))
s.send("Hello server!")
with open('received_file', 'wb') as f:
print 'file opened'
while True:
print('receiving data...')
data = s.recv(1024)
print('data=%s', (data))
if not data:
break
# write data to a file
f.write(data)
f.close()
print('Successfully get the file')
s.close()
print('connection closed')

View File

@ -0,0 +1,36 @@
"""
File transfer protocol used to send and receive files using FTP server.
Use credentials to provide access to the FTP client
Note: Do not use root username & password for security reasons
Create a seperate user and provide access to a home directory of the user
Use login id and password of the user created
cwd here stands for current working directory
"""
from ftplib import FTP
ftp = FTP('xxx.xxx.x.x') # Enter the ip address or the domain name here
ftp.login(user='username', passwd='password')
ftp.cwd('/Enter the directory here/')
"""
The file which will be received via the FTP server
Enter the location of the file where the file is received
"""
def ReceiveFile():
FileName = 'example.txt' """ Enter the location of the file """
LocalFile = open(FileName, 'wb')
ftp.retrbinary('RETR ' + FileName, LocalFile.write, 1024)
ftp.quit()
LocalFile.close()
"""
The file which will be sent via the FTP server
The file send will be send to the current working directory
"""
def SendFile():
FileName = 'example.txt' """ Enter the name of the file """
ftp.storbinary('STOR ' + FileName, open(FileName, 'rb'))
ftp.quit()

102
Graphs/a_star.py Normal file
View File

@ -0,0 +1,102 @@
from __future__ import print_function
grid = [[0, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0],#0 are free path whereas 1's are obstacles
[0, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 1, 0],
[0, 0, 0, 0, 1, 0]]
'''
heuristic = [[9, 8, 7, 6, 5, 4],
[8, 7, 6, 5, 4, 3],
[7, 6, 5, 4, 3, 2],
[6, 5, 4, 3, 2, 1],
[5, 4, 3, 2, 1, 0]]'''
init = [0, 0]
goal = [len(grid)-1, len(grid[0])-1] #all coordinates are given in format [y,x]
cost = 1
#the cost map which pushes the path closer to the goal
heuristic = [[0 for row in range(len(grid[0]))] for col in range(len(grid))]
for i in range(len(grid)):
for j in range(len(grid[0])):
heuristic[i][j] = abs(i - goal[0]) + abs(j - goal[1])
if grid[i][j] == 1:
heuristic[i][j] = 99 #added extra penalty in the heuristic map
#the actions we can take
delta = [[-1, 0 ], # go up
[ 0, -1], # go left
[ 1, 0 ], # go down
[ 0, 1 ]] # go right
#function to search the path
def search(grid,init,goal,cost,heuristic):
closed = [[0 for col in range(len(grid[0]))] for row in range(len(grid))]# the referrence grid
closed[init[0]][init[1]] = 1
action = [[0 for col in range(len(grid[0]))] for row in range(len(grid))]#the action grid
x = init[0]
y = init[1]
g = 0
f = g + heuristic[init[0]][init[0]]
cell = [[f, g, x, y]]
found = False # flag that is set when search is complete
resign = False # flag set if we can't find expand
while not found and not resign:
if len(cell) == 0:
resign = True
return "FAIL"
else:
cell.sort()#to choose the least costliest action so as to move closer to the goal
cell.reverse()
next = cell.pop()
x = next[2]
y = next[3]
g = next[1]
f = next[0]
if x == goal[0] and y == goal[1]:
found = True
else:
for i in range(len(delta)):#to try out different valid actions
x2 = x + delta[i][0]
y2 = y + delta[i][1]
if x2 >= 0 and x2 < len(grid) and y2 >=0 and y2 < len(grid[0]):
if closed[x2][y2] == 0 and grid[x2][y2] == 0:
g2 = g + cost
f2 = g2 + heuristic[x2][y2]
cell.append([f2, g2, x2, y2])
closed[x2][y2] = 1
action[x2][y2] = i
invpath = []
x = goal[0]
y = goal[1]
invpath.append([x, y])#we get the reverse path from here
while x != init[0] or y != init[1]:
x2 = x - delta[action[x][y]][0]
y2 = y - delta[action[x][y]][1]
x = x2
y = y2
invpath.append([x, y])
path = []
for i in range(len(invpath)):
path.append(invpath[len(invpath) - 1 - i])
print("ACTION MAP")
for i in range(len(action)):
print(action[i])
return path
a = search(grid,init,goal,cost,heuristic)
for i in range(len(a)):
print(a[i])

281
Graphs/basic-graphs.py Normal file
View File

@ -0,0 +1,281 @@
from __future__ import print_function
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
try:
xrange # Python 2
except NameError:
xrange = range # Python 3
# Accept No. of Nodes and edges
n, m = map(int, raw_input().split(" "))
# Initialising Dictionary of edges
g = {}
for i in xrange(n):
g[i + 1] = []
"""
--------------------------------------------------------------------------------
Accepting edges of Unweighted Directed Graphs
--------------------------------------------------------------------------------
"""
for _ in xrange(m):
x, y = map(int, raw_input().split(" "))
g[x].append(y)
"""
--------------------------------------------------------------------------------
Accepting edges of Unweighted Undirected Graphs
--------------------------------------------------------------------------------
"""
for _ in xrange(m):
x, y = map(int, raw_input().split(" "))
g[x].append(y)
g[y].append(x)
"""
--------------------------------------------------------------------------------
Accepting edges of Weighted Undirected Graphs
--------------------------------------------------------------------------------
"""
for _ in xrange(m):
x, y, r = map(int, raw_input().split(" "))
g[x].append([y, r])
g[y].append([x, r])
"""
--------------------------------------------------------------------------------
Depth First Search.
Args : G - Dictionary of edges
s - Starting Node
Vars : vis - Set of visited nodes
S - Traversal Stack
--------------------------------------------------------------------------------
"""
def dfs(G, s):
vis, S = set([s]), [s]
print(s)
while S:
flag = 0
for i in G[S[-1]]:
if i not in vis:
S.append(i)
vis.add(i)
flag = 1
print(i)
break
if not flag:
S.pop()
"""
--------------------------------------------------------------------------------
Breadth First Search.
Args : G - Dictionary of edges
s - Starting Node
Vars : vis - Set of visited nodes
Q - Traveral Stack
--------------------------------------------------------------------------------
"""
from collections import deque
def bfs(G, s):
vis, Q = set([s]), deque([s])
print(s)
while Q:
u = Q.popleft()
for v in G[u]:
if v not in vis:
vis.add(v)
Q.append(v)
print(v)
"""
--------------------------------------------------------------------------------
Dijkstra's shortest path Algorithm
Args : G - Dictionary of edges
s - Starting Node
Vars : dist - Dictionary storing shortest distance from s to every other node
known - Set of knows nodes
path - Preceding node in path
--------------------------------------------------------------------------------
"""
def dijk(G, s):
dist, known, path = {s: 0}, set(), {s: 0}
while True:
if len(known) == len(G) - 1:
break
mini = 100000
for i in dist:
if i not in known and dist[i] < mini:
mini = dist[i]
u = i
known.add(u)
for v in G[u]:
if v[0] not in known:
if dist[u] + v[1] < dist.get(v[0], 100000):
dist[v[0]] = dist[u] + v[1]
path[v[0]] = u
for i in dist:
if i != s:
print(dist[i])
"""
--------------------------------------------------------------------------------
Topological Sort
--------------------------------------------------------------------------------
"""
from collections import deque
def topo(G, ind=None, Q=[1]):
if ind == None:
ind = [0] * (len(G) + 1) # SInce oth Index is ignored
for u in G:
for v in G[u]:
ind[v] += 1
Q = deque()
for i in G:
if ind[i] == 0:
Q.append(i)
if len(Q) == 0:
return
v = Q.popleft()
print(v)
for w in G[v]:
ind[w] -= 1
if ind[w] == 0:
Q.append(w)
topo(G, ind, Q)
"""
--------------------------------------------------------------------------------
Reading an Adjacency matrix
--------------------------------------------------------------------------------
"""
def adjm():
n, a = input(), []
for i in xrange(n):
a.append(map(int, raw_input().split()))
return a, n
"""
--------------------------------------------------------------------------------
Floyd Warshall's algorithm
Args : G - Dictionary of edges
s - Starting Node
Vars : dist - Dictionary storing shortest distance from s to every other node
known - Set of knows nodes
path - Preceding node in path
--------------------------------------------------------------------------------
"""
def floy(A_and_n):
(A, n) = A_and_n
dist = list(A)
path = [[0] * n for i in xrange(n)]
for k in xrange(n):
for i in xrange(n):
for j in xrange(n):
if dist[i][j] > dist[i][k] + dist[k][j]:
dist[i][j] = dist[i][k] + dist[k][j]
path[i][k] = k
print(dist)
"""
--------------------------------------------------------------------------------
Prim's MST Algorithm
Args : G - Dictionary of edges
s - Starting Node
Vars : dist - Dictionary storing shortest distance from s to nearest node
known - Set of knows nodes
path - Preceding node in path
--------------------------------------------------------------------------------
"""
def prim(G, s):
dist, known, path = {s: 0}, set(), {s: 0}
while True:
if len(known) == len(G) - 1:
break
mini = 100000
for i in dist:
if i not in known and dist[i] < mini:
mini = dist[i]
u = i
known.add(u)
for v in G[u]:
if v[0] not in known:
if v[1] < dist.get(v[0], 100000):
dist[v[0]] = v[1]
path[v[0]] = u
"""
--------------------------------------------------------------------------------
Accepting Edge list
Vars : n - Number of nodes
m - Number of edges
Returns : l - Edge list
n - Number of Nodes
--------------------------------------------------------------------------------
"""
def edglist():
n, m = map(int, raw_input().split(" "))
l = []
for i in xrange(m):
l.append(map(int, raw_input().split(' ')))
return l, n
"""
--------------------------------------------------------------------------------
Kruskal's MST Algorithm
Args : E - Edge list
n - Number of Nodes
Vars : s - Set of all nodes as unique disjoint sets (initially)
--------------------------------------------------------------------------------
"""
def krusk(E_and_n):
# Sort edges on the basis of distance
(E, n) = E_and_n
E.sort(reverse=True, key=lambda x: x[2])
s = [set([i]) for i in range(1, n + 1)]
while True:
if len(s) == 1:
break
print(s)
x = E.pop()
for i in xrange(len(s)):
if x[0] in s[i]:
break
for j in xrange(len(s)):
if x[1] in s[j]:
if i == j:
break
s[j].update(s[i])
s.pop(i)
break

View File

@ -0,0 +1,32 @@
from __future__ import print_function
num_nodes, num_edges = list(map(int,input().split()))
edges = []
for i in range(num_edges):
node1, node2, cost = list(map(int,input().split()))
edges.append((i,node1,node2,cost))
edges = sorted(edges, key=lambda edge: edge[3])
parent = [i for i in range(num_nodes)]
def find_parent(i):
if(i != parent[i]):
parent[i] = find_parent(parent[i])
return parent[i]
minimum_spanning_tree_cost = 0
minimum_spanning_tree = []
for edge in edges:
parent_a = find_parent(edge[1])
parent_b = find_parent(edge[2])
if(parent_a != parent_b):
minimum_spanning_tree_cost += edge[3]
minimum_spanning_tree.append(edge)
parent[parent_a] = parent_b
print(minimum_spanning_tree_cost)
for edge in minimum_spanning_tree:
print(edge)

46
Graphs/scc_kosaraju.py Normal file
View File

@ -0,0 +1,46 @@
from __future__ import print_function
# n - no of nodes, m - no of edges
n, m = list(map(int,input().split()))
g = [[] for i in range(n)] #graph
r = [[] for i in range(n)] #reversed graph
# input graph data (edges)
for i in range(m):
u, v = list(map(int,input().split()))
g[u].append(v)
r[v].append(u)
stack = []
visit = [False]*n
scc = []
component = []
def dfs(u):
global g, r, scc, component, visit, stack
if visit[u]: return
visit[u] = True
for v in g[u]:
dfs(v)
stack.append(u)
def dfs2(u):
global g, r, scc, component, visit, stack
if visit[u]: return
visit[u] = True
component.append(u)
for v in r[u]:
dfs2(v)
def kosaraju():
global g, r, scc, component, visit, stack
for i in range(n):
dfs(i)
visit = [False]*n
for i in stack[::-1]:
if visit[i]: continue
component = []
dfs2(i)
scc.append(component)
return scc
print(kosaraju())

78
Graphs/tarjans_scc.py Normal file
View File

@ -0,0 +1,78 @@
from collections import deque
def tarjan(g):
"""
Tarjan's algo for finding strongly connected components in a directed graph
Uses two main attributes of each node to track reachability, the index of that node within a component(index),
and the lowest index reachable from that node(lowlink).
We then perform a dfs of the each component making sure to update these parameters for each node and saving the
nodes we visit on the way.
If ever we find that the lowest reachable node from a current node is equal to the index of the current node then it
must be the root of a strongly connected component and so we save it and it's equireachable vertices as a strongly
connected component.
Complexity: strong_connect() is called at most once for each node and has a complexity of O(|E|) as it is DFS.
Therefore this has complexity O(|V| + |E|) for a graph G = (V, E)
"""
n = len(g)
stack = deque()
on_stack = [False for _ in range(n)]
index_of = [-1 for _ in range(n)]
lowlink_of = index_of[:]
def strong_connect(v, index, components):
index_of[v] = index # the number when this node is seen
lowlink_of[v] = index # lowest rank node reachable from here
index += 1
stack.append(v)
on_stack[v] = True
for w in g[v]:
if index_of[w] == -1:
index = strong_connect(w, index, components)
lowlink_of[v] = lowlink_of[w] if lowlink_of[w] < lowlink_of[v] else lowlink_of[v]
elif on_stack[w]:
lowlink_of[v] = lowlink_of[w] if lowlink_of[w] < lowlink_of[v] else lowlink_of[v]
if lowlink_of[v] == index_of[v]:
component = []
w = stack.pop()
on_stack[w] = False
component.append(w)
while w != v:
w = stack.pop()
on_stack[w] = False
component.append(w)
components.append(component)
return index
components = []
for v in range(n):
if index_of[v] == -1:
strong_connect(v, 0, components)
return components
def create_graph(n, edges):
g = [[] for _ in range(n)]
for u, v in edges:
g[u].append(v)
return g
if __name__ == '__main__':
# Test
n_vertices = 7
source = [0, 0, 1, 2, 3, 3, 4, 4, 6]
target = [1, 3, 2, 0, 1, 4, 5, 6, 5]
edges = [(u, v) for u, v in zip(source, target)]
g = create_graph(n_vertices, edges)
assert [[5], [6], [4], [3, 2, 1, 0]] == tarjan(g)

16
Intersection.py Normal file
View File

@ -0,0 +1,16 @@
import math
def intersection(function,x0,x1): #function is the f we want to find its root and x0 and x1 are two random starting points
x_n = x0
x_n1 = x1
while True:
x_n2 = x_n1-(function(x_n1)/((function(x_n1)-function(x_n))/(x_n1-x_n)))
if abs(x_n2 - x_n1)<0.00001 :
return x_n2
x_n=x_n1
x_n1=x_n2
def f(x):
return math.pow(x,3)-2*x-5
print(intersection(f,3,3.5))

21
License Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016 The Algorithms
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,20 @@
def modularExponential(base, power, mod):
if power < 0:
return -1
base %= mod
result = 1
while power > 0:
if power & 1:
result = (result * base) % mod
power = power >> 1
base = (base * base) % mod
return result
def main():
print(modularExponential(3, 200, 13))
if __name__ == '__main__':
main()

268
Multi_Hueristic_Astar.py Normal file
View File

@ -0,0 +1,268 @@
from __future__ import print_function
import heapq
import numpy as np
import math
import copy
try:
xrange # Python 2
except NameError:
xrange = range # Python 3
class PriorityQueue:
def __init__(self):
self.elements = []
self.set = set()
def minkey(self):
if not self.empty():
return self.elements[0][0]
else:
return float('inf')
def empty(self):
return len(self.elements) == 0
def put(self, item, priority):
if item not in self.set:
heapq.heappush(self.elements, (priority, item))
self.set.add(item)
else:
# update
# print("update", item)
temp = []
(pri, x) = heapq.heappop(self.elements)
while x != item:
temp.append((pri, x))
(pri, x) = heapq.heappop(self.elements)
temp.append((priority, item))
for (pro, xxx) in temp:
heapq.heappush(self.elements, (pro, xxx))
def remove_element(self, item):
if item in self.set:
self.set.remove(item)
temp = []
(pro, x) = heapq.heappop(self.elements)
while x != item:
temp.append((pro, x))
(pro, x) = heapq.heappop(self.elements)
for (prito, yyy) in temp:
heapq.heappush(self.elements, (prito, yyy))
def top_show(self):
return self.elements[0][1]
def get(self):
(priority, item) = heapq.heappop(self.elements)
self.set.remove(item)
return (priority, item)
def consistent_hueristic(P, goal):
# euclidean distance
a = np.array(P)
b = np.array(goal)
return np.linalg.norm(a - b)
def hueristic_2(P, goal):
# integer division by time variable
return consistent_hueristic(P, goal) // t
def hueristic_1(P, goal):
# manhattan distance
return abs(P[0] - goal[0]) + abs(P[1] - goal[1])
def key(start, i, goal, g_function):
ans = g_function[start] + W1 * hueristics[i](start, goal)
return ans
def do_something(back_pointer, goal, start):
grid = np.chararray((n, n))
for i in range(n):
for j in range(n):
grid[i][j] = '*'
for i in range(n):
for j in range(n):
if (j, (n-1)-i) in blocks:
grid[i][j] = "#"
grid[0][(n-1)] = "-"
x = back_pointer[goal]
while x != start:
(x_c, y_c) = x
# print(x)
grid[(n-1)-y_c][x_c] = "-"
x = back_pointer[x]
grid[(n-1)][0] = "-"
for i in xrange(n):
for j in range(n):
if (i, j) == (0, n-1):
print(grid[i][j], end=' ')
print("<-- End position", end=' ')
else:
print(grid[i][j], end=' ')
print()
print("^")
print("Start position")
print()
print("# is an obstacle")
print("- is the path taken by algorithm")
print("PATH TAKEN BY THE ALGORITHM IS:-")
x = back_pointer[goal]
while x != start:
print(x, end=' ')
x = back_pointer[x]
print(x)
quit()
def valid(p):
if p[0] < 0 or p[0] > n-1:
return False
if p[1] < 0 or p[1] > n-1:
return False
return True
def expand_state(s, j, visited, g_function, close_list_anchor, close_list_inad, open_list, back_pointer):
for itera in range(n_hueristic):
open_list[itera].remove_element(s)
# print("s", s)
# print("j", j)
(x, y) = s
left = (x-1, y)
right = (x+1, y)
up = (x, y+1)
down = (x, y-1)
for neighbours in [left, right, up, down]:
if neighbours not in blocks:
if valid(neighbours) and neighbours not in visited:
# print("neighbour", neighbours)
visited.add(neighbours)
back_pointer[neighbours] = -1
g_function[neighbours] = float('inf')
if valid(neighbours) and g_function[neighbours] > g_function[s] + 1:
g_function[neighbours] = g_function[s] + 1
back_pointer[neighbours] = s
if neighbours not in close_list_anchor:
open_list[0].put(neighbours, key(neighbours, 0, goal, g_function))
if neighbours not in close_list_inad:
for var in range(1,n_hueristic):
if key(neighbours, var, goal, g_function) <= W2 * key(neighbours, 0, goal, g_function):
# print("why not plssssssssss")
open_list[j].put(neighbours, key(neighbours, var, goal, g_function))
# print
def make_common_ground():
some_list = []
# block 1
for x in range(1, 5):
for y in range(1, 6):
some_list.append((x, y))
# line
for x in range(15, 20):
some_list.append((x, 17))
# block 2 big
for x in range(10, 19):
for y in range(1, 15):
some_list.append((x, y))
# L block
for x in range(1, 4):
for y in range(12, 19):
some_list.append((x, y))
for x in range(3, 13):
for y in range(16, 19):
some_list.append((x, y))
return some_list
hueristics = {0: consistent_hueristic, 1: hueristic_1, 2: hueristic_2}
blocks_blk = [(0, 1),(1, 1),(2, 1),(3, 1),(4, 1),(5, 1),(6, 1),(7, 1),(8, 1),(9, 1),(10, 1),(11, 1),(12, 1),(13, 1),(14, 1),(15, 1),(16, 1),(17, 1),(18, 1), (19, 1)]
blocks_no = []
blocks_all = make_common_ground()
blocks = blocks_blk
# hyper parameters
W1 = 1
W2 = 1
n = 20
n_hueristic = 3 # one consistent and two other inconsistent
# start and end destination
start = (0, 0)
goal = (n-1, n-1)
t = 1
def multi_a_star(start, goal, n_hueristic):
g_function = {start: 0, goal: float('inf')}
back_pointer = {start:-1, goal:-1}
open_list = []
visited = set()
for i in range(n_hueristic):
open_list.append(PriorityQueue())
open_list[i].put(start, key(start, i, goal, g_function))
close_list_anchor = []
close_list_inad = []
while open_list[0].minkey() < float('inf'):
for i in range(1, n_hueristic):
# print("i", i)
# print(open_list[0].minkey(), open_list[i].minkey())
if open_list[i].minkey() <= W2 * open_list[0].minkey():
global t
t += 1
# print("less prio")
if g_function[goal] <= open_list[i].minkey():
if g_function[goal] < float('inf'):
do_something(back_pointer, goal, start)
else:
_, get_s = open_list[i].top_show()
visited.add(get_s)
expand_state(get_s, i, visited, g_function, close_list_anchor, close_list_inad, open_list, back_pointer)
close_list_inad.append(get_s)
else:
# print("more prio")
if g_function[goal] <= open_list[0].minkey():
if g_function[goal] < float('inf'):
do_something(back_pointer, goal, start)
else:
# print("hoolla")
get_s = open_list[0].top_show()
visited.add(get_s)
expand_state(get_s, 0, visited, g_function, close_list_anchor, close_list_inad, open_list, back_pointer)
close_list_anchor.append(get_s)
print("No path found to goal")
print()
for i in range(n-1,-1, -1):
for j in range(n):
if (j, i) in blocks:
print('#', end=' ')
elif (j, i) in back_pointer:
if (j, i) == (n-1, n-1):
print('*', end=' ')
else:
print('-', end=' ')
else:
print('*', end=' ')
if (j, i) == (n-1, n-1):
print('<-- End position', end=' ')
print()
print("^")
print("Start position")
print()
print("# is an obstacle")
print("- is the path taken by algorithm")
multi_a_star(start, goal, n_hueristic)

190
Neural_Network/bpnn.py Normal file
View File

@ -0,0 +1,190 @@
'''
A Framework of Back Propagation Neural NetworkBP model
Easy to use:
* add many layers as you want
* clearly see how the loss decreasing
Easy to expand:
* more activation functions
* more loss functions
* more optimization method
Author: Stephen Lee
Github : https://github.com/RiptideBo
Date: 2017.11.23
'''
import numpy as np
import matplotlib.pyplot as plt
def sigmoid(x):
return 1 / (1 + np.exp(-1 * x))
class DenseLayer():
'''
Layers of BP neural network
'''
def __init__(self,units,activation=None,learning_rate=None,is_input_layer=False):
'''
common connected layer of bp network
:param units: numbers of neural units
:param activation: activation function
:param learning_rate: learning rate for paras
:param is_input_layer: whether it is input layer or not
'''
self.units = units
self.weight = None
self.bias = None
self.activation = activation
if learning_rate is None:
learning_rate = 0.3
self.learn_rate = learning_rate
self.is_input_layer = is_input_layer
def initializer(self,back_units):
self.weight = np.asmatrix(np.random.normal(0,0.5,(self.units,back_units)))
self.bias = np.asmatrix(np.random.normal(0,0.5,self.units)).T
if self.activation is None:
self.activation = sigmoid
def cal_gradient(self):
if self.activation == sigmoid:
gradient_mat = np.dot(self.output ,(1- self.output).T)
gradient_activation = np.diag(np.diag(gradient_mat))
else:
gradient_activation = 1
return gradient_activation
def forward_propagation(self,xdata):
self.xdata = xdata
if self.is_input_layer:
# input layer
self.wx_plus_b = xdata
self.output = xdata
return xdata
else:
self.wx_plus_b = np.dot(self.weight,self.xdata) - self.bias
self.output = self.activation(self.wx_plus_b)
return self.output
def back_propagation(self,gradient):
gradient_activation = self.cal_gradient() # i * i 维
gradient = np.asmatrix(np.dot(gradient.T,gradient_activation))
self._gradient_weight = np.asmatrix(self.xdata)
self._gradient_bias = -1
self._gradient_x = self.weight
self.gradient_weight = np.dot(gradient.T,self._gradient_weight.T)
self.gradient_bias = gradient * self._gradient_bias
self.gradient = np.dot(gradient,self._gradient_x).T
# ----------------------upgrade
# -----------the Negative gradient direction --------
self.weight = self.weight - self.learn_rate * self.gradient_weight
self.bias = self.bias - self.learn_rate * self.gradient_bias.T
return self.gradient
class BPNN():
'''
Back Propagation Neural Network model
'''
def __init__(self):
self.layers = []
self.train_mse = []
self.fig_loss = plt.figure()
self.ax_loss = self.fig_loss.add_subplot(1,1,1)
def add_layer(self,layer):
self.layers.append(layer)
def build(self):
for i,layer in enumerate(self.layers[:]):
if i < 1:
layer.is_input_layer = True
else:
layer.initializer(self.layers[i-1].units)
def summary(self):
for i,layer in enumerate(self.layers[:]):
print('------- layer %d -------'%i)
print('weight.shape ',np.shape(layer.weight))
print('bias.shape ',np.shape(layer.bias))
def train(self,xdata,ydata,train_round,accuracy):
self.train_round = train_round
self.accuracy = accuracy
self.ax_loss.hlines(self.accuracy, 0, self.train_round * 1.1)
x_shape = np.shape(xdata)
for round_i in range(train_round):
all_loss = 0
for row in range(x_shape[0]):
_xdata = np.asmatrix(xdata[row,:]).T
_ydata = np.asmatrix(ydata[row,:]).T
# forward propagation
for layer in self.layers:
_xdata = layer.forward_propagation(_xdata)
loss, gradient = self.cal_loss(_ydata, _xdata)
all_loss = all_loss + loss
# back propagation
# the input_layer does not upgrade
for layer in self.layers[:0:-1]:
gradient = layer.back_propagation(gradient)
mse = all_loss/x_shape[0]
self.train_mse.append(mse)
self.plot_loss()
if mse < self.accuracy:
print('----达到精度----')
return mse
def cal_loss(self,ydata,ydata_):
self.loss = np.sum(np.power((ydata - ydata_),2))
self.loss_gradient = 2 * (ydata_ - ydata)
# vector (shape is the same as _ydata.shape)
return self.loss,self.loss_gradient
def plot_loss(self):
if self.ax_loss.lines:
self.ax_loss.lines.remove(self.ax_loss.lines[0])
self.ax_loss.plot(self.train_mse, 'r-')
plt.ion()
plt.show()
plt.pause(0.1)
def example():
x = np.random.randn(10,10)
y = np.asarray([[0.8,0.4],[0.4,0.3],[0.34,0.45],[0.67,0.32],
[0.88,0.67],[0.78,0.77],[0.55,0.66],[0.55,0.43],[0.54,0.1],
[0.1,0.5]])
model = BPNN()
model.add_layer(DenseLayer(10))
model.add_layer(DenseLayer(20))
model.add_layer(DenseLayer(30))
model.add_layer(DenseLayer(2))
model.build()
model.summary()
model.train(xdata=x,ydata=y,train_round=100,accuracy=0.01)
if __name__ == '__main__':
example()

View File

@ -0,0 +1,306 @@
#-*- coding: utf-8 -*-
'''
- - - - - -- - - - - - - - - - - - - - - - - - - - - - -
Name - - CNN - Convolution Neural Network For Photo Recognizing
Goal - - Recognize Handing Writting Word Photo
DetailTotal 5 layers neural network
* Convolution layer
* Pooling layer
* Input layer layer of BP
* Hiden layer of BP
* Output layer of BP
Author: Stephen Lee
Github: 245885195@qq.com
Date: 2017.9.20
- - - - - -- - - - - - - - - - - - - - - - - - - - - - -
'''
from __future__ import print_function
import numpy as np
import matplotlib.pyplot as plt
class CNN():
def __init__(self,conv1_get,size_p1,bp_num1,bp_num2,bp_num3,rate_w=0.2,rate_t=0.2):
'''
:param conv1_get: [a,c,d]size, number, step of convolution kernel
:param size_p1: pooling size
:param bp_num1: units number of flatten layer
:param bp_num2: units number of hidden layer
:param bp_num3: units number of output layer
:param rate_w: rate of weight learning
:param rate_t: rate of threshold learning
'''
self.num_bp1 = bp_num1
self.num_bp2 = bp_num2
self.num_bp3 = bp_num3
self.conv1 = conv1_get[:2]
self.step_conv1 = conv1_get[2]
self.size_pooling1 = size_p1
self.rate_weight = rate_w
self.rate_thre = rate_t
self.w_conv1 = [np.mat(-1*np.random.rand(self.conv1[0],self.conv1[0])+0.5) for i in range(self.conv1[1])]
self.wkj = np.mat(-1 * np.random.rand(self.num_bp3, self.num_bp2) + 0.5)
self.vji = np.mat(-1*np.random.rand(self.num_bp2, self.num_bp1)+0.5)
self.thre_conv1 = -2*np.random.rand(self.conv1[1])+1
self.thre_bp2 = -2*np.random.rand(self.num_bp2)+1
self.thre_bp3 = -2*np.random.rand(self.num_bp3)+1
def save_model(self,save_path):
#save model dict with pickle
import pickle
model_dic = {'num_bp1':self.num_bp1,
'num_bp2':self.num_bp2,
'num_bp3':self.num_bp3,
'conv1':self.conv1,
'step_conv1':self.step_conv1,
'size_pooling1':self.size_pooling1,
'rate_weight':self.rate_weight,
'rate_thre':self.rate_thre,
'w_conv1':self.w_conv1,
'wkj':self.wkj,
'vji':self.vji,
'thre_conv1':self.thre_conv1,
'thre_bp2':self.thre_bp2,
'thre_bp3':self.thre_bp3}
with open(save_path, 'wb') as f:
pickle.dump(model_dic, f)
print('Model saved %s'% save_path)
@classmethod
def ReadModel(cls,model_path):
#read saved model
import pickle
with open(model_path, 'rb') as f:
model_dic = pickle.load(f)
conv_get= model_dic.get('conv1')
conv_get.append(model_dic.get('step_conv1'))
size_p1 = model_dic.get('size_pooling1')
bp1 = model_dic.get('num_bp1')
bp2 = model_dic.get('num_bp2')
bp3 = model_dic.get('num_bp3')
r_w = model_dic.get('rate_weight')
r_t = model_dic.get('rate_thre')
#create model instance
conv_ins = CNN(conv_get,size_p1,bp1,bp2,bp3,r_w,r_t)
#modify model parameter
conv_ins.w_conv1 = model_dic.get('w_conv1')
conv_ins.wkj = model_dic.get('wkj')
conv_ins.vji = model_dic.get('vji')
conv_ins.thre_conv1 = model_dic.get('thre_conv1')
conv_ins.thre_bp2 = model_dic.get('thre_bp2')
conv_ins.thre_bp3 = model_dic.get('thre_bp3')
return conv_ins
def sig(self,x):
return 1 / (1 + np.exp(-1*x))
def do_round(self,x):
return round(x, 3)
def convolute(self,data,convs,w_convs,thre_convs,conv_step):
#convolution process
size_conv = convs[0]
num_conv =convs[1]
size_data = np.shape(data)[0]
#get the data slice of original image data, data_focus
data_focus = []
for i_focus in range(0, size_data - size_conv + 1, conv_step):
for j_focus in range(0, size_data - size_conv + 1, conv_step):
focus = data[i_focus:i_focus + size_conv, j_focus:j_focus + size_conv]
data_focus.append(focus)
#caculate the feature map of every single kernel, and saved as list of matrix
data_featuremap = []
Size_FeatureMap = int((size_data - size_conv) / conv_step + 1)
for i_map in range(num_conv):
featuremap = []
for i_focus in range(len(data_focus)):
net_focus = np.sum(np.multiply(data_focus[i_focus], w_convs[i_map])) - thre_convs[i_map]
featuremap.append(self.sig(net_focus))
featuremap = np.asmatrix(featuremap).reshape(Size_FeatureMap, Size_FeatureMap)
data_featuremap.append(featuremap)
#expanding the data slice to One dimenssion
focus1_list = []
for each_focus in data_focus:
focus1_list.extend(self.Expand_Mat(each_focus))
focus_list = np.asarray(focus1_list)
return focus_list,data_featuremap
def pooling(self,featuremaps,size_pooling,type='average_pool'):
#pooling process
size_map = len(featuremaps[0])
size_pooled = int(size_map/size_pooling)
featuremap_pooled = []
for i_map in range(len(featuremaps)):
map = featuremaps[i_map]
map_pooled = []
for i_focus in range(0,size_map,size_pooling):
for j_focus in range(0, size_map, size_pooling):
focus = map[i_focus:i_focus + size_pooling, j_focus:j_focus + size_pooling]
if type == 'average_pool':
#average pooling
map_pooled.append(np.average(focus))
elif type == 'max_pooling':
#max pooling
map_pooled.append(np.max(focus))
map_pooled = np.asmatrix(map_pooled).reshape(size_pooled,size_pooled)
featuremap_pooled.append(map_pooled)
return featuremap_pooled
def _expand(self,datas):
#expanding three dimension data to one dimension list
data_expanded = []
for i in range(len(datas)):
shapes = np.shape(datas[i])
data_listed = datas[i].reshape(1,shapes[0]*shapes[1])
data_listed = data_listed.getA().tolist()[0]
data_expanded.extend(data_listed)
data_expanded = np.asarray(data_expanded)
return data_expanded
def _expand_mat(self,data_mat):
#expanding matrix to one dimension list
data_mat = np.asarray(data_mat)
shapes = np.shape(data_mat)
data_expanded = data_mat.reshape(1,shapes[0]*shapes[1])
return data_expanded
def _calculate_gradient_from_pool(self,out_map,pd_pool,num_map,size_map,size_pooling):
'''
calcluate the gradient from the data slice of pool layer
pd_pool: list of matrix
out_map: the shape of data slice(size_map*size_map)
return: pd_all: list of matrix, [num, size_map, size_map]
'''
pd_all = []
i_pool = 0
for i_map in range(num_map):
pd_conv1 = np.ones((size_map, size_map))
for i in range(0, size_map, size_pooling):
for j in range(0, size_map, size_pooling):
pd_conv1[i:i + size_pooling, j:j + size_pooling] = pd_pool[i_pool]
i_pool = i_pool + 1
pd_conv2 = np.multiply(pd_conv1,np.multiply(out_map[i_map],(1-out_map[i_map])))
pd_all.append(pd_conv2)
return pd_all
def trian(self,patterns,datas_train, datas_teach, n_repeat, error_accuracy,draw_e = bool):
#model traning
print('----------------------Start Training-------------------------')
print((' - - Shape: Train_Data ',np.shape(datas_train)))
print((' - - Shape: Teach_Data ',np.shape(datas_teach)))
rp = 0
all_mse = []
mse = 10000
while rp < n_repeat and mse >= error_accuracy:
alle = 0
print('-------------Learning Time %d--------------'%rp)
for p in range(len(datas_train)):
#print('------------Learning Image: %d--------------'%p)
data_train = np.asmatrix(datas_train[p])
data_teach = np.asarray(datas_teach[p])
data_focus1,data_conved1 = self.convolute(data_train,self.conv1,self.w_conv1,
self.thre_conv1,conv_step=self.step_conv1)
data_pooled1 = self.pooling(data_conved1,self.size_pooling1)
shape_featuremap1 = np.shape(data_conved1)
'''
print(' -----original shape ', np.shape(data_train))
print(' ---- after convolution ',np.shape(data_conv1))
print(' -----after pooling ',np.shape(data_pooled1))
'''
data_bp_input = self._expand(data_pooled1)
bp_out1 = data_bp_input
bp_net_j = np.dot(bp_out1,self.vji.T) - self.thre_bp2
bp_out2 = self.sig(bp_net_j)
bp_net_k = np.dot(bp_out2 ,self.wkj.T) - self.thre_bp3
bp_out3 = self.sig(bp_net_k)
#--------------Model Leaning ------------------------
# calcluate error and gradient---------------
pd_k_all = np.multiply((data_teach - bp_out3), np.multiply(bp_out3, (1 - bp_out3)))
pd_j_all = np.multiply(np.dot(pd_k_all,self.wkj), np.multiply(bp_out2, (1 - bp_out2)))
pd_i_all = np.dot(pd_j_all,self.vji)
pd_conv1_pooled = pd_i_all / (self.size_pooling1*self.size_pooling1)
pd_conv1_pooled = pd_conv1_pooled.T.getA().tolist()
pd_conv1_all = self._calculate_gradient_from_pool(data_conved1,pd_conv1_pooled,shape_featuremap1[0],
shape_featuremap1[1],self.size_pooling1)
#weight and threshold learning process---------
#convolution layer
for k_conv in range(self.conv1[1]):
pd_conv_list = self._expand_mat(pd_conv1_all[k_conv])
delta_w = self.rate_weight * np.dot(pd_conv_list,data_focus1)
self.w_conv1[k_conv] = self.w_conv1[k_conv] + delta_w.reshape((self.conv1[0],self.conv1[0]))
self.thre_conv1[k_conv] = self.thre_conv1[k_conv] - np.sum(pd_conv1_all[k_conv]) * self.rate_thre
#all connected layer
self.wkj = self.wkj + pd_k_all.T * bp_out2 * self.rate_weight
self.vji = self.vji + pd_j_all.T * bp_out1 * self.rate_weight
self.thre_bp3 = self.thre_bp3 - pd_k_all * self.rate_thre
self.thre_bp2 = self.thre_bp2 - pd_j_all * self.rate_thre
# calculate the sum error of all single image
errors = np.sum(abs((data_teach - bp_out3)))
alle = alle + errors
#print(' ----Teach ',data_teach)
#print(' ----BP_output ',bp_out3)
rp = rp + 1
mse = alle/patterns
all_mse.append(mse)
def draw_error():
yplot = [error_accuracy for i in range(int(n_repeat * 1.2))]
plt.plot(all_mse, '+-')
plt.plot(yplot, 'r--')
plt.xlabel('Learning Times')
plt.ylabel('All_mse')
plt.grid(True, alpha=0.5)
plt.show()
print('------------------Training Complished---------------------')
print((' - - Training epoch: ', rp, ' - - Mse: %.6f' % mse))
if draw_e:
draw_error()
return mse
def predict(self,datas_test):
#model predict
produce_out = []
print('-------------------Start Testing-------------------------')
print((' - - Shape: Test_Data ',np.shape(datas_test)))
for p in range(len(datas_test)):
data_test = np.asmatrix(datas_test[p])
data_focus1, data_conved1 = self.convolute(data_test, self.conv1, self.w_conv1,
self.thre_conv1, conv_step=self.step_conv1)
data_pooled1 = self.pooling(data_conved1, self.size_pooling1)
data_bp_input = self._expand(data_pooled1)
bp_out1 = data_bp_input
bp_net_j = bp_out1 * self.vji.T - self.thre_bp2
bp_out2 = self.sig(bp_net_j)
bp_net_k = bp_out2 * self.wkj.T - self.thre_bp3
bp_out3 = self.sig(bp_net_k)
produce_out.extend(bp_out3.getA().tolist())
res = [list(map(self.do_round,each)) for each in produce_out]
return np.asarray(res)
def convolution(self,data):
#return the data of image after convoluting process so we can check it out
data_test = np.asmatrix(data)
data_focus1, data_conved1 = self.convolute(data_test, self.conv1, self.w_conv1,
self.thre_conv1, conv_step=self.step_conv1)
data_pooled1 = self.pooling(data_conved1, self.size_pooling1)
return data_conved1,data_pooled1
if __name__ == '__main__':
pass
'''
I will put the example on other file
'''

View File

@ -0,0 +1,124 @@
'''
Perceptron
w = w + N * (d(k) - y) * x(k)
Using perceptron network for oil analysis,
with Measuring of 3 parameters that represent chemical characteristics we can classify the oil, in p1 or p2
p1 = -1
p2 = 1
'''
from __future__ import print_function
import random
class Perceptron:
def __init__(self, sample, exit, learn_rate=0.01, epoch_number=1000, bias=-1):
self.sample = sample
self.exit = exit
self.learn_rate = learn_rate
self.epoch_number = epoch_number
self.bias = bias
self.number_sample = len(sample)
self.col_sample = len(sample[0])
self.weight = []
def trannig(self):
for sample in self.sample:
sample.insert(0, self.bias)
for i in range(self.col_sample):
self.weight.append(random.random())
self.weight.insert(0, self.bias)
epoch_count = 0
while True:
erro = False
for i in range(self.number_sample):
u = 0
for j in range(self.col_sample + 1):
u = u + self.weight[j] * self.sample[i][j]
y = self.sign(u)
if y != self.exit[i]:
for j in range(self.col_sample + 1):
self.weight[j] = self.weight[j] + self.learn_rate * (self.exit[i] - y) * self.sample[i][j]
erro = True
#print('Epoch: \n',epoch_count)
epoch_count = epoch_count + 1
# if you want controle the epoch or just by erro
if erro == False:
print(('\nEpoch:\n',epoch_count))
print('------------------------\n')
#if epoch_count > self.epoch_number or not erro:
break
def sort(self, sample):
sample.insert(0, self.bias)
u = 0
for i in range(self.col_sample + 1):
u = u + self.weight[i] * sample[i]
y = self.sign(u)
if y == -1:
print(('Sample: ', sample))
print('classification: P1')
else:
print(('Sample: ', sample))
print('classification: P2')
def sign(self, u):
return 1 if u >= 0 else -1
samples = [
[-0.6508, 0.1097, 4.0009],
[-1.4492, 0.8896, 4.4005],
[2.0850, 0.6876, 12.0710],
[0.2626, 1.1476, 7.7985],
[0.6418, 1.0234, 7.0427],
[0.2569, 0.6730, 8.3265],
[1.1155, 0.6043, 7.4446],
[0.0914, 0.3399, 7.0677],
[0.0121, 0.5256, 4.6316],
[-0.0429, 0.4660, 5.4323],
[0.4340, 0.6870, 8.2287],
[0.2735, 1.0287, 7.1934],
[0.4839, 0.4851, 7.4850],
[0.4089, -0.1267, 5.5019],
[1.4391, 0.1614, 8.5843],
[-0.9115, -0.1973, 2.1962],
[0.3654, 1.0475, 7.4858],
[0.2144, 0.7515, 7.1699],
[0.2013, 1.0014, 6.5489],
[0.6483, 0.2183, 5.8991],
[-0.1147, 0.2242, 7.2435],
[-0.7970, 0.8795, 3.8762],
[-1.0625, 0.6366, 2.4707],
[0.5307, 0.1285, 5.6883],
[-1.2200, 0.7777, 1.7252],
[0.3957, 0.1076, 5.6623],
[-0.1013, 0.5989, 7.1812],
[2.4482, 0.9455, 11.2095],
[2.0149, 0.6192, 10.9263],
[0.2012, 0.2611, 5.4631]
]
exit = [-1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1]
network = Perceptron(sample=samples, exit = exit, learn_rate=0.01, epoch_number=1000, bias=-1)
network.trannig()
while True:
sample = []
for i in range(3):
sample.insert(i, float(input('value: ')))
network.sort(sample)

15
NeutonMethod.py Normal file
View File

@ -0,0 +1,15 @@
def newton(function,function1,startingInt): #function is the f(x) and function1 is the f'(x)
x_n=startingInt
while True:
x_n1=x_n-function(x_n)/function1(x_n)
if abs(x_n-x_n1)<0.00001:
return x_n1
x_n=x_n1
def f(x):
return (x**3)-2*x-5
def f1(x):
return 3*(x**2)-2
print(newton(f,f1,3))

View File

@ -0,0 +1,17 @@
'''
Problem Statement:
If we list all the natural numbers below 10 that are multiples of 3 or 5,
we get 3,5,6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below N.
'''
from __future__ import print_function
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
n = int(raw_input().strip())
sum=0
for a in range(3,n):
if(a%3==0 or a%5==0):
sum+=a
print(sum)

View File

@ -0,0 +1,20 @@
'''
Problem Statement:
If we list all the natural numbers below 10 that are multiples of 3 or 5,
we get 3,5,6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below N.
'''
from __future__ import print_function
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
n = int(raw_input().strip())
sum = 0
terms = (n-1)/3
sum+= ((terms)*(6+(terms-1)*3))/2 #sum of an A.P.
terms = (n-1)/5
sum+= ((terms)*(10+(terms-1)*5))/2
terms = (n-1)/15
sum-= ((terms)*(30+(terms-1)*15))/2
print(sum)

View File

@ -0,0 +1,48 @@
'''
Problem Statement:
If we list all the natural numbers below 10 that are multiples of 3 or 5,
we get 3,5,6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below N.
'''
'''
This solution is based on the pattern that the successive numbers in the series follow: 0+3,+2,+1,+3,+1,+2,+3.
'''
from __future__ import print_function
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
n = int(raw_input().strip())
sum=0
num=0
while(1):
num+=3
if(num>=n):
break
sum+=num
num+=2
if(num>=n):
break
sum+=num
num+=1
if(num>=n):
break
sum+=num
num+=3
if(num>=n):
break
sum+=num
num+=1
if(num>=n):
break
sum+=num
num+=2
if(num>=n):
break
sum+=num
num+=3
if(num>=n):
break
sum+=num
print(sum);

View File

@ -0,0 +1,26 @@
'''
Problem:
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2,
the first 10 terms will be:
1,2,3,5,8,13,21,34,55,89,..
By considering the terms in the Fibonacci sequence whose values do not exceed n, find the sum of the even-valued terms.
e.g. for n=10, we have {2,8}, sum is 10.
'''
from __future__ import print_function
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
n = int(raw_input().strip())
i=1
j=2
sum=0
while(j<=n):
if((j&1)==0): #can also use (j%2==0)
sum+=j
temp=i
i=j
j=temp+i
print(sum)

View File

@ -0,0 +1,39 @@
'''
Problem:
The prime factors of 13195 are 5,7,13 and 29. What is the largest prime factor of a given number N?
e.g. for 10, largest prime factor = 5. For 17, largest prime factor = 17.
'''
from __future__ import print_function
import math
def isprime(no):
if(no==2):
return True
elif (no%2==0):
return False
sq = int(math.sqrt(no))+1
for i in range(3,sq,2):
if(no%i==0):
return False
return True
maxNumber = 0
n=int(input())
if(isprime(n)):
print(n)
else:
while (n%2==0):
n=n/2
if(isprime(n)):
print(n)
else:
n1 = int(math.sqrt(n))+1
for i in range(3,n1,2):
if(n%i==0):
if(isprime(n/i)):
maxNumber = n/i
break
elif(isprime(i)):
maxNumber = i
print(maxNumber)

View File

@ -0,0 +1,17 @@
'''
Problem:
The prime factors of 13195 are 5,7,13 and 29. What is the largest prime factor of a given number N?
e.g. for 10, largest prime factor = 5. For 17, largest prime factor = 17.
'''
from __future__ import print_function
n=int(input())
prime=1
i=2
while(i*i<=n):
while(n%i==0):
prime=i
n/=i
i+=1
if(n>1):
prime=n
print(prime)

View File

@ -0,0 +1,29 @@
'''
Problem:
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.
Find the largest palindrome made from the product of two 3-digit numbers which is less than N.
'''
from __future__ import print_function
limit = int(input("limit? "))
# fetchs the next number
for number in range(limit-1,10000,-1):
# converts number into string.
strNumber = str(number)
# checks whether 'strNumber' is a palindrome.
if(strNumber == strNumber[::-1]):
divisor = 999
# if 'number' is a product of two 3-digit numbers
# then number is the answer otherwise fetch next number.
while(divisor != 99):
if((number % divisor == 0) and (len(str(number / divisor)) == 3)):
print(number)
exit(0)
divisor -=1

View File

@ -0,0 +1,19 @@
'''
Problem:
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.
Find the largest palindrome made from the product of two 3-digit numbers which is less than N.
'''
from __future__ import print_function
arr = []
for i in range(999,100,-1):
for j in range(999,100,-1):
t = str(i*j)
if t == t[::-1]:
arr.append(i*j)
arr.sort()
n=int(input())
for i in arr[::-1]:
if(i<n):
print(i)
exit(0)

View File

@ -0,0 +1,21 @@
'''
Problem:
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible(divisible with no remainder) by all of the numbers from 1 to N?
'''
from __future__ import print_function
n = int(input())
i = 0
while 1:
i+=n*(n-1)
nfound=0
for j in range(2,n):
if (i%j != 0):
nfound=1
break
if(nfound==0):
if(i==0):
i=1
print(i)
break

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
'''
Problem:
The sum of the squares of the first ten natural numbers is,
1^2 + 2^2 + ... + 10^2 = 385
The square of the sum of the first ten natural numbers is,
(1 + 2 + ... + 10)^2 = 552 = 3025
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.
Find the difference between the sum of the squares of the first N natural numbers and the square of the sum.
'''
from __future__ import print_function
suma = 0
sumb = 0
n = int(input())
for i in range(1,n+1):
suma += i**2
sumb += i
sum = sumb**2 - suma
print(sum)

View File

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
'''
Problem:
The sum of the squares of the first ten natural numbers is,
1^2 + 2^2 + ... + 10^2 = 385
The square of the sum of the first ten natural numbers is,
(1 + 2 + ... + 10)^2 = 552 = 3025
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.
Find the difference between the sum of the squares of the first N natural numbers and the square of the sum.
'''
from __future__ import print_function
n = int(input())
suma = n*(n+1)/2
suma **= 2
sumb = n*(n+1)*(2*n+1)/6
print(suma-sumb)

View File

@ -0,0 +1,30 @@
'''
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?
'''
from __future__ import print_function
from math import sqrt
def isprime(n):
if (n==2):
return True
elif (n%2==0):
return False
else:
sq = int(sqrt(n))+1
for i in range(3,sq,2):
if(n%i==0):
return False
return True
n = int(input())
i=0
j=1
while(i!=n and j<3):
j+=1
if (isprime(j)):
i+=1
while(i!=n):
j+=2
if(isprime(j)):
i+=1
print(j)

View File

@ -0,0 +1,16 @@
# 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?
def isprime(number):
for i in range(2,int(number**0.5)+1):
if number%i==0:
return False
return True
n = int(input('Enter The N\'th Prime Number You Want To Get: ')) # Ask For The N'th Prime Number Wanted
primes = []
num = 2
while len(primes) < n:
if isprime(num):
primes.append(num)
num += 1
else:
num += 1
print(primes[len(primes) - 1])

View File

@ -0,0 +1,14 @@
'''
Problem Statement:
Work out the first ten digits of the sum of the N 50-digit numbers.
'''
from __future__ import print_function
n = int(input().strip())
array = []
for i in range(n):
array.append(int(input().strip()))
print(str(sum(array))[:10])

View File

@ -0,0 +1,21 @@
from __future__ import print_function
largest_number = 0
pre_counter = 0
for input1 in range(750000,1000000):
counter = 1
number = input1
while number > 1:
if number % 2 == 0:
number /=2
counter += 1
else:
number = (3*number)+1
counter += 1
if counter > pre_counter:
largest_number = input1
pre_counter = counter
print(('Largest Number:',largest_number,'->',pre_counter,'digits'))

View File

@ -0,0 +1,15 @@
power = int(input("Enter the power of 2: "))
num = 2**power
string_num = str(num)
list_num = list(string_num)
sum_of_num = 0
print("2 ^",power,"=",num)
for i in list_num:
sum_of_num += int(i)
print("Sum of the digits are:",sum_of_num)

View File

@ -0,0 +1,27 @@
# Finding the factorial.
def factorial(n):
fact = 1
for i in range(1,n+1):
fact *= i
return fact
# Spliting the digits and adding it.
def split_and_add(number):
sum_of_digits = 0
while(number>0):
last_digit = number % 10
sum_of_digits += last_digit
number = int(number/10) # Removing the last_digit from the given number.
return sum_of_digits
# Taking the user input.
number = int(input("Enter the Number: "))
# Assigning the factorial from the factorial function.
factorial = factorial(number)
# Spliting and adding the factorial into answer.
answer = split_and_add(factorial)
# Printing the answer.
print(answer)

View File

@ -0,0 +1,34 @@
def main():
"""
Consider all integer combinations of ab for 2 <= a <= 5 and 2 <= b <= 5:
22=4, 23=8, 24=16, 25=32
32=9, 33=27, 34=81, 35=243
42=16, 43=64, 44=256, 45=1024
52=25, 53=125, 54=625, 55=3125
If they are then placed in numerical order, with any repeats removed, we get the following sequence of 15 distinct terms:
4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125
How many distinct terms are in the sequence generated by ab for 2 <= a <= 100 and 2 <= b <= 100?
"""
collectPowers = set()
currentPow = 0
N = 101 # maximum limit
for a in range(2,N):
for b in range (2,N):
currentPow = a**b # calculates the current power
collectPowers.add(currentPow) # adds the result to the set
print "Number of terms ", len(collectPowers)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,15 @@
from __future__ import print_function
# Program to find the product of a,b,c which are Pythagorean Triplet that satisfice the following:
# 1. a < b < c
# 2. a**2 + b**2 = c**2
# 3. a + b + c = 1000
print("Please Wait...")
for a in range(300):
for b in range(400):
for c in range(500):
if(a < b < c):
if((a**2) + (b**2) == (c**2)):
if((a+b+c) == 1000):
print(("Product of",a,"*",b,"*",c,"=",(a*b*c)))
break

58
Project Euler/README.md Normal file
View File

@ -0,0 +1,58 @@
# ProjectEuler
Problems are taken from https://projecteuler.net/.
Project Euler is a series of challenging mathematical/computer programming problems that will require more than just mathematical
insights to solve. Project Euler is ideal for mathematicians who are learning to code.
Here the efficiency of your code is also checked.
I've tried to provide all the best possible solutions.
PROBLEMS:
1. If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3,5,6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below N.
2. Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2,
the first 10 terms will be:
1,2,3,5,8,13,21,34,55,89,..
By considering the terms in the Fibonacci sequence whose values do not exceed n, find the sum of the even-valued terms.
e.g. for n=10, we have {2,8}, sum is 10.
3. The prime factors of 13195 are 5,7,13 and 29. What is the largest prime factor of a given number N?
e.g. for 10, largest prime factor = 5. For 17, largest prime factor = 17.
4. A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers which is less than N.
5. 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible(divisible with no remainder) by all of the numbers from 1 to N?
6. The sum of the squares of the first ten natural numbers is,
1^2 + 2^2 + ... + 10^2 = 385
The square of the sum of the first ten natural numbers is,
(1 + 2 + ... + 10)^2 = 552 = 3025
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.
Find the difference between the sum of the squares of the first N natural numbers and the square of the sum.
7. 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?
9. A Pythagorean triplet is a set of three natural numbers, a < b < c, for which,
a^2 + b^2 = c^2
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.
14. The following iterative sequence is defined for the set of positive integers:
n → n/2 (n is even)
n → 3n + 1 (n is odd)
Using the rule above and starting with 13, we generate the following sequence:
13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
Which starting number, under one million, produces the longest chain?
16. 2^15 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.
What is the sum of the digits of the number 2^1000?
20. n! means n × (n 1) × ... × 3 × 2 × 1
For example, 10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800,
and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.
Find the sum of the digits in the number 100!

View File

@ -1,4 +1,4 @@
# The Algorithms - Python [![Build Status](https://travis-ci.org/TheAlgorithms/Python.svg)](https://travis-ci.org/TheAlgorithms/Python)
# The Algorithms - Python <!-- [![Build Status](https://travis-ci.org/TheAlgorithms/Python.svg)](https://travis-ci.org/TheAlgorithms/Python) -->
### All algorithms implemented in Python (for education)
@ -74,7 +74,7 @@ __Properties__
### Shell
![alt text][shell-image]
From [Wikipedia][shell-wiki]: Shellsort is a generalization of insertion sort that allows the exchange of items that are far apart. The idea is to arrange the list of elements so that, starting anywherem considereing every nth element gives a sorted list. Such a list is said to be h-sorted. Equivanelty, it can be thought of as h intterleaved lists, each individually sorted.
From [Wikipedia][shell-wiki]: Shellsort is a generalization of insertion sort that allows the exchange of items that are far apart. The idea is to arrange the list of elements so that, starting anywhere, considering every nth element gives a sorted list. Such a list is said to be h-sorted. Equivalently, it can be thought of as h interleaved lists, each individually sorted.
__Properties__
* Worst case performance O(nlog2 2n)
@ -83,6 +83,14 @@ __Properties__
###### View the algorithm in [action][shell-toptal]
### Time-Compexity Graphs
Comparing the complexity of sorting algorithms (Bubble Sort, Insertion Sort, Selection Sort)
[Complexity Graphs](https://github.com/prateekiiest/Python/blob/master/sorts/sortinggraphs.png)
----------------------------------------------------------------------------------
## Search Algorithms
### Linear
@ -108,6 +116,8 @@ __Properties__
* Average case performance O(log n)
* Worst case space complexity O(1)
----------------------------------------------------------------------------------------------------------------------
## Ciphers
### Caesar
@ -118,6 +128,13 @@ The method is named after **Julius Caesar**, who used it in his private correspo
The encryption step performed by a Caesar cipher is often incorporated as part of more complex schemes, such as the Vigenère cipher, and still has modern application in the ROT13 system. As with all single-alphabet substitution ciphers, the Caesar cipher is easily broken and in modern practice offers essentially no communication security.
###### Source: [Wikipedia](https://en.wikipedia.org/wiki/Caesar_cipher)
### Vigenère
The **Vigenère cipher** is a method of encrypting alphabetic text by using a series of **interwoven Caesar ciphers** based on the letters of a keyword. It is **a form of polyalphabetic substitution**.<br>
The Vigenère cipher has been reinvented many times. The method was originally described by Giovan Battista Bellaso in his 1553 book La cifra del. Sig. Giovan Battista Bellaso; however, the scheme was later misattributed to Blaise de Vigenère in the 19th century, and is now widely known as the "Vigenère cipher".<br>
Though the cipher is easy to understand and implement, for three centuries it resisted all attempts to break it; this earned it the description **le chiffre indéchiffrable**(French for 'the indecipherable cipher').
Many people have tried to implement encryption schemes that are essentially Vigenère ciphers. Friedrich Kasiski was the first to publish a general method of deciphering a Vigenère cipher in 1863.
###### Source: [Wikipedia](https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher)
### Transposition
In cryptography, a **transposition cipher** is a method of encryption by which the positions held by units of plaintext (which are commonly characters or groups of characters) are shifted according to a regular system, so that the ciphertext constitutes a permutation of the plaintext. That is, the order of the units is changed (the plaintext is reordered).<br>
Mathematically a bijective function is used on the characters' positions to encrypt and an inverse function to decrypt.

209
ciphers/XOR_cipher.py Normal file
View File

@ -0,0 +1,209 @@
"""
author: Christian Bender
date: 21.12.2017
class: XORCipher
This class implements the XOR-cipher algorithm and provides
some useful methods for encrypting and decrypting strings and
files.
Overview about methods
- encrypt : list of char
- decrypt : list of char
- encrypt_string : str
- decrypt_string : str
- encrypt_file : boolean
- decrypt_file : boolean
"""
class XORCipher(object):
def __init__(self, key = 0):
"""
simple constructor that receives a key or uses
default key = 0
"""
#private field
self.__key = key
def encrypt(self, content, key):
"""
input: 'content' of type string and 'key' of type int
output: encrypted string 'content' as a list of chars
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
# precondition
assert (isinstance(key,int) and isinstance(content,str))
key = key or self.__key or 1
# make sure key can be any size
while (key > 255):
key -= 255
# This will be returned
ans = []
for ch in content:
ans.append(chr(ord(ch) ^ key))
return ans
def decrypt(self,content,key):
"""
input: 'content' of type list and 'key' of type int
output: decrypted string 'content' as a list of chars
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
# precondition
assert (isinstance(key,int) and isinstance(content,list))
key = key or self.__key or 1
# make sure key can be any size
while (key > 255):
key -= 255
# This will be returned
ans = []
for ch in content:
ans.append(chr(ord(ch) ^ key))
return ans
def encrypt_string(self,content, key = 0):
"""
input: 'content' of type string and 'key' of type int
output: encrypted string 'content'
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
# precondition
assert (isinstance(key,int) and isinstance(content,str))
key = key or self.__key or 1
# make sure key can be any size
while (key > 255):
key -= 255
# This will be returned
ans = ""
for ch in content:
ans += chr(ord(ch) ^ key)
return ans
def decrypt_string(self,content,key = 0):
"""
input: 'content' of type string and 'key' of type int
output: decrypted string 'content'
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
# precondition
assert (isinstance(key,int) and isinstance(content,str))
key = key or self.__key or 1
# make sure key can be any size
while (key > 255):
key -= 255
# This will be returned
ans = ""
for ch in content:
ans += chr(ord(ch) ^ key)
return ans
def encrypt_file(self, file, key = 0):
"""
input: filename (str) and a key (int)
output: returns true if encrypt process was
successful otherwise false
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
#precondition
assert (isinstance(file,str) and isinstance(key,int))
try:
with open(file,"r") as fin:
with open("encrypt.out","w+") as fout:
# actual encrypt-process
for line in fin:
fout.write(self.encrypt_string(line,key))
except:
return False
return True
def decrypt_file(self,file, key):
"""
input: filename (str) and a key (int)
output: returns true if decrypt process was
successful otherwise false
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
#precondition
assert (isinstance(file,str) and isinstance(key,int))
try:
with open(file,"r") as fin:
with open("decrypt.out","w+") as fout:
# actual encrypt-process
for line in fin:
fout.write(self.decrypt_string(line,key))
except:
return False
return True
# Tests
# crypt = XORCipher()
# key = 67
# # test enrcypt
# print crypt.encrypt("hallo welt",key)
# # test decrypt
# print crypt.decrypt(crypt.encrypt("hallo welt",key), key)
# # test encrypt_string
# print crypt.encrypt_string("hallo welt",key)
# # test decrypt_string
# print crypt.decrypt_string(crypt.encrypt_string("hallo welt",key),key)
# if (crypt.encrypt_file("test.txt",key)):
# print "encrypt successful"
# else:
# print "encrypt unsuccessful"
# if (crypt.decrypt_file("encrypt.out",key)):
# print "decrypt successful"
# else:
# print "decrypt unsuccessful"

View File

@ -1,3 +1,4 @@
from __future__ import print_function
import sys, random, cryptomath_module as cryptoMath
SYMBOLS = """ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"""

View File

@ -1,3 +1,4 @@
from __future__ import print_function
def decrypt(message):
"""
>>> decrypt('TMDETUX PMDVU')

View File

@ -1,9 +1,10 @@
from __future__ import print_function
# The Caesar Cipher Algorithm
def main():
message = input("Enter message: ")
key = int(input("Key [1-26]: "))
mode = input("Encrypt or Decrypt [e/d]: ")
key = int(input("Key [1-26]: "))
mode = input("Encrypt or Decrypt [e/d]: ")
if mode.lower().startswith('e'):
mode = "encrypt"
@ -11,41 +12,34 @@ def main():
mode = "decrypt"
translated = encdec(message, key, mode)
if mode == "encrypt":
print("Encryption:", translated)
if mode == "encrypt":
print(("Encryption:", translated))
elif mode == "decrypt":
print("Decryption:", translated)
print(("Decryption:", translated))
def encdec(message, key, mode):
"""
>>> encdec('Harshil Darji', 12, 'encrypt')
'TMDETUX PMDVU'
>>> encdec('TMDETUX PMDVU', 12, 'decrypt')
'HARSHIL DARJI'
"""
message = message.upper()
message = message.upper()
translated = ""
LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
for symbol in message:
if symbol in LETTERS:
num = LETTERS.find(symbol)
if mode == "encrypt":
if mode == "encrypt":
num = num + key
elif mode == "decrypt":
num = num - key
if num >= len(LETTERS):
num = num - len(LETTERS)
num -= len(LETTERS)
elif num < 0:
num = num + len(LETTERS)
num += len(LETTERS)
translated = translated + LETTERS[num]
translated += LETTERS[num]
else:
translated = translated + symbol
translated += symbol
return translated
if __name__ == '__main__':
import doctest
doctest.testmod()
main()
main()

102
ciphers/playfair_cipher.py Normal file
View File

@ -0,0 +1,102 @@
import string
import itertools
def chunker(seq, size):
it = iter(seq)
while True:
chunk = tuple(itertools.islice(it, size))
if not chunk:
return
yield chunk
def prepare_input(dirty):
"""
Prepare the plaintext by up-casing it
and separating repeated letters with X's
"""
dirty = ''.join([c.upper() for c in dirty if c in string.ascii_letters])
clean = ""
if len(dirty) < 2:
return dirty
for i in range(len(dirty)-1):
clean += dirty[i]
if dirty[i] == dirty[i+1]:
clean += 'X'
clean += dirty[-1]
if len(clean) & 1:
clean += 'X'
return clean
def generate_table(key):
# I and J are used interchangeably to allow
# us to use a 5x5 table (25 letters)
alphabet = "ABCDEFGHIKLMNOPQRSTUVWXYZ"
# we're using a list instead of a '2d' array because it makes the math
# for setting up the table and doing the actual encoding/decoding simpler
table = []
# copy key chars into the table if they are in `alphabet` ignoring duplicates
for char in key.upper():
if char not in table and char in alphabet:
table.append(char)
# fill the rest of the table in with the remaining alphabet chars
for char in alphabet:
if char not in table:
table.append(char)
return table
def encode(plaintext, key):
table = generate_table(key)
plaintext = prepare_input(plaintext)
ciphertext = ""
# https://en.wikipedia.org/wiki/Playfair_cipher#Description
for char1, char2 in chunker(plaintext, 2):
row1, col1 = divmod(table.index(char1), 5)
row2, col2 = divmod(table.index(char2), 5)
if row1 == row2:
ciphertext += table[row1*5+(col1+1)%5]
ciphertext += table[row2*5+(col2+1)%5]
elif col1 == col2:
ciphertext += table[((row1+1)%5)*5+col1]
ciphertext += table[((row2+1)%5)*5+col2]
else: # rectangle
ciphertext += table[row1*5+col2]
ciphertext += table[row2*5+col1]
return ciphertext
def decode(ciphertext, key):
table = generate_table(key)
plaintext = ""
# https://en.wikipedia.org/wiki/Playfair_cipher#Description
for char1, char2 in chunker(ciphertext, 2):
row1, col1 = divmod(table.index(char1), 5)
row2, col2 = divmod(table.index(char2), 5)
if row1 == row2:
plaintext += table[row1*5+(col1-1)%5]
plaintext += table[row2*5+(col2-1)%5]
elif col1 == col2:
plaintext += table[((row1-1)%5)*5+col1]
plaintext += table[((row2-1)%5)*5+col2]
else: # rectangle
plaintext += table[row1*5+col2]
plaintext += table[row2*5+col1]
return plaintext

View File

@ -1,3 +1,4 @@
from __future__ import print_function
# Primality Testing with the Rabin-Miller Algorithm
import random
@ -59,5 +60,5 @@ def generateLargePrime(keysize = 1024):
if __name__ == '__main__':
num = generateLargePrime()
print('Prime number:', num)
print('isPrime:', isPrime(num))
print(('Prime number:', num))
print(('isPrime:', isPrime(num)))

25
ciphers/rot13.py Normal file
View File

@ -0,0 +1,25 @@
from __future__ import print_function
def dencrypt(s, n):
out = ''
for c in s:
if c >= 'A' and c <= 'Z':
out += chr(ord('A') + (ord(c) - ord('A') + n) % 26)
elif c >= 'a' and c <= 'z':
out += chr(ord('a') + (ord(c) - ord('a') + n) % 26)
else:
out += c
return out
def main():
s0 = 'HELLO'
s1 = dencrypt(s0, 13)
print(s1) # URYYB
s2 = dencrypt(s1, 13)
print(s2) # HELLO
if __name__ == '__main__':
main()

125
ciphers/rsa_cipher.py Normal file
View File

@ -0,0 +1,125 @@
from __future__ import print_function
import sys, rsa_key_generator as rkg, os
DEFAULT_BLOCK_SIZE = 128
BYTE_SIZE = 256
def main():
filename = 'encrypted_file.txt'
response = input('Encrypte\Decrypt [e\d]: ')
if response.lower().startswith('e'):
mode = 'encrypt'
elif response.lower().startswith('d'):
mode = 'decrypt'
if mode == 'encrypt':
if not os.path.exists('rsa_pubkey.txt'):
rkg.makeKeyFiles('rsa', 1024)
message = input('\nEnter message: ')
pubKeyFilename = 'rsa_pubkey.txt'
print('Encrypting and writing to %s...' % (filename))
encryptedText = encryptAndWriteToFile(filename, pubKeyFilename, message)
print('\nEncrypted text:')
print(encryptedText)
elif mode == 'decrypt':
privKeyFilename = 'rsa_privkey.txt'
print('Reading from %s and decrypting...' % (filename))
decryptedText = readFromFileAndDecrypt(filename, privKeyFilename)
print('writing decryption to rsa_decryption.txt...')
with open('rsa_decryption.txt', 'w') as dec:
dec.write(decryptedText)
print('\nDecryption:')
print(decryptedText)
def getBlocksFromText(message, blockSize=DEFAULT_BLOCK_SIZE):
messageBytes = message.encode('ascii')
blockInts = []
for blockStart in range(0, len(messageBytes), blockSize):
blockInt = 0
for i in range(blockStart, min(blockStart + blockSize, len(messageBytes))):
blockInt += messageBytes[i] * (BYTE_SIZE ** (i % blockSize))
blockInts.append(blockInt)
return blockInts
def getTextFromBlocks(blockInts, messageLength, blockSize=DEFAULT_BLOCK_SIZE):
message = []
for blockInt in blockInts:
blockMessage = []
for i in range(blockSize - 1, -1, -1):
if len(message) + i < messageLength:
asciiNumber = blockInt // (BYTE_SIZE ** i)
blockInt = blockInt % (BYTE_SIZE ** i)
blockMessage.insert(0, chr(asciiNumber))
message.extend(blockMessage)
return ''.join(message)
def encryptMessage(message, key, blockSize=DEFAULT_BLOCK_SIZE):
encryptedBlocks = []
n, e = key
for block in getBlocksFromText(message, blockSize):
encryptedBlocks.append(pow(block, e, n))
return encryptedBlocks
def decryptMessage(encryptedBlocks, messageLength, key, blockSize=DEFAULT_BLOCK_SIZE):
decryptedBlocks = []
n, d = key
for block in encryptedBlocks:
decryptedBlocks.append(pow(block, d, n))
return getTextFromBlocks(decryptedBlocks, messageLength, blockSize)
def readKeyFile(keyFilename):
fo = open(keyFilename)
content = fo.read()
fo.close()
keySize, n, EorD = content.split(',')
return (int(keySize), int(n), int(EorD))
def encryptAndWriteToFile(messageFilename, keyFilename, message, blockSize=DEFAULT_BLOCK_SIZE):
keySize, n, e = readKeyFile(keyFilename)
if keySize < blockSize * 8:
sys.exit('ERROR: Block size is %s bits and key size is %s bits. The RSA cipher requires the block size to be equal to or greater than the key size. Either decrease the block size or use different keys.' % (blockSize * 8, keySize))
encryptedBlocks = encryptMessage(message, (n, e), blockSize)
for i in range(len(encryptedBlocks)):
encryptedBlocks[i] = str(encryptedBlocks[i])
encryptedContent = ','.join(encryptedBlocks)
encryptedContent = '%s_%s_%s' % (len(message), blockSize, encryptedContent)
fo = open(messageFilename, 'w')
fo.write(encryptedContent)
fo.close()
return encryptedContent
def readFromFileAndDecrypt(messageFilename, keyFilename):
keySize, n, d = readKeyFile(keyFilename)
fo = open(messageFilename)
content = fo.read()
messageLength, blockSize, encryptedMessage = content.split('_')
messageLength = int(messageLength)
blockSize = int(blockSize)
if keySize < blockSize * 8:
sys.exit('ERROR: Block size is %s bits and key size is %s bits. The RSA cipher requires the block size to be equal to or greater than the key size. Did you specify the correct key file and encrypted file?' % (blockSize * 8, keySize))
encryptedBlocks = []
for block in encryptedMessage.split(','):
encryptedBlocks.append(int(block))
return decryptMessage(encryptedBlocks, messageLength, (n, d), blockSize)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,46 @@
from __future__ import print_function
import random, sys, os
import rabin_miller as rabinMiller, cryptomath_module as cryptoMath
def main():
print('Making key files...')
makeKeyFiles('rsa', 1024)
print('Key files generation successful.')
def generateKey(keySize):
print('Generating prime p...')
p = rabinMiller.generateLargePrime(keySize)
print('Generating prime q...')
q = rabinMiller.generateLargePrime(keySize)
n = p * q
print('Generating e that is relatively prime to (p - 1) * (q - 1)...')
while True:
e = random.randrange(2 ** (keySize - 1), 2 ** (keySize))
if cryptoMath.gcd(e, (p - 1) * (q - 1)) == 1:
break
print('Calculating d that is mod inverse of e...')
d = cryptoMath.findModInverse(e, (p - 1) * (q - 1))
publicKey = (n, e)
privateKey = (n, d)
return (publicKey, privateKey)
def makeKeyFiles(name, keySize):
if os.path.exists('%s_pubkey.txt' % (name)) or os.path.exists('%s_privkey.txt' % (name)):
print('\nWARNING:')
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))
sys.exit()
publicKey, privateKey = generateKey(keySize)
print('\nWriting public key to file %s_pubkey.txt...' % name)
with open('%s_pubkey.txt' % name, 'w') as fo:
fo.write('%s,%s,%s' % (keySize, publicKey[0], publicKey[1]))
print('Writing private key to file %s_privkey.txt...' % name)
with open('%s_privkey.txt' % name, 'w') as fo:
fo.write('%s,%s,%s' % (keySize, privateKey[0], privateKey[1]))
if __name__ == '__main__':
main()

View File

@ -1,3 +1,4 @@
from __future__ import print_function
import sys, random
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

View File

@ -1,3 +1,4 @@
from __future__ import print_function
import math
def main():

View File

@ -1,3 +1,4 @@
from __future__ import print_function
import time, os, sys
import transposition_cipher as transCipher
@ -29,7 +30,7 @@ def main():
outputObj.close()
totalTime = round(time.time() - startTime, 2)
print('Done (', totalTime, 'seconds )')
print(('Done (', totalTime, 'seconds )'))
if __name__ == '__main__':
main()

View File

@ -1,3 +1,4 @@
from __future__ import print_function
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
def main():

181
data_structures/AVL/AVL.py Normal file
View File

@ -0,0 +1,181 @@
"""
An AVL tree
"""
from __future__ import print_function
class Node:
def __init__(self, label):
self.label = label
self._parent = None
self._left = None
self._right = None
self.height = 0
@property
def right(self):
return self._right
@right.setter
def right(self, node):
if node is not None:
node._parent = self
self._right = node
@property
def left(self):
return self._left
@left.setter
def left(self, node):
if node is not None:
node._parent = self
self._left = node
@property
def parent(self):
return self._parent
@parent.setter
def parent(self, node):
if node is not None:
self._parent = node
self.height = self.parent.height + 1
else:
self.height = 0
class AVL:
def __init__(self):
self.root = None
self.size = 0
def insert(self, value):
node = Node(value)
if self.root is None:
self.root = node
self.root.height = 0
self.size = 1
else:
# Same as Binary Tree
dad_node = None
curr_node = self.root
while True:
if curr_node is not None:
dad_node = curr_node
if node.label < curr_node.label:
curr_node = curr_node.left
else:
curr_node = curr_node.right
else:
node.height = dad_node.height
dad_node.height += 1
if node.label < dad_node.label:
dad_node.left = node
else:
dad_node.right = node
self.rebalance(node)
self.size += 1
break
def rebalance(self, node):
n = node
while n is not None:
height_right = n.height
height_left = n.height
if n.right is not None:
height_right = n.right.height
if n.left is not None:
height_left = n.left.height
if abs(height_left - height_right) > 1:
if height_left > height_right:
left_child = n.left
if left_child is not None:
h_right = (left_child.right.height
if (left_child.right is not None) else 0)
h_left = (left_child.left.height
if (left_child.left is not None) else 0)
if (h_left > h_right):
self.rotate_left(n)
break
else:
self.double_rotate_right(n)
break
else:
right_child = n.right
if right_child is not None:
h_right = (right_child.right.height
if (right_child.right is not None) else 0)
h_left = (right_child.left.height
if (right_child.left is not None) else 0)
if (h_left > h_right):
self.double_rotate_left(n)
break
else:
self.rotate_right(n)
break
n = n.parent
def rotate_left(self, node):
aux = node.parent.label
node.parent.label = node.label
node.parent.right = Node(aux)
node.parent.right.height = node.parent.height + 1
node.parent.left = node.right
def rotate_right(self, node):
aux = node.parent.label
node.parent.label = node.label
node.parent.left = Node(aux)
node.parent.left.height = node.parent.height + 1
node.parent.right = node.right
def double_rotate_left(self, node):
self.rotate_right(node.getRight().getRight())
self.rotate_left(node)
def double_rotate_right(self, node):
self.rotate_left(node.getLeft().getLeft())
self.rotate_right(node)
def empty(self):
if self.root is None:
return True
return False
def preShow(self, curr_node):
if curr_node is not None:
self.preShow(curr_node.left)
print(curr_node.label, end=" ")
self.preShow(curr_node.right)
def preorder(self, curr_node):
if curr_node is not None:
self.preShow(curr_node.left)
self.preShow(curr_node.right)
print(curr_node.label, end=" ")
def getRoot(self):
return self.root
t = AVL()
t.insert(1)
t.insert(2)
t.insert(3)
# t.preShow(t.root)
# print("\n")
# t.insert(4)
# t.insert(5)
# t.preShow(t.root)
# t.preorden(t.root)

1
data_structures/Arrays Normal file
View File

@ -0,0 +1 @@
Arrays implementation using python programming.

View File

@ -0,0 +1,29 @@
from __future__ import print_function
class FenwickTree:
def __init__(self, SIZE): # create fenwick tree with size SIZE
self.Size = SIZE
self.ft = [0 for i in range (0,SIZE)]
def update(self, i, val): # update data (adding) in index i in O(lg N)
while (i < self.Size):
self.ft[i] += val
i += i & (-i)
def query(self, i): # query cumulative data from index 0 to i in O(lg N)
ret = 0
while (i > 0):
ret += self.ft[i]
i -= i & (-i)
return ret
if __name__ == '__main__':
f = FenwickTree(100)
f.update(1,20)
f.update(4,4)
print (f.query(1))
print (f.query(3))
print (f.query(4))
f.update(2,-5)
print (f.query(1))
print (f.query(3))

View File

@ -0,0 +1,91 @@
from __future__ import print_function
import math
class SegmentTree:
def __init__(self, N):
self.N = N
self.st = [0 for i in range(0,4*N)] # approximate the overall size of segment tree with array N
self.lazy = [0 for i in range(0,4*N)] # create array to store lazy update
self.flag = [0 for i in range(0,4*N)] # flag for lazy update
def left(self, idx):
return idx*2
def right(self, idx):
return idx*2 + 1
def build(self, idx, l, r, A):
if l==r:
self.st[idx] = A[l-1]
else :
mid = (l+r)//2
self.build(self.left(idx),l,mid, A)
self.build(self.right(idx),mid+1,r, A)
self.st[idx] = max(self.st[self.left(idx)] , self.st[self.right(idx)])
# update with O(lg N) (Normal segment tree without lazy update will take O(Nlg N) for each update)
def update(self, idx, l, r, a, b, val): # update(1, 1, N, a, b, v) for update val v to [a,b]
if self.flag[idx] == True:
self.st[idx] = self.lazy[idx]
self.flag[idx] = False
if l!=r:
self.lazy[self.left(idx)] = self.lazy[idx]
self.lazy[self.right(idx)] = self.lazy[idx]
self.flag[self.left(idx)] = True
self.flag[self.right(idx)] = True
if r < a or l > b:
return True
if l >= a and r <= b :
self.st[idx] = val
if l!=r:
self.lazy[self.left(idx)] = val
self.lazy[self.right(idx)] = val
self.flag[self.left(idx)] = True
self.flag[self.right(idx)] = True
return True
mid = (l+r)//2
self.update(self.left(idx),l,mid,a,b,val)
self.update(self.right(idx),mid+1,r,a,b,val)
self.st[idx] = max(self.st[self.left(idx)] , self.st[self.right(idx)])
return True
# query with O(lg N)
def query(self, idx, l, r, a, b): #query(1, 1, N, a, b) for query max of [a,b]
if self.flag[idx] == True:
self.st[idx] = self.lazy[idx]
self.flag[idx] = False
if l != r:
self.lazy[self.left(idx)] = self.lazy[idx]
self.lazy[self.right(idx)] = self.lazy[idx]
self.flag[self.left(idx)] = True
self.flag[self.right(idx)] = True
if r < a or l > b:
return -math.inf
if l >= a and r <= b:
return self.st[idx]
mid = (l+r)//2
q1 = self.query(self.left(idx),l,mid,a,b)
q2 = self.query(self.right(idx),mid+1,r,a,b)
return max(q1,q2)
def showData(self):
showList = []
for i in range(1,N+1):
showList += [self.query(1, 1, self.N, i, i)]
print (showList)
if __name__ == '__main__':
A = [1,2,-4,7,3,-5,6,11,-20,9,14,15,5,2,-8]
N = 15
segt = SegmentTree(N)
segt.build(1,1,N,A)
print (segt.query(1,1,N,4,6))
print (segt.query(1,1,N,7,11))
print (segt.query(1,1,N,7,12))
segt.update(1,1,N,1,3,111)
print (segt.query(1,1,N,1,15))
segt.update(1,1,N,7,8,235)
segt.showData()

View File

@ -0,0 +1,65 @@
from __future__ import print_function
import math
class SegmentTree:
def __init__(self, N):
self.N = N
self.st = [0 for i in range(0,4*N)] # approximate the overall size of segment tree with array N
def left(self, idx):
return idx*2
def right(self, idx):
return idx*2 + 1
def build(self, idx, l, r, A):
if l==r:
self.st[idx] = A[l-1]
else :
mid = (l+r)//2
self.build(self.left(idx),l,mid, A)
self.build(self.right(idx),mid+1,r, A)
self.st[idx] = max(self.st[self.left(idx)] , self.st[self.right(idx)])
def update(self, idx, l, r, a, b, val): # update(1, 1, N, a, b, v) for update val v to [a,b]
if r < a or l > b:
return True
if l == r :
self.st[idx] = val
return True
mid = (l+r)//2
self.update(self.left(idx),l,mid,a,b,val)
self.update(self.right(idx),mid+1,r,a,b,val)
self.st[idx] = max(self.st[self.left(idx)] , self.st[self.right(idx)])
return True
def query(self, idx, l, r, a, b): #query(1, 1, N, a, b) for query max of [a,b]
if r < a or l > b:
return -math.inf
if l >= a and r <= b:
return self.st[idx]
mid = (l+r)//2
q1 = self.query(self.left(idx),l,mid,a,b)
q2 = self.query(self.right(idx),mid+1,r,a,b)
return max(q1,q2)
def showData(self):
showList = []
for i in range(1,N+1):
showList += [self.query(1, 1, self.N, i, i)]
print (showList)
if __name__ == '__main__':
A = [1,2,-4,7,3,-5,6,11,-20,9,14,15,5,2,-8]
N = 15
segt = SegmentTree(N)
segt.build(1,1,N,A)
print (segt.query(1,1,N,4,6))
print (segt.query(1,1,N,7,11))
print (segt.query(1,1,N,7,12))
segt.update(1,1,N,1,3,111)
print (segt.query(1,1,N,1,15))
segt.update(1,1,N,7,8,235)
segt.showData()

View File

@ -0,0 +1,258 @@
'''
A binary search Tree
'''
from __future__ import print_function
class Node:
def __init__(self, label, parent):
self.label = label
self.left = None
self.right = None
#Added in order to delete a node easier
self.parent = parent
def getLabel(self):
return self.label
def setLabel(self, label):
self.label = label
def getLeft(self):
return self.left
def setLeft(self, left):
self.left = left
def getRight(self):
return self.right
def setRight(self, right):
self.right = right
def getParent(self):
return self.parent
def setParent(self, parent):
self.parent = parent
class BinarySearchTree:
def __init__(self):
self.root = None
def insert(self, label):
# Create a new Node
new_node = Node(label, None)
# If Tree is empty
if self.empty():
self.root = new_node
else:
#If Tree is not empty
curr_node = self.root
#While we don't get to a leaf
while curr_node is not None:
#We keep reference of the parent node
parent_node = curr_node
#If node label is less than current node
if new_node.getLabel() < curr_node.getLabel():
#We go left
curr_node = curr_node.getLeft()
else:
#Else we go right
curr_node = curr_node.getRight()
#We insert the new node in a leaf
if new_node.getLabel() < parent_node.getLabel():
parent_node.setLeft(new_node)
else:
parent_node.setRight(new_node)
#Set parent to the new node
new_node.setParent(parent_node)
def delete(self, label):
if (not self.empty()):
#Look for the node with that label
node = self.getNode(label)
#If the node exists
if(node is not None):
#If it has no children
if(node.getLeft() is None and node.getRight() is None):
self.__reassignNodes(node, None)
node = None
#Has only right children
elif(node.getLeft() is None and node.getRight() is not None):
self.__reassignNodes(node, node.getRight())
#Has only left children
elif(node.getLeft() is not None and node.getRight() is None):
self.__reassignNodes(node, node.getLeft())
#Has two children
else:
#Gets the max value of the left branch
tmpNode = self.getMax(node.getLeft())
#Deletes the tmpNode
self.delete(tmpNode.getLabel())
#Assigns the value to the node to delete and keesp tree structure
node.setLabel(tmpNode.getLabel())
def getNode(self, label):
curr_node = None
#If the tree is not empty
if(not self.empty()):
#Get tree root
curr_node = self.getRoot()
#While we don't find the node we look for
#I am using lazy evaluation here to avoid NoneType Attribute error
while curr_node is not None and curr_node.getLabel() is not label:
#If node label is less than current node
if label < curr_node.getLabel():
#We go left
curr_node = curr_node.getLeft()
else:
#Else we go right
curr_node = curr_node.getRight()
return curr_node
def getMax(self, root = None):
if(root is not None):
curr_node = root
else:
#We go deep on the right branch
curr_node = self.getRoot()
if(not self.empty()):
while(curr_node.getRight() is not None):
curr_node = curr_node.getRight()
return curr_node
def getMin(self, root = None):
if(root is not None):
curr_node = root
else:
#We go deep on the left branch
curr_node = self.getRoot()
if(not self.empty()):
curr_node = self.getRoot()
while(curr_node.getLeft() is not None):
curr_node = curr_node.getLeft()
return curr_node
def empty(self):
if self.root is None:
return True
return False
def __InOrderTraversal(self, curr_node):
nodeList = []
if curr_node is not None:
nodeList.insert(0, curr_node)
nodeList = nodeList + self.__InOrderTraversal(curr_node.getLeft())
nodeList = nodeList + self.__InOrderTraversal(curr_node.getRight())
return nodeList
def getRoot(self):
return self.root
def __isRightChildren(self, node):
if(node == node.getParent().getRight()):
return True
return False
def __reassignNodes(self, node, newChildren):
if(newChildren is not None):
newChildren.setParent(node.getParent())
if(node.getParent() is not None):
#If it is the Right Children
if(self.__isRightChildren(node)):
node.getParent().setRight(newChildren)
else:
#Else it is the left children
node.getParent().setLeft(newChildren)
#This function traversal the tree. By default it returns an
#In order traversal list. You can pass a function to traversal
#The tree as needed by client code
def traversalTree(self, traversalFunction = None, root = None):
if(traversalFunction is None):
#Returns a list of nodes in preOrder by default
return self.__InOrderTraversal(self.root)
else:
#Returns a list of nodes in the order that the users wants to
return traversalFunction(self.root)
#Returns an string of all the nodes labels in the list
#In Order Traversal
def __str__(self):
list = self.__InOrderTraversal(self.root)
str = ""
for x in list:
str = str + " " + x.getLabel().__str__()
return str
def InPreOrder(curr_node):
nodeList = []
if curr_node is not None:
nodeList = nodeList + InPreOrder(curr_node.getLeft())
nodeList.insert(0, curr_node.getLabel())
nodeList = nodeList + InPreOrder(curr_node.getRight())
return nodeList
def testBinarySearchTree():
'''
Example
8
/ \
3 10
/ \ \
1 6 14
/ \ /
4 7 13
'''
'''
Example After Deletion
7
/ \
1 4
'''
t = BinarySearchTree()
t.insert(8)
t.insert(3)
t.insert(6)
t.insert(1)
t.insert(10)
t.insert(14)
t.insert(13)
t.insert(4)
t.insert(7)
#Prints all the elements of the list in order traversal
print(t.__str__())
if(t.getNode(6) is not None):
print("The label 6 exists")
else:
print("The label 6 doesn't exist")
if(t.getNode(-1) is not None):
print("The label -1 exists")
else:
print("The label -1 doesn't exist")
if(not t.empty()):
print(("Max Value: ", t.getMax().getLabel()))
print(("Min Value: ", t.getMin().getLabel()))
t.delete(13)
t.delete(10)
t.delete(8)
t.delete(3)
t.delete(6)
t.delete(14)
#Gets all the elements of the tree In pre order
#And it prints them
list = t.traversalTree(InPreOrder, t.root)
for x in list:
print(x)
if __name__ == "__main__":
testBinarySearchTree()

View File

@ -0,0 +1,54 @@
from __future__ import print_function
def printDist(dist, V):
print("\nVertex Distance")
for i in range(V):
if dist[i] != float('inf') :
print(i,"\t",int(dist[i]),end = "\t")
else:
print(i,"\t","INF",end="\t")
print()
def BellmanFord(graph, V, E, src):
mdist=[float('inf') for i in range(V)]
mdist[src] = 0.0
for i in range(V-1):
for j in range(V):
u = graph[j]["src"]
v = graph[j]["dst"]
w = graph[j]["weight"]
if mdist[u] != float('inf') and mdist[u] + w < mdist[v]:
mdist[v] = mdist[u] + w
for j in range(V):
u = graph[j]["src"]
v = graph[j]["dst"]
w = graph[j]["weight"]
if mdist[u] != float('inf') and mdist[u] + w < mdist[v]:
print("Negative cycle found. Solution not possible.")
return
printDist(mdist, V)
#MAIN
V = int(input("Enter number of vertices: "))
E = int(input("Enter number of edges: "))
graph = [dict() for j in range(E)]
for i in range(V):
graph[i][i] = 0.0
for i in range(E):
print("\nEdge ",i+1)
src = int(input("Enter source:"))
dst = int(input("Enter destination:"))
weight = float(input("Enter weight:"))
graph[i] = {"src": src,"dst": dst, "weight": weight}
gsrc = int(input("\nEnter shortest path source:"))
BellmanFord(graph, V, E, gsrc)

View File

@ -0,0 +1,63 @@
# Author: OMKAR PATHAK
from __future__ import print_function
class Graph():
def __init__(self):
self.vertex = {}
# for printing the Graph vertexes
def printGraph(self):
for i in self.vertex.keys():
print(i,' -> ', ' -> '.join([str(j) for j in self.vertex[i]]))
# for adding the edge beween two vertexes
def addEdge(self, fromVertex, toVertex):
# check if vertex is already present,
if fromVertex in self.vertex.keys():
self.vertex[fromVertex].append(toVertex)
else:
# else make a new vertex
self.vertex[fromVertex] = [toVertex]
def BFS(self, startVertex):
# Take a list for stoting already visited vertexes
visited = [False] * len(self.vertex)
# create a list to store all the vertexes for BFS
queue = []
# mark the source node as visited and enqueue it
visited[startVertex] = True
queue.append(startVertex)
while queue:
startVertex = queue.pop(0)
print(startVertex, end = ' ')
# mark all adjacent nodes as visited and print them
for i in self.vertex[startVertex]:
if visited[i] == False:
queue.append(i)
visited[i] = True
if __name__ == '__main__':
g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)
g.printGraph()
print('BFS:')
g.BFS(2)
# OUTPUT:
# 0  ->  1 -> 2
# 1  ->  2
# 2  ->  0 -> 3
# 3  ->  3
# BFS:
# 2 0 3 1

View File

@ -0,0 +1,63 @@
# Author: OMKAR PATHAK
from __future__ import print_function
class Graph():
def __init__(self):
self.vertex = {}
# for printing the Graph vertexes
def printGraph(self):
print(self.vertex)
for i in self.vertex.keys():
print(i,' -> ', ' -> '.join([str(j) for j in self.vertex[i]]))
# for adding the edge beween two vertexes
def addEdge(self, fromVertex, toVertex):
# check if vertex is already present,
if fromVertex in self.vertex.keys():
self.vertex[fromVertex].append(toVertex)
else:
# else make a new vertex
self.vertex[fromVertex] = [toVertex]
def DFS(self):
# visited array for storing already visited nodes
visited = [False] * len(self.vertex)
# call the recursive helper function
for i in range(len(self.vertex)):
if visited[i] == False:
self.DFSRec(i, visited)
def DFSRec(self, startVertex, visited):
# mark start vertex as visited
visited[startVertex] = True
print(startVertex, end = ' ')
# Recur for all the vertexes that are adjacent to this node
for i in self.vertex.keys():
if visited[i] == False:
self.DFSRec(i, visited)
if __name__ == '__main__':
g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)
g.printGraph()
print('DFS:')
g.DFS()
# OUTPUT:
# 0  ->  1 -> 2
# 1  ->  2
# 2  ->  0 -> 3
# 3  ->  3
# DFS:
# 0 1 2 3

View File

@ -0,0 +1,57 @@
from __future__ import print_function
def printDist(dist, V):
print("\nVertex Distance")
for i in range(V):
if dist[i] != float('inf') :
print(i,"\t",int(dist[i]),end = "\t")
else:
print(i,"\t","INF",end="\t")
print()
def minDist(mdist, vset, V):
minVal = float('inf')
minInd = -1
for i in range(V):
if (not vset[i]) and mdist[i] < minVal :
minInd = i
minVal = mdist[i]
return minInd
def Dijkstra(graph, V, src):
mdist=[float('inf') for i in range(V)]
vset = [False for i in range(V)]
mdist[src] = 0.0;
for i in range(V-1):
u = minDist(mdist, vset, V)
vset[u] = True
for v in range(V):
if (not vset[v]) and graph[u][v]!=float('inf') and mdist[u] + graph[u][v] < mdist[v]:
mdist[v] = mdist[u] + graph[u][v]
printDist(mdist, V)
#MAIN
V = int(input("Enter number of vertices: "))
E = int(input("Enter number of edges: "))
graph = [[float('inf') for i in range(V)] for j in range(V)]
for i in range(V):
graph[i][i] = 0.0
for i in range(E):
print("\nEdge ",i+1)
src = int(input("Enter source:"))
dst = int(input("Enter destination:"))
weight = float(input("Enter weight:"))
graph[src][dst] = weight
gsrc = int(input("\nEnter shortest path source:"))
Dijkstra(graph, V, gsrc)

View File

@ -0,0 +1,48 @@
from __future__ import print_function
def printDist(dist, V):
print("\nThe shortest path matrix using Floyd Warshall algorithm\n")
for i in range(V):
for j in range(V):
if dist[i][j] != float('inf') :
print(int(dist[i][j]),end = "\t")
else:
print("INF",end="\t")
print()
def FloydWarshall(graph, V):
dist=[[float('inf') for i in range(V)] for j in range(V)]
for i in range(V):
for j in range(V):
dist[i][j] = graph[i][j]
for k in range(V):
for i in range(V):
for j in range(V):
if dist[i][k]!=float('inf') and dist[k][j]!=float('inf') and dist[i][k]+dist[k][j] < dist[i][j]:
dist[i][j] = dist[i][k] + dist[k][j]
printDist(dist, V)
#MAIN
V = int(input("Enter number of vertices: "))
E = int(input("Enter number of edges: "))
graph = [[float('inf') for i in range(V)] for j in range(V)]
for i in range(V):
graph[i][i] = 0.0
for i in range(E):
print("\nEdge ",i+1)
src = int(input("Enter source:"))
dst = int(input("Enter destination:"))
weight = float(input("Enter weight:"))
graph[src][dst] = weight
FloydWarshall(graph, V)

View File

@ -0,0 +1,41 @@
from __future__ import print_function
# Author: OMKAR PATHAK
# We can use Python's dictionary for constructing the graph
class AdjacencyList(object):
def __init__(self):
self.List = {}
def addEdge(self, fromVertex, toVertex):
# check if vertex is already present
if fromVertex in self.List.keys():
self.List[fromVertex].append(toVertex)
else:
self.List[fromVertex] = [toVertex]
def printList(self):
for i in self.List:
print((i,'->',' -> '.join([str(j) for j in self.List[i]])))
if __name__ == '__main__':
al = AdjacencyList()
al.addEdge(0, 1)
al.addEdge(0, 4)
al.addEdge(4, 1)
al.addEdge(4, 3)
al.addEdge(1, 0)
al.addEdge(1, 4)
al.addEdge(1, 3)
al.addEdge(1, 2)
al.addEdge(2, 3)
al.addEdge(3, 4)
al.printList()
# OUTPUT:
# 0 -> 1 -> 4
# 1 -> 0 -> 4 -> 3 -> 2
# 2 -> 3
# 3 -> 4
# 4 -> 1 -> 3

View File

@ -0,0 +1,31 @@
from __future__ import print_function
class Graph:
def __init__(self, vertex):
self.vertex = vertex
self.graph = [[0] for i in range(vertex)]
def add_edge(self, u, v):
self.graph[u - 1].append(v - 1)
def show(self):
for i in range(self.vertex):
print('%d: '% (i + 1), end=' ')
for j in self.graph[i]:
print('%d-> '% (j + 1), end=' ')
print(' ')
g = Graph(100)
g.add_edge(1,3)
g.add_edge(2,3)
g.add_edge(3,4)
g.add_edge(3,5)
g.add_edge(4,5)
g.show()

View File

@ -0,0 +1,32 @@
from __future__ import print_function
class Graph:
def __init__(self, vertex):
self.vertex = vertex
self.graph = [[0] * vertex for i in range(vertex) ]
def add_edge(self, u, v):
self.graph[u - 1][v - 1] = 1
self.graph[v - 1][u - 1] = 1
def show(self):
for i in self.graph:
for j in i:
print(j, end=' ')
print(' ')
g = Graph(100)
g.add_edge(1,4)
g.add_edge(4,2)
g.add_edge(4,5)
g.add_edge(2,5)
g.add_edge(5,3)
g.show()

View File

@ -0,0 +1,212 @@
# Title: Dijkstra's Algorithm for finding single source shortest path from scratch
# Author: Shubham Malik
# References: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
from __future__ import print_function
import math
import sys
# For storing the vertex set to retreive node with the lowest distance
class PriorityQueue:
# Based on Min Heap
def __init__(self):
self.cur_size = 0
self.array = []
self.pos = {} # To store the pos of node in array
def isEmpty(self):
return self.cur_size == 0
def min_heapify(self, idx):
lc = self.left(idx)
rc = self.right(idx)
if lc < self.cur_size and self.array(lc)[0] < self.array(idx)[0]:
smallest = lc
else:
smallest = idx
if rc < self.cur_size and self.array(rc)[0] < self.array(smallest)[0]:
smallest = rc
if smallest != idx:
self.swap(idx, smallest)
self.min_heapify(smallest)
def insert(self, tup):
# Inserts a node into the Priority Queue
self.pos[tup[1]] = self.cur_size
self.cur_size += 1
self.array.append((sys.maxsize, tup[1]))
self.decrease_key((sys.maxsize, tup[1]), tup[0])
def extract_min(self):
# Removes and returns the min element at top of priority queue
min_node = self.array[0][1]
self.array[0] = self.array[self.cur_size - 1]
self.cur_size -= 1
self.min_heapify(1)
del self.pos[min_node]
return min_node
def left(self, i):
# returns the index of left child
return 2 * i + 1
def right(self, i):
# returns the index of right child
return 2 * i + 2
def par(self, i):
# returns the index of parent
return math.floor(i / 2)
def swap(self, i, j):
# swaps array elements at indices i and j
# update the pos{}
self.pos[self.array[i][1]] = j
self.pos[self.array[j][1]] = i
temp = self.array[i]
self.array[i] = self.array[j]
self.array[j] = temp
def decrease_key(self, tup, new_d):
idx = self.pos[tup[1]]
# assuming the new_d is atmost old_d
self.array[idx] = (new_d, tup[1])
while idx > 0 and self.array[self.par(idx)][0] > self.array[idx][0]:
self.swap(idx, self.par(idx))
idx = self.par(idx)
class Graph:
def __init__(self, num):
self.adjList = {} # To store graph: u -> (v,w)
self.num_nodes = num # Number of nodes in graph
# To store the distance from source vertex
self.dist = [0] * self.num_nodes
self.par = [-1] * self.num_nodes # To store the path
def add_edge(self, u, v, w):
# Edge going from node u to v and v to u with weight w
# u (w)-> v, v (w) -> u
# Check if u already in graph
if u in self.adjList.keys():
self.adjList[u].append((v, w))
else:
self.adjList[u] = [(v, w)]
# Assuming undirected graph
if v in self.adjList.keys():
self.adjList[v].append((u, w))
else:
self.adjList[v] = [(u, w)]
def show_graph(self):
# u -> v(w)
for u in self.adjList:
print(u, '->', ' -> '.join(str("{}({})".format(v, w))
for v, w in self.adjList[u]))
def dijkstra(self, src):
# Flush old junk values in par[]
self.par = [-1] * self.num_nodes
# src is the source node
self.dist[src] = 0
Q = PriorityQueue()
Q.insert((0, src)) # (dist from src, node)
for u in self.adjList.keys():
if u != src:
self.dist[u] = sys.maxsize # Infinity
self.par[u] = -1
while not Q.isEmpty():
u = Q.extract_min() # Returns node with the min dist from source
# Update the distance of all the neighbours of u and
# if their prev dist was INFINITY then push them in Q
for v, w in self.adjList[u]:
new_dist = self.dist[u] + w
if self.dist[v] > new_dist:
if self.dist[v] == sys.maxsize:
Q.insert((new_dist, v))
else:
Q.decrease_key((self.dist[v], v), new_dist)
self.dist[v] = new_dist
self.par[v] = u
# Show the shortest distances from src
self.show_distances(src)
def show_distances(self, src):
print("Distance from node: {}".format(src))
for u in range(self.num_nodes):
print('Node {} has distance: {}'.format(u, self.dist[u]))
def show_path(self, src, dest):
# To show the shortest path from src to dest
# WARNING: Use it *after* calling dijkstra
path = []
cost = 0
temp = dest
# Backtracking from dest to src
while self.par[temp] != -1:
path.append(temp)
if temp != src:
for v, w in self.adjList[temp]:
if v == self.par[temp]:
cost += w
break
temp = self.par[temp]
path.append(src)
path.reverse()
print('----Path to reach {} from {}----'.format(dest, src))
for u in path:
print('{}'.format(u), end=' ')
if u != dest:
print('-> ', end='')
print('\nTotal cost of path: ', cost)
if __name__ == '__main__':
graph = Graph(9)
graph.add_edge(0, 1, 4)
graph.add_edge(0, 7, 8)
graph.add_edge(1, 2, 8)
graph.add_edge(1, 7, 11)
graph.add_edge(2, 3, 7)
graph.add_edge(2, 8, 2)
graph.add_edge(2, 5, 4)
graph.add_edge(3, 4, 9)
graph.add_edge(3, 5, 14)
graph.add_edge(4, 5, 10)
graph.add_edge(5, 6, 2)
graph.add_edge(6, 7, 1)
graph.add_edge(6, 8, 6)
graph.add_edge(7, 8, 7)
graph.show_graph()
graph.dijkstra(0)
graph.show_path(0, 4)
# OUTPUT
# 0 -> 1(4) -> 7(8)
# 1 -> 0(4) -> 2(8) -> 7(11)
# 7 -> 0(8) -> 1(11) -> 6(1) -> 8(7)
# 2 -> 1(8) -> 3(7) -> 8(2) -> 5(4)
# 3 -> 2(7) -> 4(9) -> 5(14)
# 8 -> 2(2) -> 6(6) -> 7(7)
# 5 -> 2(4) -> 3(14) -> 4(10) -> 6(2)
# 4 -> 3(9) -> 5(10)
# 6 -> 5(2) -> 7(1) -> 8(6)
# Distance from node: 0
# Node 0 has distance: 0
# Node 1 has distance: 4
# Node 2 has distance: 12
# Node 3 has distance: 19
# Node 4 has distance: 21
# Node 5 has distance: 11
# Node 6 has distance: 9
# Node 7 has distance: 8
# Node 8 has distance: 14
# ----Path to reach 4 from 0----
# 0 -> 7 -> 6 -> 5 -> 4
# Total cost of path: 21

View File

@ -0,0 +1,70 @@
"""
You are given a tree(a simple connected graph with no cycles). The tree has N
nodes numbered from 1 to N and is rooted at node 1.
Find the maximum number of edges you can remove from the tree to get a forest
such that each connected component of the forest contains an even number of
nodes.
Constraints
2 <= 2 <= 100
Note: The tree input will be such that it can always be decomposed into
components containing an even number of nodes.
"""
from __future__ import print_function
# pylint: disable=invalid-name
from collections import defaultdict
def dfs(start):
"""DFS traversal"""
# pylint: disable=redefined-outer-name
ret = 1
visited[start] = True
for v in tree.get(start):
if v not in visited:
ret += dfs(v)
if ret % 2 == 0:
cuts.append(start)
return ret
def even_tree():
"""
2 1
3 1
4 3
5 2
6 1
7 2
8 6
9 8
10 8
On removing edges (1,3) and (1,6), we can get the desired result 2.
"""
dfs(1)
if __name__ == '__main__':
n, m = 10, 9
tree = defaultdict(list)
visited = {}
cuts = []
count = 0
edges = [
(2, 1),
(3, 1),
(4, 3),
(5, 2),
(6, 1),
(7, 2),
(8, 6),
(9, 8),
(10, 8),
]
for u, v in edges:
tree[u].append(v)
tree[v].append(u)
even_tree()
print(len(cuts) - 1)

View File

@ -0,0 +1,90 @@
#!/usr/bin/python
from __future__ import print_function
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
class Heap:
def __init__(self):
self.h = []
self.currsize = 0
def leftChild(self,i):
if 2*i+1 < self.currsize:
return 2*i+1
return None
def rightChild(self,i):
if 2*i+2 < self.currsize:
return 2*i+2
return None
def maxHeapify(self,node):
if node < self.currsize:
m = node
lc = self.leftChild(node)
rc = self.rightChild(node)
if lc is not None and self.h[lc] > self.h[m]:
m = lc
if rc is not None and self.h[rc] > self.h[m]:
m = rc
if m!=node:
temp = self.h[node]
self.h[node] = self.h[m]
self.h[m] = temp
self.maxHeapify(m)
def buildHeap(self,a):
self.currsize = len(a)
self.h = list(a)
for i in range(self.currsize/2,-1,-1):
self.maxHeapify(i)
def getMax(self):
if self.currsize >= 1:
me = self.h[0]
temp = self.h[0]
self.h[0] = self.h[self.currsize-1]
self.h[self.currsize-1] = temp
self.currsize -= 1
self.maxHeapify(0)
return me
return None
def heapSort(self):
size = self.currsize
while self.currsize-1 >= 0:
temp = self.h[0]
self.h[0] = self.h[self.currsize-1]
self.h[self.currsize-1] = temp
self.currsize -= 1
self.maxHeapify(0)
self.currsize = size
def insert(self,data):
self.h.append(data)
curr = self.currsize
self.currsize+=1
while self.h[curr] > self.h[curr/2]:
temp = self.h[curr/2]
self.h[curr/2] = self.h[curr]
self.h[curr] = temp
curr = curr/2
def display(self):
print(self.h)
def main():
l = list(map(int, raw_input().split()))
h = Heap()
h.buildHeap(l)
h.heapSort()
h.display()
if __name__=='__main__':
main()

View File

@ -0,0 +1,76 @@
'''
- A linked list is similar to an array, it holds values. However, links in a linked list do not have indexes.
- This is an example of a double ended, doubly linked list.
- Each link references the next link and the previous one.
'''
from __future__ import print_function
class LinkedList:
def __init__(self):
self.head = None
self.tail = None
def insertHead(self, x):
newLink = Link(x) #Create a new link with a value attached to it
if(self.isEmpty() == True): #Set the first element added to be the tail
self.tail = newLink
else:
self.head.previous = newLink # newLink <-- currenthead(head)
newLink.next = self.head # newLink <--> currenthead(head)
self.head = newLink # newLink(head) <--> oldhead
def deleteHead(self):
temp = self.head
self.head = self.head.next # oldHead <--> 2ndElement(head)
self.head.previous = None # oldHead --> 2ndElement(head) nothing pointing at it so the old head will be removed
if(self.head == None):
self.tail = None
return temp
def insertTail(self, x):
newLink = Link(x)
newLink.next = None # currentTail(tail) newLink -->
self.tail.next = newLink # currentTail(tail) --> newLink -->
newLink.previous = self.tail #currentTail(tail) <--> newLink -->
self.tail = newLink # oldTail <--> newLink(tail) -->
def deleteTail(self):
temp = self.tail
self.tail = self.tail.previous # 2ndLast(tail) <--> oldTail --> None
self.tail.next = None # 2ndlast(tail) --> None
return temp
def delete(self, x):
current = self.head
while(current.value != x): # Find the position to delete
current = current.next
if(current == self.head):
self.deleteHead()
elif(current == self.tail):
self.deleteTail()
else: #Before: 1 <--> 2(current) <--> 3
current.previous.next = current.next # 1 --> 3
current.next.previous = current.previous # 1 <--> 3
def isEmpty(self): #Will return True if the list is empty
return(self.head == None)
def display(self): #Prints contents of the list
current = self.head
while(current != None):
current.displayLink()
current = current.next
print()
class Link:
next = None #This points to the link in front of the new link
previous = None #This points to the link behind the new link
def __init__(self, x):
self.value = x
def displayLink(self):
print("{}".format(self.value), end=" ")

View File

@ -0,0 +1,22 @@
class Node:
def __init__(self, item, next):
self.item = item
self.next = next
class LinkedList:
def __init__(self):
self.head = None
def add(self, item):
self.head = Node(item, self.head)
def remove(self):
if self.is_empty():
return None
else:
item = self.head.item
self.head = self.head.next
return item
def is_empty(self):
return self.head == None

View File

@ -0,0 +1,67 @@
from __future__ import print_function
class Node:#create a Node
def __int__(self,data):
self.data=data#given data
self.next=None#given next to None
class Linked_List:
pass
def insert_tail(Head,data):
if(Head.next is None):
Head.next = Node(data)
else:
insert_tail(Head.next, data)
def insert_head(Head,data):
tamp = Head
if (tamp == None):
newNod = Node()#create a new Node
newNod.data = data
newNod.next = None
Head = newNod#make new node to Head
else:
newNod = Node()
newNod.data = data
newNod.next = Head#put the Head at NewNode Next
Head=newNod#make a NewNode to Head
return Head
def printList(Head):#print every node data
tamp=Head
while tamp!=None:
print(tamp.data)
tamp=tamp.next
def delete_head(Head):#delete from head
if Head!=None:
Head=Head.next
return Head#return new Head
def delete_tail(Head):#delete from tail
if Head!=None:
tamp = Node()
tamp = Head
while (tamp.next).next!= None:#find the 2nd last element
tamp = tamp.next
tamp.next=None#delete the last element by give next None to 2nd last Element
return Head
def isEmpty(Head):
return Head is None #Return if Head is none
def reverse(Head):
prev = None
current = Head
while(current):
# Store the current node's next node.
next_node = current.next
# Make the current node's next point backwards
current.next = prev
# Make the previous node be the current node
prev = current
# Make the current node the next node (to progress iteration)
current = next_node
# Return prev in order to put the head at the end
Head = prev

View File

@ -0,0 +1,40 @@
from __future__ import print_function
# Python code to demonstrate working of
# extend(), extendleft(), rotate(), reverse()
# importing "collections" for deque operations
import collections
# initializing deque
de = collections.deque([1, 2, 3,])
# using extend() to add numbers to right end
# adds 4,5,6 to right end
de.extend([4,5,6])
# printing modified deque
print ("The deque after extending deque at end is : ")
print (de)
# using extendleft() to add numbers to left end
# adds 7,8,9 to right end
de.extendleft([7,8,9])
# printing modified deque
print ("The deque after extending deque at beginning is : ")
print (de)
# using rotate() to rotate the deque
# rotates by 3 to left
de.rotate(-3)
# printing modified deque
print ("The deque after rotating deque is : ")
print (de)
# using reverse() to reverse the deque
de.reverse()
# printing modified deque
print ("The deque after reversing deque is : ")
print (de)

View File

@ -0,0 +1,45 @@
"""Queue represented by a python list"""
class Queue():
def __init__(self):
self.entries = []
self.length = 0
self.front=0
def __str__(self):
printed = '<' + str(self.entries)[1:-1] + '>'
return printed
"""Enqueues {@code item}
@param item
item to enqueue"""
def put(self, item):
self.entries.append(item)
self.length = self.length + 1
"""Dequeues {@code item}
@requirement: |self.length| > 0
@return dequeued
item that was dequeued"""
def get(self):
self.length = self.length - 1
dequeued = self.entries[self.front]
self.front-=1
self.entries = self.entries[self.front:]
return dequeued
"""Rotates the queue {@code rotation} times
@param rotation
number of times to rotate queue"""
def rotate(self, rotation):
for i in range(rotation):
self.put(self.get())
"""Enqueues {@code item}
@return item at front of self.entries"""
def front(self):
return self.entries[0]
"""Returns the length of this.entries"""
def size(self):
return self.length

View File

@ -0,0 +1,50 @@
"""Queue represented by a pseudo stack (represented by a list with pop and append)"""
class Queue():
def __init__(self):
self.stack = []
self.length = 0
def __str__(self):
printed = '<' + str(self.stack)[1:-1] + '>'
return printed
"""Enqueues {@code item}
@param item
item to enqueue"""
def put(self, item):
self.stack.append(item)
self.length = self.length + 1
"""Dequeues {@code item}
@requirement: |self.length| > 0
@return dequeued
item that was dequeued"""
def get(self):
self.rotate(1)
dequeued = self.stack[self.length-1]
self.stack = self.stack[:-1]
self.rotate(self.length-1)
self.length = self.length -1
return dequeued
"""Rotates the queue {@code rotation} times
@param rotation
number of times to rotate queue"""
def rotate(self, rotation):
for i in range(rotation):
temp = self.stack[0]
self.stack = self.stack[1:]
self.put(temp)
self.length = self.length - 1
"""Reports item at the front of self
@return item at front of self.stack"""
def front(self):
front = self.get()
self.put(front)
self.rotate(self.length-1)
return front
"""Returns the length of this.stack"""
def size(self):
return self.length

View File

View File

@ -0,0 +1,23 @@
class Stack:
def __init__(self):
self.stack = []
self.top = 0
def is_empty(self):
return (self.top == 0)
def push(self, item):
if self.top < len(self.stack):
self.stack[self.top] = item
else:
self.stack.append(item)
self.top += 1
def pop(self):
if self.is_empty():
return None
else:
self.top -= 1
return self.stack[self.top]

View File

@ -0,0 +1,23 @@
from __future__ import print_function
from __future__ import absolute_import
from .Stack import Stack
__author__ = 'Omkar Pathak'
def balanced_parentheses(parentheses):
""" Use a stack to check if a string of parentheses are balanced."""
stack = Stack(len(parentheses))
for parenthesis in parentheses:
if parenthesis == '(':
stack.push(parenthesis)
elif parenthesis == ')':
stack.pop()
return not stack.is_empty()
if __name__ == '__main__':
examples = ['((()))', '((())']
print('Balanced parentheses demonstration:\n')
for example in examples:
print(example + ': ' + str(balanced_parentheses(example)))

View File

@ -0,0 +1,64 @@
from __future__ import print_function
from __future__ import absolute_import
import string
from .Stack import Stack
__author__ = 'Omkar Pathak'
def is_operand(char):
return char in string.ascii_letters or char in string.digits
def precedence(char):
""" Return integer value representing an operator's precedence, or
order of operation.
https://en.wikipedia.org/wiki/Order_of_operations
"""
dictionary = {'+': 1, '-': 1,
'*': 2, '/': 2,
'^': 3}
return dictionary.get(char, -1)
def infix_to_postfix(expression):
""" Convert infix notation to postfix notation using the Shunting-yard
algorithm.
https://en.wikipedia.org/wiki/Shunting-yard_algorithm
https://en.wikipedia.org/wiki/Infix_notation
https://en.wikipedia.org/wiki/Reverse_Polish_notation
"""
stack = Stack(len(expression))
postfix = []
for char in expression:
if is_operand(char):
postfix.append(char)
elif char not in {'(', ')'}:
while (not stack.is_empty()
and precedence(char) <= precedence(stack.peek())):
postfix.append(stack.pop())
stack.push(char)
elif char == '(':
stack.push(char)
elif char == ')':
while not stack.is_empty() and stack.peek() != '(':
postfix.append(stack.pop())
# Pop '(' from stack. If there is no '(', there is a mismatched
# parentheses.
if stack.peek() != '(':
raise ValueError('Mismatched parentheses')
stack.pop()
while not stack.is_empty():
postfix.append(stack.pop())
return ' '.join(postfix)
if __name__ == '__main__':
expression = 'a+b*(c^d-e)^(f+g*h)-i'
print('Infix to Postfix Notation demonstration:\n')
print('Infix notation: ' + expression)
print('Postfix notation: ' + infix_to_postfix(expression))

View File

@ -0,0 +1,17 @@
from __future__ import print_function
# Function to print element and NGE pair for all elements of list
def printNGE(arr):
for i in range(0, len(arr), 1):
next = -1
for j in range(i+1, len(arr), 1):
if arr[i] < arr[j]:
next = arr[j]
break
print(str(arr[i]) + " -- " + str(next))
# Driver program to test above function
arr = [11,13,21,3]
printNGE(arr)

View File

@ -0,0 +1,69 @@
from __future__ import print_function
__author__ = 'Omkar Pathak'
class Stack(object):
""" A stack is an abstract data type that serves as a collection of
elements with two principal operations: push() and pop(). push() adds an
element to the top of the stack, and pop() removes an element from the top
of a stack. The order in which elements come off of a stack are
Last In, First Out (LIFO).
https://en.wikipedia.org/wiki/Stack_(abstract_data_type)
"""
def __init__(self, limit=10):
self.stack = []
self.limit = limit
def __bool__(self):
return not bool(self.stack)
def __str__(self):
return str(self.stack)
def push(self, data):
""" Push an element to the top of the stack."""
if len(self.stack) >= self.limit:
raise StackOverflowError
self.stack.append(data)
def pop(self):
""" Pop an element off of the top of the stack."""
if self.stack:
return self.stack.pop()
else:
raise IndexError('pop from an empty stack')
def peek(self):
""" Peek at the top-most element of the stack."""
if self.stack:
return self.stack[-1]
def is_empty(self):
""" Check if a stack is empty."""
return not bool(self.stack)
def size(self):
""" Return the size of the stack."""
return len(self.stack)
class StackOverflowError(BaseException):
pass
if __name__ == '__main__':
stack = Stack()
for i in range(10):
stack.push(i)
print('Stack demonstration:\n')
print('Initial stack: ' + str(stack))
print('pop(): ' + str(stack.pop()))
print('After pop(), the stack is now: ' + str(stack))
print('peek(): ' + str(stack.peek()))
stack.push(100)
print('After push(100), the stack is now: ' + str(stack))
print('is_empty(): ' + str(stack.is_empty()))
print('size(): ' + str(stack.size()))

View File

@ -0,0 +1,75 @@
"""
A Trie/Prefix Tree is a kind of search tree used to provide quick lookup
of words/patterns in a set of words. A basic Trie however has O(n^2) space complexity
making it impractical in practice. It however provides O(max(search_string, length of longest word)) lookup
time making it an optimal approach when space is not an issue.
"""
class TrieNode:
def __init__(self):
self.nodes = dict() # Mapping from char to TrieNode
self.is_leaf = False
def insert_many(self, words: [str]):
"""
Inserts a list of words into the Trie
:param words: list of string words
:return: None
"""
for word in words:
self.insert(word)
def insert(self, word: str):
"""
Inserts a word into the Trie
:param word: word to be inserted
:return: None
"""
curr = self
for char in word:
if char not in curr.nodes:
curr.nodes[char] = TrieNode()
curr = curr.nodes[char]
curr.is_leaf = True
def find(self, word: str) -> bool:
"""
Tries to find word in a Trie
:param word: word to look for
:return: Returns True if word is found, False otherwise
"""
curr = self
for char in word:
if char not in curr.nodes:
return False
curr = curr.nodes[char]
return curr.is_leaf
def print_words(node: TrieNode, word: str):
"""
Prints all the words in a Trie
:param node: root node of Trie
:param word: Word variable should be empty at start
:return: None
"""
if node.is_leaf:
print(word, end=' ')
for key, value in node.nodes.items():
print_words(value, word + key)
def test():
words = ['banana', 'bananas', 'bandana', 'band', 'apple', 'all', 'beast']
root = TrieNode()
root.insert_many(words)
# print_words(root, '')
assert root.find('banana')
assert not root.find('bandanas')
assert not root.find('apps')
assert root.find('apple')
test()

View File

View File

@ -0,0 +1,78 @@
from __future__ import absolute_import
from .union_find import UnionFind
import unittest
class TestUnionFind(unittest.TestCase):
def test_init_with_valid_size(self):
uf = UnionFind(5)
self.assertEqual(uf.size, 5)
def test_init_with_invalid_size(self):
with self.assertRaises(ValueError):
uf = UnionFind(0)
with self.assertRaises(ValueError):
uf = UnionFind(-5)
def test_union_with_valid_values(self):
uf = UnionFind(10)
for i in range(11):
for j in range(11):
uf.union(i, j)
def test_union_with_invalid_values(self):
uf = UnionFind(10)
with self.assertRaises(ValueError):
uf.union(-1, 1)
with self.assertRaises(ValueError):
uf.union(11, 1)
def test_same_set_with_valid_values(self):
uf = UnionFind(10)
for i in range(11):
for j in range(11):
if i == j:
self.assertTrue(uf.same_set(i, j))
else:
self.assertFalse(uf.same_set(i, j))
uf.union(1, 2)
self.assertTrue(uf.same_set(1, 2))
uf.union(3, 4)
self.assertTrue(uf.same_set(3, 4))
self.assertFalse(uf.same_set(1, 3))
self.assertFalse(uf.same_set(1, 4))
self.assertFalse(uf.same_set(2, 3))
self.assertFalse(uf.same_set(2, 4))
uf.union(1, 3)
self.assertTrue(uf.same_set(1, 3))
self.assertTrue(uf.same_set(1, 4))
self.assertTrue(uf.same_set(2, 3))
self.assertTrue(uf.same_set(2, 4))
uf.union(4, 10)
self.assertTrue(uf.same_set(1, 10))
self.assertTrue(uf.same_set(2, 10))
self.assertTrue(uf.same_set(3, 10))
self.assertTrue(uf.same_set(4, 10))
def test_same_set_with_invalid_values(self):
uf = UnionFind(10)
with self.assertRaises(ValueError):
uf.same_set(-1, 1)
with self.assertRaises(ValueError):
uf.same_set(11, 0)
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,87 @@
class UnionFind():
"""
https://en.wikipedia.org/wiki/Disjoint-set_data_structure
The union-find is a disjoint-set data structure
You can merge two sets and tell if one set belongs to
another one.
It's used on the Kruskal Algorithm
(https://en.wikipedia.org/wiki/Kruskal%27s_algorithm)
The elements are in range [0, size]
"""
def __init__(self, size):
if size <= 0:
raise ValueError("size should be greater than 0")
self.size = size
# The below plus 1 is because we are using elements
# in range [0, size]. It makes more sense.
# Every set begins with only itself
self.root = [i for i in range(size+1)]
# This is used for heuristic union by rank
self.weight = [0 for i in range(size+1)]
def union(self, u, v):
"""
Union of the sets u and v.
Complexity: log(n).
Amortized complexity: < 5 (it's very fast).
"""
self._validate_element_range(u, "u")
self._validate_element_range(v, "v")
if u == v:
return
# Using union by rank will guarantee the
# log(n) complexity
rootu = self._root(u)
rootv = self._root(v)
weight_u = self.weight[rootu]
weight_v = self.weight[rootv]
if weight_u >= weight_v:
self.root[rootv] = rootu
if weight_u == weight_v:
self.weight[rootu] += 1
else:
self.root[rootu] = rootv
def same_set(self, u, v):
"""
Return true if the elements u and v belongs to
the same set
"""
self._validate_element_range(u, "u")
self._validate_element_range(v, "v")
return self._root(u) == self._root(v)
def _root(self, u):
"""
Get the element set root.
This uses the heuristic path compression
See wikipedia article for more details.
"""
if u != self.root[u]:
self.root[u] = self._root(self.root[u])
return self.root[u]
def _validate_element_range(self, u, element_name):
"""
Raises ValueError if element is not in range
"""
if u < 0 or u > self.size:
msg = ("element {0} with value {1} "
"should be in range [0~{2}]")\
.format(element_name, u, self.size)
raise ValueError(msg)

View File

View File

@ -0,0 +1,37 @@
import math
class Graph:
def __init__(self, N = 0): # a graph with Node 0,1,...,N-1
self.N = N
self.W = [[math.inf for j in range(0,N)] for i in range(0,N)] # adjacency matrix for weight
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
def addEdge(self, u, v, w):
self.dp[u][v] = w
def floyd_warshall(self):
for k in range(0,self.N):
for i in range(0,self.N):
for j in range(0,self.N):
self.dp[i][j] = min(self.dp[i][j], self.dp[i][k] + self.dp[k][j])
def showMin(self, u, v):
return self.dp[u][v]
if __name__ == '__main__':
graph = Graph(5)
graph.addEdge(0,2,9)
graph.addEdge(0,4,10)
graph.addEdge(1,3,5)
graph.addEdge(2,3,7)
graph.addEdge(3,0,10)
graph.addEdge(3,1,2)
graph.addEdge(3,2,1)
graph.addEdge(3,4,6)
graph.addEdge(4,1,3)
graph.addEdge(4,2,4)
graph.addEdge(4,3,9)
graph.floyd_warshall()
graph.showMin(1,4)
graph.showMin(0,3)

View File

@ -0,0 +1,29 @@
"""
https://www.hackerrank.com/challenges/abbr/problem
You can perform the following operation on some string, :
1. Capitalize zero or more of 's lowercase letters at some index i
(i.e., make them uppercase).
2. Delete all of the remaining lowercase letters in .
Example:
a=daBcd and b="ABC"
daBcd -> capitalize a and c(dABCd) -> remove d (ABC)
"""
def abbr(a, b):
n = len(a)
m = len(b)
dp = [[False for _ in range(m + 1)] for _ in range(n + 1)]
dp[0][0] = True
for i in range(n):
for j in range(m + 1):
if dp[i][j]:
if j < m and a[i].upper() == b[j]:
dp[i + 1][j + 1] = True
if a[i].islower():
dp[i + 1][j] = True
return dp[n][m]
if __name__ == "__main__":
print abbr("daBcd", "ABC") # expect True

View File

@ -0,0 +1,26 @@
"""
You have m types of coins available in infinite quantities
where the value of each coins is given in the array S=[S0,... Sm-1]
Can you determine number of ways of making change for n units using
the given types of coins?
https://www.hackerrank.com/challenges/coin-change/problem
"""
from __future__ import print_function
def dp_count(S, m, n):
table = [0] * (n + 1)
# Base case (If given value is 0)
table[0] = 1
# Pick all coins one by one and update table[] values
# after the index greater than or equal to the value of the
# picked coin
for i in range(0, m):
for j in range(S[i], n + 1):
table[j] += table[j - S[i]]
return table[n]
if __name__ == '__main__':
print(dp_count([1, 2, 3], 3, 4)) # answer 4
print(dp_count([2, 5, 3, 6], 4, 10)) # answer 5

View File

@ -0,0 +1,75 @@
"""
Author : Turfa Auliarachman
Date : October 12, 2016
This is a pure Python implementation of Dynamic Programming solution to the edit distance problem.
The problem is :
Given two strings A and B. Find the minimum number of operations to string B such that A = B. The permitted operations are removal, insertion, and substitution.
"""
from __future__ import print_function
class EditDistance:
"""
Use :
solver = EditDistance()
editDistanceResult = solver.solve(firstString, secondString)
"""
def __init__(self):
self.__prepare__()
def __prepare__(self, N = 0, M = 0):
self.dp = [[-1 for y in range(0,M)] for x in range(0,N)]
def __solveDP(self, x, y):
if (x==-1):
return y+1
elif (y==-1):
return x+1
elif (self.dp[x][y]>-1):
return self.dp[x][y]
else:
if (self.A[x]==self.B[y]):
self.dp[x][y] = self.__solveDP(x-1,y-1)
else:
self.dp[x][y] = 1+min(self.__solveDP(x,y-1), self.__solveDP(x-1,y), self.__solveDP(x-1,y-1))
return self.dp[x][y]
def solve(self, A, B):
if isinstance(A,bytes):
A = A.decode('ascii')
if isinstance(B,bytes):
B = B.decode('ascii')
self.A = str(A)
self.B = str(B)
self.__prepare__(len(A), len(B))
return self.__solveDP(len(A)-1, len(B)-1)
if __name__ == '__main__':
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
solver = EditDistance()
print("****************** Testing Edit Distance DP Algorithm ******************")
print()
print("Enter the first string: ", end="")
S1 = raw_input().strip()
print("Enter the second string: ", end="")
S2 = raw_input().strip()
print()
print("The minimum Edit Distance is: %d" % (solver.solve(S1, S2)))
print()
print("*************** End of Testing Edit Distance DP Algorithm ***************")

View File

@ -0,0 +1,43 @@
"""
This program calculates the nth Fibonacci number in O(log(n)).
It's possible to calculate F(1000000) in less than a second.
"""
from __future__ import print_function
import sys
# returns F(n)
def fibonacci(n: int):
if n < 0:
raise ValueError("Negative arguments are not supported")
return _fib(n)[0]
# returns (F(n), F(n-1))
def _fib(n: int):
if n == 0:
# (F(0), F(1))
return (0, 1)
else:
# F(2n) = F(n)[2F(n+1) F(n)]
# F(2n+1) = F(n+1)^2+F(n)^2
a, b = _fib(n // 2)
c = a * (b * 2 - a)
d = a * a + b * b
if n % 2 == 0:
return (c, d)
else:
return (d, c + d)
if __name__ == "__main__":
args = sys.argv[1:]
if len(args) != 1:
print("Too few or too much parameters given.")
exit(1)
try:
n = int(args[0])
except ValueError:
print("Could not convert data to an integer.")
exit(1)
print("F(%d) = %d" % (n, fibonacci(n)))

View File

@ -0,0 +1,54 @@
"""
This is a pure Python implementation of Dynamic Programming solution to the fibonacci sequence problem.
"""
from __future__ import print_function
class Fibonacci:
def __init__(self, N=None):
self.fib_array = []
if N:
N = int(N)
self.fib_array.append(0)
self.fib_array.append(1)
for i in range(2, N + 1):
self.fib_array.append(self.fib_array[i - 1] + self.fib_array[i - 2])
elif N == 0:
self.fib_array.append(0)
def get(self, sequence_no=None):
if sequence_no != None:
if sequence_no < len(self.fib_array):
return print(self.fib_array[:sequence_no + 1])
else:
print("Out of bound.")
else:
print("Please specify a value")
if __name__ == '__main__':
print("\n********* Fibonacci Series Using Dynamic Programming ************\n")
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
print("\n Enter the upper limit for the fibonacci sequence: ", end="")
try:
N = eval(raw_input().strip())
fib = Fibonacci(N)
print(
"\n********* Enter different values to get the corresponding fibonacci sequence, enter any negative number to exit. ************\n")
while True:
print("Enter value: ", end=" ")
try:
i = eval(raw_input().strip())
if i < 0:
print("\n********* Good Bye!! ************\n")
break
fib.get(i)
except NameError:
print("\nInvalid input, please try again.")
except NameError:
print("\n********* Invalid input, good bye!! ************\n")

View File

@ -0,0 +1,141 @@
import tensorflow as tf
from random import choice, shuffle
from numpy import array
def TFKMeansCluster(vectors, noofclusters):
"""
K-Means Clustering using TensorFlow.
'vectors' should be a n*k 2-D NumPy array, where n is the number
of vectors of dimensionality k.
'noofclusters' should be an integer.
"""
noofclusters = int(noofclusters)
assert noofclusters < len(vectors)
#Find out the dimensionality
dim = len(vectors[0])
#Will help select random centroids from among the available vectors
vector_indices = list(range(len(vectors)))
shuffle(vector_indices)
#GRAPH OF COMPUTATION
#We initialize a new graph and set it as the default during each run
#of this algorithm. This ensures that as this function is called
#multiple times, the default graph doesn't keep getting crowded with
#unused ops and Variables from previous function calls.
graph = tf.Graph()
with graph.as_default():
#SESSION OF COMPUTATION
sess = tf.Session()
##CONSTRUCTING THE ELEMENTS OF COMPUTATION
##First lets ensure we have a Variable vector for each centroid,
##initialized to one of the vectors from the available data points
centroids = [tf.Variable((vectors[vector_indices[i]]))
for i in range(noofclusters)]
##These nodes will assign the centroid Variables the appropriate
##values
centroid_value = tf.placeholder("float64", [dim])
cent_assigns = []
for centroid in centroids:
cent_assigns.append(tf.assign(centroid, centroid_value))
##Variables for cluster assignments of individual vectors(initialized
##to 0 at first)
assignments = [tf.Variable(0) for i in range(len(vectors))]
##These nodes will assign an assignment Variable the appropriate
##value
assignment_value = tf.placeholder("int32")
cluster_assigns = []
for assignment in assignments:
cluster_assigns.append(tf.assign(assignment,
assignment_value))
##Now lets construct the node that will compute the mean
#The placeholder for the input
mean_input = tf.placeholder("float", [None, dim])
#The Node/op takes the input and computes a mean along the 0th
#dimension, i.e. the list of input vectors
mean_op = tf.reduce_mean(mean_input, 0)
##Node for computing Euclidean distances
#Placeholders for input
v1 = tf.placeholder("float", [dim])
v2 = tf.placeholder("float", [dim])
euclid_dist = tf.sqrt(tf.reduce_sum(tf.pow(tf.sub(
v1, v2), 2)))
##This node will figure out which cluster to assign a vector to,
##based on Euclidean distances of the vector from the centroids.
#Placeholder for input
centroid_distances = tf.placeholder("float", [noofclusters])
cluster_assignment = tf.argmin(centroid_distances, 0)
##INITIALIZING STATE VARIABLES
##This will help initialization of all Variables defined with respect
##to the graph. The Variable-initializer should be defined after
##all the Variables have been constructed, so that each of them
##will be included in the initialization.
init_op = tf.initialize_all_variables()
#Initialize all variables
sess.run(init_op)
##CLUSTERING ITERATIONS
#Now perform the Expectation-Maximization steps of K-Means clustering
#iterations. To keep things simple, we will only do a set number of
#iterations, instead of using a Stopping Criterion.
noofiterations = 100
for iteration_n in range(noofiterations):
##EXPECTATION STEP
##Based on the centroid locations till last iteration, compute
##the _expected_ centroid assignments.
#Iterate over each vector
for vector_n in range(len(vectors)):
vect = vectors[vector_n]
#Compute Euclidean distance between this vector and each
#centroid. Remember that this list cannot be named
#'centroid_distances', since that is the input to the
#cluster assignment node.
distances = [sess.run(euclid_dist, feed_dict={
v1: vect, v2: sess.run(centroid)})
for centroid in centroids]
#Now use the cluster assignment node, with the distances
#as the input
assignment = sess.run(cluster_assignment, feed_dict = {
centroid_distances: distances})
#Now assign the value to the appropriate state variable
sess.run(cluster_assigns[vector_n], feed_dict={
assignment_value: assignment})
##MAXIMIZATION STEP
#Based on the expected state computed from the Expectation Step,
#compute the locations of the centroids so as to maximize the
#overall objective of minimizing within-cluster Sum-of-Squares
for cluster_n in range(noofclusters):
#Collect all the vectors assigned to this cluster
assigned_vects = [vectors[i] for i in range(len(vectors))
if sess.run(assignments[i]) == cluster_n]
#Compute new centroid location
new_location = sess.run(mean_op, feed_dict={
mean_input: array(assigned_vects)})
#Assign value to appropriate variable
sess.run(cent_assigns[cluster_n], feed_dict={
centroid_value: new_location})
#Return centroids and assignments
centroids = sess.run(centroids)
assignments = sess.run(assignments)
return centroids, assignments

View File

@ -0,0 +1,14 @@
"""
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.
"""
def knapsack(W, wt, val, n):
dp = [[0 for i in range(W+1)]for j in range(n+1)]
for i in range(1,n+1):
for w in range(1,W+1):
if(wt[i-1]<=w):
dp[i][w] = max(val[i-1]+dp[i-1][w-wt[i-1]],dp[i-1][w])
else:
dp[i][w] = dp[i-1][w]
return dp[n][w]

View File

@ -0,0 +1,37 @@
"""
LCS Problem Statement: Given two sequences, find the length of longest subsequence present in both of them.
A subsequence is a sequence that appears in the same relative order, but not necessarily continious.
Example:"abc", "abg" are subsequences of "abcdefgh".
"""
from __future__ import print_function
try:
xrange # Python 2
except NameError:
xrange = range # Python 3
def lcs_dp(x, y):
# find the length of strings
m = len(x)
n = len(y)
# declaring the array for storing the dp values
L = [[None] * (n + 1) for i in xrange(m + 1)]
seq = []
for i in range(m + 1):
for j in range(n + 1):
if i == 0 or j == 0:
L[i][j] = 0
elif x[i - 1] == y[ j - 1]:
L[i][j] = L[i - 1][j - 1] + 1
seq.append(x[i -1])
else:
L[i][j] = max(L[i - 1][j], L[i][j - 1])
# L[m][n] contains the length of LCS of X[0..n-1] & Y[0..m-1]
return L[m][n], seq
if __name__=='__main__':
x = 'AGGTAB'
y = 'GXTXAYB'
print(lcs_dp(x, y))

View File

@ -0,0 +1,42 @@
'''
Author : Mehdi ALAOUI
This is a pure Python implementation of Dynamic Programming solution to the longest increasing subsequence of a given sequence.
The problem is :
Given an ARRAY, to find the longest and increasing sub ARRAY in that given ARRAY and return it.
Example: [10, 22, 9, 33, 21, 50, 41, 60, 80] as input will return [10, 22, 33, 41, 60, 80] as output
'''
from __future__ import print_function
def longestSub(ARRAY): #This function is recursive
ARRAY_LENGTH = len(ARRAY)
if(ARRAY_LENGTH <= 1): #If the array contains only one element, we return it (it's the stop condition of recursion)
return ARRAY
#Else
PIVOT=ARRAY[0]
isFound=False
i=1
LONGEST_SUB=[]
while(not isFound and i<ARRAY_LENGTH):
if (ARRAY[i] < PIVOT):
isFound=True
TEMPORARY_ARRAY = [ element for element in ARRAY[i:] if element >= ARRAY[i] ]
TEMPORARY_ARRAY = longestSub(TEMPORARY_ARRAY)
if ( len(TEMPORARY_ARRAY) > len(LONGEST_SUB) ):
LONGEST_SUB = TEMPORARY_ARRAY
else:
i+=1
TEMPORARY_ARRAY = [ element for element in ARRAY[1:] if element >= PIVOT ]
TEMPORARY_ARRAY = [PIVOT] + longestSub(TEMPORARY_ARRAY)
if ( len(TEMPORARY_ARRAY) > len(LONGEST_SUB) ):
return TEMPORARY_ARRAY
else:
return LONGEST_SUB
#Some examples
print(longestSub([4,8,7,5,1,12,2,3,9]))
print(longestSub([9,8,7,6,5,7]))

View File

@ -0,0 +1,41 @@
from __future__ import print_function
#############################
# Author: Aravind Kashyap
# File: lis.py
# comments: This programme outputs the Longest Strictly Increasing Subsequence in O(NLogN)
# Where N is the Number of elements in the list
#############################
def CeilIndex(v,l,r,key):
while r-l > 1:
m = (l + r)/2
if v[m] >= key:
r = m
else:
l = m
return r
def LongestIncreasingSubsequenceLength(v):
if(len(v) == 0):
return 0
tail = [0]*len(v)
length = 1
tail[0] = v[0]
for i in range(1,len(v)):
if v[i] < tail[0]:
tail[0] = v[i]
elif v[i] > tail[length-1]:
tail[length] = v[i]
length += 1
else:
tail[CeilIndex(tail,-1,length-1,v[i])] = v[i]
return length
v = [2, 5, 3, 7, 11, 8, 10, 13, 6]
print(LongestIncreasingSubsequenceLength(v))

View File

@ -0,0 +1,33 @@
'''
Auther : Yvonne
This is a pure Python implementation of Dynamic Programming solution to the longest_sub_array problem.
The problem is :
Given an array, to find the longest and continuous sub array and get the max sum of the sub array in the given array.
'''
from __future__ import print_function
class SubArray:
def __init__(self, arr):
# we need a list not a string, so do something to change the type
self.array = arr.split(',')
print(("the input array is:", self.array))
def solve_sub_array(self):
rear = [int(self.array[0])]*len(self.array)
sum_value = [int(self.array[0])]*len(self.array)
for i in range(1, len(self.array)):
sum_value[i] = max(int(self.array[i]) + sum_value[i-1], int(self.array[i]))
rear[i] = max(sum_value[i], rear[i-1])
return rear[len(self.array)-1]
if __name__ == '__main__':
whole_array = input("please input some numbers:")
array = SubArray(whole_array)
re = array.solve_sub_array()
print(("the results is:", re))

View File

@ -0,0 +1,60 @@
"""
author : Mayank Kumar Jha (mk9440)
"""
from __future__ import print_function
import time
import matplotlib.pyplot as plt
from random import randint
def find_max_sub_array(A,low,high):
if low==high:
return low,high,A[low]
else :
mid=(low+high)//2
left_low,left_high,left_sum=find_max_sub_array(A,low,mid)
right_low,right_high,right_sum=find_max_sub_array(A,mid+1,high)
cross_left,cross_right,cross_sum=find_max_cross_sum(A,low,mid,high)
if left_sum>=right_sum and left_sum>=cross_sum:
return left_low,left_high,left_sum
elif right_sum>=left_sum and right_sum>=cross_sum :
return right_low,right_high,right_sum
else:
return cross_left,cross_right,cross_sum
def find_max_cross_sum(A,low,mid,high):
left_sum,max_left=-999999999,-1
right_sum,max_right=-999999999,-1
summ=0
for i in range(mid,low-1,-1):
summ+=A[i]
if summ > left_sum:
left_sum=summ
max_left=i
summ=0
for i in range(mid+1,high+1):
summ+=A[i]
if summ > right_sum:
right_sum=summ
max_right=i
return max_left,max_right,(left_sum+right_sum)
if __name__=='__main__':
inputs=[10,100,1000,10000,50000,100000,200000,300000,400000,500000]
tim=[]
for i in inputs:
li=[randint(1,i) for j in range(i)]
strt=time.time()
(find_max_sub_array(li,0,len(li)-1))
end=time.time()
tim.append(end-strt)
print("No of Inputs Time Taken")
for i in range(len(inputs)):
print((inputs[i],'\t\t',tim[i]))
plt.plot(inputs,tim)
plt.xlabel("Number of Inputs");plt.ylabel("Time taken in seconds ")
plt.show()

View File

@ -0,0 +1,28 @@
"""
Partition a set into two subsets such that the difference of subset sums is minimum
"""
def findMin(arr):
n = len(arr)
s = sum(arr)
dp = [[False for x in range(s+1)]for y in range(n+1)]
for i in range(1, n+1):
dp[i][0] = True
for i in range(1, s+1):
dp[0][i] = False
for i in range(1, n+1):
for j in range(1, s+1):
dp[i][j]= dp[i][j-1]
if (arr[i-1] <= j):
dp[i][j] = dp[i][j] or dp[i-1][j-arr[i-1]]
for j in range(int(s/2), -1, -1):
if dp[n][j] == True:
diff = s-2*j
break;
return diff

Some files were not shown because too many files have changed in this diff Show More