This commit is contained in:
Marina Wahl 2014-03-17 16:11:16 -04:00
parent cf40c0610f
commit dad3793c4b
44 changed files with 25 additions and 2028 deletions

View File

@ -1,49 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Heapify(object):
def __init__(self, data=None):
self.data = data or []
for i in range(len(data)//2, -1, -1):
self.__max_heapify__(i)
def __repr__(self):
return '{}'.format(self.data)
def parent(self, i):
return i >> 1
def left_child(self, i):
return (i << 1) + 1
def right_child(self, i):
return (i << 1) + 2 # +2 instead of +1 because it's 0-indexed.
def __max_heapify__(self, i):
largest = i
left = self.left_child(i)
right = self.right_child(i)
n = len(self.data)
largest = (left < n and self.data[left] > self.data[i]) and left or i
largest = (right < n and self.data[right] > self.data[largest]) and right or largest
if i is not largest:
self.data[i], self.data[largest] = self.data[largest], self.data[i]
self.__max_heapify__(largest)
def extract_max(self):
n = len(self.data)
max_element = self.data[0]
self.data[0] = self.data[n - 1]
self.data = self.data[:n - 1]
self.__max_heapify__(0)
return max_element
def test_Heapify():
l1 = [3, 2, 5, 1, 7, 8, 2]
h = Heapify(l1)
assert(h.extract_max() == 8)
if __name__ == '__main__':
test_Heapify()

View File

@ -1,41 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import heapq
class PriorityQueue(object):
''' implements a priority queue class '''
def __init__(self):
self._queue = []
self._index = 0 # index property order items with same priority level, good for comparisons
def push(self, item, priority):
heapq.heappush(self._queue, (-priority, self._index, item)) # notice the tuple
self._index += 1
def pop(self):
return heapq.heappop(self._queue)[-1]
class Item:
def __init__(self, name):
self.name = name
def __repr__(self):
return "Item({!r})".format(self.name)
def test_PriorityQueue():
''' push and pop are all O(logN) '''
q = PriorityQueue()
q.push(Item('test1'), 1)
q.push(Item('test2'), 4)
q.push(Item('test3'), 3)
assert(str(q.pop()) == "Item('test2')")
print('Tests passed!'.center(20,'*'))
if __name__ == '__main__':
test_PriorityQueue()

View File

@ -1,44 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
'''The structure of an unordered list is a collection of items where each item holds a relative position with respect to the others '''
class Node:
''' The basic building block for the linked list implementation is the node.
Each node object must hold at least two pieces of information:
First, the node must contain the list item itself (data field),
second each node must hold a reference to the next node '''
def __init__(self,initdata):
self.data = initdata
self.next = None
def getData(self):
return self.data
def getNext(self):
return self.next
def setData(self,newdata):
self.data = newdata
def setNext(self,newnext):
self.next = newnext
def test_Node(module_name='this module'):
temp = Node(40)
assert(temp.getData() == 40)
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_Node()

View File

@ -1,65 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from node import Node
class UnorderedList(object):
def __init__(self):
self.head = None
def add(self, item):
temp = Node(item)
temp.setNext(self.head)
self.head = temp
def length(self):
current = self.head
count = 0
while current != None:
count = count + 1
current = current.getNext()
return count
def search(self,item):
current = self.head
found = False
while current != None and not found:
if current.getData() == item:
found = True
else:
current = current.getNext()
return found
def remove(self,item):
current = self.head
previous = None
found = False
while not found:
if current.getData() == item:
found = True
else:
previous = current
current = current.getNext()
if previous == None:
self.head = current.getNext()
else:
previous.setNext(current.getNext())
def test_UnorderedList(module_name='this module'):
llist = UnorderedList()
llist.add(31)
llist.add(22)
llist.add(10)
assert(llist.search(22) == True)
llist.remove(22)
assert(llist.search(22) == False)
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_UnorderedList()

View File

@ -1,39 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
'''The structure of an unordered list is a collection of items where each item holds a relative position with respect to the others '''
class Node:
def __init__(self,initdata):
self.data = initdata
self.next = None
def getData(self):
return self.data
def getNext(self):
return self.next
def setData(self,newdata):
self.data = newdata
def setNext(self,newnext):
self.next = newnext
def test_Node(module_name='this module'):
temp = Node(40)
assert(temp.getData() == 40)
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_Node()

View File

@ -1,46 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Deque(object):
''' a class for a double ended queue '''
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def add_front(self, item):
self.items.append(item)
def add_rear(self, item):
self.items.insert(0, item)
def remove_front(self):
return self.items.pop()
def remove_rear(self):
return self.items.pop(0)
def size(self):
return len(self.items)
def __repr__(self):
return '{}'.format(self.items)
def main():
dq = Deque()
dq.add_front(1)
dq.add_front(2)
dq.add_front(3)
dq.add_rear(40)
dq.add_rear(50)
assert(dq.size() == 5)
assert(dq == [50, 40, 1, 2, 3])
if __name__ == '__main__':
main()

View File

@ -1,61 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Node(object):
def __init__(self, value):
self.value = value
self.next = None
class LinkedQueue(object):
''' Queue acts as a container for nodes (objects) that are inserted and removed according FIFO'''
def __init__(self):
self.front = None
self.back = None
def isEmpty(self):
return bool(self.front)
def dequeue(self):
if self.front:
value = self.front.value
self.front = self.front.next
return value
raise Exception('Queue is empty, cannot dequeue.')
def enqueue(self, value):
node = Node(value)
if self.front:
self.back.next = node
self.back = node
else:
self.front = node
self.back = node
return True
def size(self):
node = self.front
num_nodes = 1
while node.next:
num_nodes += 1
node = node.next
return num_nodes
def peek(self):
return self.front.value[-1]
def main():
queue = LinkedQueue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print(queue.size())
print(queue.peek())
print(queue.dequeue())
print(queue.peek())
if __name__ == '__main__':
main()

View File

@ -1,39 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Queue(object):
''' a class for a queue '''
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def enqueue(self, item):
self.items.insert(0, item)
def dequeue(self):
return self.items.pop()
def size(self):
return len(self.items)
def size(self):
return self.items[-1]
def main():
queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print(queue.size())
print(queue.peek())
print(queue.dequeue())
print(queue.peek())
if __name__ == '__main__':
main()

View File

@ -1,48 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Queue(object):
''' an example of a queue implemented from 2 stacks '''
def __init__(self):
self.in_stack = []
self.out_stack = []
def enqueue(self, item):
return self.in_stack.append(item)
def dequeue(self):
if self.out_stack:
return self.out_stack.pop()
while self.in_stack:
self.out_stack.append(self.in_stack.pop())
if not self.out_stack:
return "Queue empty!"
return self.out_stack.pop()
def size(self):
return len(self.in_stack) + len(self.out_stack)
def peek(self):
if self.out_stack:
return self.out_stack[-1]
while self.in_stack:
self.out_stack.append(self.in_stack.pop())
return self.out_stack[-1]
def main():
queue = Queue()
queue.add(1)
queue.add(2)
queue.add(3)
print(queue.size())
print(queue.peek())
print(queue.remove())
print(queue.peek())
if __name__ == '__main__':
main()

View File

@ -1,47 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Node:
def __init__(self, value):
self.value = value
self.next = None
class Queue:
''' Queue acts as a container for nodes (objects) that are inserted and removed according FIFO'''
def __init__(self):
self.first = None
self.last = None
def dequeue(self):
if self.front:
value = self.first.value
self.first = self.first.next
return value
raise Exception('Queue is empty, cannot dequeue.')
def enqueue(self, value):
node = Node(value)
if self.first:
self.last.next = node
self.last = node
else:
self.first = node
self.last = node
return True
def isEmpty(self):
return bool(self.first)
def size(self):
node = self.first
num_nodes = 0
while node.next:
num_nodes += 1
node = node.next
return num_nodes

View File

@ -1,51 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Node:
def __init__(self, value=None):
self.value = value
self.next = None
class StackwithNodes:
''' Define a Stack with nodes'''
def __init__(self):
self.top = None
def isEmpty(self):
return bool(self.top)
def pop(self):
node = self.top
self.top = node.next
return node.value
def push(self, value):
node = Node(value)
node.next = self.top
self.top = node
def size(self):
node = self.top
num_nodes = 1
while node.next:
num_nodes += 1
node = node.next
return num_nodes
def peek(self):
return self.top.value
def main():
stack = StackwithNodes()
stack.push(1)
stack.push(2)
stack.push(3)
print(stack.size())
print(stack.peek())
print(stack.pop())
print(stack.peek())
if __name__ == '__main__':
main()

View File

@ -1,30 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import sys
import stack
def reverse_string_with_stack(str1):
''' Uses a stack to reverse a string '''
s = stack.Stack()
revStr = ''
for c in str1:
s.push(c)
while not s.isEmpty():
revStr += s.pop()
return revStr
def test_reverse_string_with_stack():
str1 = 'Buffy is a Slayer!'
assert(reverse_string_with_stack(str1) == '!reyalS a si yffuB')
print('Tests passed!')
if __name__ == '__main__':
test_reverse_string_with_stack()

View File

@ -1,48 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class SetOfStacks(list):
def __init__(self, capacity=4):
self.stacks = []
self.last_stack = []
self.capacity = capacity
self.stacks.append(self.last_stack)
def __repr__(self):
return str(self.stacks)
def push(self, value):
last_stack = self.last_stack
if len(last_stack) is self.capacity:
last_stack = []
self.last_stack = last_stack
self.stacks.append(last_stack)
last_stack.append(value)
def pop(self):
last_stack = self.last_stack
value = last_stack.pop()
if len(last_stack) is 0:
self.stacks.pop()
self.last_stack = self.stacks[-1]
return value
def main():
stack = SetOfStacks()
stack.push(1)
stack.push(2)
stack.push(3)
stack.push(4)
stack.push(5)
stack.push(6)
print(stack)
stack.pop()
stack.pop()
stack.pop()
print(stack)
if __name__ == '__main__':
main()

View File

@ -1,24 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Stack(object):
''' define the stack class '''
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def push(self, items):
self.items.append(items)
def pop(self):
return self.items.pop()
def peek(self):
return self.items[-1]
def size(self):
return len(self.items)

View File

@ -1,54 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from linked_stack import StackwithNodes
from node import Node
class StackWithMins(Stack):
mins = StackwithNodes()
def push(self, item):
node = Node(item)
node.next = self.top
self.top = node
if self.mins.top is not None:
if self.mins.top.data > item:
self.mins.push(item)
else:
self.mins.push(item)
def pop(self):
if self.top is not None:
if self.peek() == self.mins.peek():
self.mins.pop()
node = self.top
self.top = self.top.next
return node
return None
def min(self):
return self.mins.peek()
def test_():
stack = StackWithMins()
stack.push(9)
stack.push(5)
stack.push(7)
stack.push(4)
stack.push(3)
stack.push(6)
stack.push(5)
stack.push(2)
stack.push(1)
stack.print_stack()
stack.mins.print_stack()
if __name__ == '__main__':
test_()

View File

@ -1,16 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import random
def benchmark(func):
import time
def wrapper(*args, **kwargs):
t = time.clock()
res = func(*args, **kwargs)
print("\t%s" % func.__name__, time.clock()-t)
return res
return wrapper

View File

@ -1,31 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def find_long_con_inc(seq):
''' find the longest continuous increasing subsequence'''
one_seq = []
result = []
for i in range(0, len(seq)-1):
pivot = seq[i]
if pivot <= seq[i+1]:
one_seq.append(pivot)
else:
one_seq.append(pivot)
if len(one_seq) > len(result):
result = one_seq
one_seq = []
return result
def test_find_long_con_inc(module_name='this module'):
seq = [1, -2, 3, 5, 1, -1, 4, -1, 6]
long_con_inc = [-2,3,5]
assert(find_long_con_inc(seq) == long_con_inc )
if __name__ == '__main__':
test_find_long_con_inc()

View File

@ -1,44 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def find_max_subarray1(l1):
''' calculate the greatest sum of subarrays from an array.
An array with n elements has n(n+1)/2 subarrays so force brute cost O(n^2).
What we can do is to check when a sum becomes a negative number or zero, and then discard, since
this will not "add" anything to the new event... When the sum decreases, it gets the previous sum. '''
sum_new, result = 0, 0
for c in l1:
result = max(result, sum_new)
sum_new += c
if sum_new <= 0: sum_new = 0
return result
def find_max_subarray2(l1):
''' find the contiguous subarray which has the largest sum (Kadane's algorithm in O(n))
with extra O(n) space '''
sum_old = [l1[0]]
for c in l1:
sum_old.append(max(c, sum_old [-1] + c))
return max(sum_old)
def test_find_max_subarray():
l1 = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
l2 = [-1, 3, -5, 4, 6, -1, 2, -7, 13, -3]
assert(find_max_subarray1(l1)) == 6)
assert(find_max_subarray1(l2)) == 17)
assert(find_max_subarray2(l1) == 6)
assert(find_max_subarray2(l2) == 17)
print('Tests passed!')
if __name__ == '__main__':
test_find_max_subarray()

View File

@ -1,47 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def find_closest_num_seq_unsorted(seq):
''' Find the Closest two Numbers in a Sequence. If we do this without sorting
first, the runtime will be O(n^2) '''
dd = float("inf")
for x in seq:
for y in seq:
if x == y: continue
d = abs(x - y)
if d < dd:
xx, yy, dd = x, y, d
return xx, yy
def find_closest_num_seq_sorted(seq):
''' However, if we sort first, we can achieve it with runtime O(n log n): '''
seq.sort()
print(seq)
dd = float("inf")
for i in range(len(seq) - 1):
x, y = seq[i], seq[i+1]
if x == y: continue
d = abs(x-y)
if d < dd:
xx, yy, dd = x, y, d
return xx, yy
def test_find_closest_num_seq(module_name='this module'):
import random
seq = [random.randrange(100) for i in range(20)]
print(seq)
print(find_closest_num_seq_sorted(seq))
print(find_closest_num_seq_unsorted(seq))
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_find_closest_num_seq()

View File

@ -1,25 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import random
def benchmark(func):
import time
def wrapper(*args, **kwargs):
t = time.clock()
res = func(*args, **kwargs)
print("\t%s" % func.__name__, time.clock()-t)
return res
return wrapper
@benchmark
def random_tree(n):
temp = [n for n in range(n)]
for i in range(n+1):
temp[random.choice(temp)] = random.choice(temp)
return temp
if __name__ == '__main__':
random_tree(1000)

View File

@ -1,41 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def find_subst_in_str(str1, set1):
sub_str1 = ''
found = False
while set1:
for c in str1):
if c in set1:
set1.remove(c)
found = True
if found == True:
sub_str1 += c
if len(set1) == 0: found = False
return sub_str1
def test_find_subst_in_str(module_name='this module'):
str1 = 'ydxahbcscdk'
set1 = {'a','b','c','d'}
result = 'dxahbc'
assert( find_subst_in_str(str1, set1)==result)
set2 = {'a','b','c'}
result2 = 'ahbc'
assert( find_subst_in_str(str1, set2)==result2)
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_find_subst_in_str()

View File

@ -1,34 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def reverse_string_inplace_rec(s):
''' takes a string and returns its reverse'''
if s:
s = s[-1] + reverse_string_inplace_rec(s[:-1])
return s
def reverse_string_inplace(s):
s = s[::-1]
if s[0] == '\0':
s = s[1:]
s += '\0'
print(s)
return s
def test_reverse_string_inplace_rec(module_name='this module'):
s = 'hello'
s2 = 'buffy\0'
assert(reverse_string_inplace(s) == 'olleh')
assert(reverse_string_inplace(s2) == 'yffub\0')
assert(reverse_string_inplace_rec(s) == 'olleh')
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_reverse_string_inplace_rec()

View File

@ -1,23 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def reversing_words_setence(str1):
''' reverse the words in a setence in a string'''
words = str1.split()
rev_set = " ".join(reversed(words))
return rev_set
def test_reversing_words_setence(module_name='this module'):
str1 = "Buffy is a Vampire Slayer"
assert(reversing_words_setence(str1) == "Slayer Vampire a is Buffy")
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_reversing_words_setence()

View File

@ -1,47 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def binary_search(seq, key, lo=0, hi=None):
''' binary search iterative algorithm '''
hi = hi or len(seq)
while lo < hi:
mid = (hi+lo) // 2
if seq[mid] == key:
return mid
elif key < seq[mid]:
hi = mid
else:
lo = mid + 1
return None
def binary_search_rec(seq, key, lo=0, hi=None):
''' binary search recursive algorithm '''
hi = hi or len(seq)
if (hi - lo) < 0: return None
mid = lo + ((hi - lo) // 2)
if seq[mid] == key:
return mid
elif seq[mid] < key:
return binary_search_rec(seq, key, mid + 1, hi)
else:
return binary_search_rec(seq, key, lo, mid - 1)
def test_binary_search():
seq = [1,2,5,6,7,10,12,12,14,15]
key = 6
assert(binary_search(seq, key) == 3)
assert(binary_search_rec(seq, key) == 3)
print('Tests passed!')
if __name__ == '__main__':
test_binary_search()

View File

@ -1,48 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import heapq
def heap_sort_api(seq):
''' heap sort with Python's heapq '''
h = []
for value in seq:
heapq.heappush(h, value)
return [heapq.heappop(h) for i in range(len(h))]
def heap_sort(seq):
''' heap sort explicitly '''
for start in range((len(seq)-2)//2, -1, -1):
siftdown(seq, start, len(seq)-1)
for end in range(len(seq)-1, 0, -1):
seq[end], seq[0] = seq[0], seq[end]
siftdown(seq, 0, end - 1)
return seq
def siftdown(seq, start, end):
root = start
while True:
child = root * 2 + 1
if child > end: break
if child + 1 <= end and seq[child] < seq[child + 1]:
child += 1
if seq[root] < seq[child]:
seq[root], seq[child] = seq[child], seq[root]
root = child
else:
break
def test_heap_sort():
seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
assert(heap_sort_api(seq) == sorted(seq))
assert(heap_sort(seq) == sorted(seq))
print('Tests passed!')
if __name__ == '__main__':
test_heap_sort()

View File

@ -1,48 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import heapq
def heap_sort_api(seq):
''' heap sort with Python's heapq '''
h = []
for value in seq:
heapq.heappush(h, value)
return [heapq.heappop(h) for i in range(len(h))]
def heap_sort(seq):
''' heap sort explicitly '''
for start in range((len(seq)-2)//2, -1, -1):
siftdown(seq, start, len(seq)-1)
for end in range(len(seq)-1, 0, -1):
seq[end], seq[0] = seq[0], seq[end]
siftdown(seq, 0, end - 1)
return seq
def siftdown(seq, start, end):
root = start
while True:
child = root * 2 + 1
if child > end: break
if child + 1 <= end and seq[child] < seq[child + 1]:
child += 1
if seq[root] < seq[child]:
seq[root], seq[child] = seq[child], seq[root]
root = child
else:
break
def test_heap_sort():
seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
assert(heap_sort_api(seq) == sorted(seq))
assert(heap_sort(seq) == sorted(seq))
print('Tests passed!')
if __name__ == '__main__':
test_heap_sort()

View File

@ -1,8 +0,0 @@
def heapsort(seq):
heap = Heap(seq)
res = []
for i in range(len(seq)):
res.insert(0, heap.extract_max())
return res

View File

@ -1,46 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from do_benchmark import benchmark
@benchmark
def insertion_sort(seq):
''' sort a sequence using the insertion sort alg '''
for i in range(1, len(seq)):
j = i
while j > 0 and seq[j-1] > seq[j]:
seq[j-1], seq[j] = seq[j], seq[j-1]
j -= 1
return seq
def insertion_sort_rec(seq, i = None):
''' sort a sequence using the recursive insertion sort alg '''
if i == None: i = len(seq) -1
if i == 0: return i
insertion_sort_rec(seq, i-1)
j = i
while j > 0 and seq[j-i] > seq[j]:
seq[j-1], seq[j] = seq[j], seq[j-1]
j -= 1
return seq
def test_insertion_sort():
seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2, 5, 4, 1, 5, 3]
assert(insertion_sort(seq) == sorted(seq))
assert(insertion_sort_rec(seq) == sorted(seq))
print('Tests passed!')
if __name__ == '__main__':
test_insertion_sort()

View File

@ -1,31 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def merge_sort(seq):
mid = len(seq)//2
lft, rgt = seq[:mid], seq[mid:]
if len(lft)>1: lft = merge_sort(lft)
if len(rgt)>1: rgt = merge_sort(rgt)
res = []
while lft and rgt:
if lft [-1]>= rgt[-1]:
res.append(lft.pop())
else:
res.append(rgt.pop())
res.reverse()
return(lft or rgt) + res
def test_merge_sort():
seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
assert(merge_sort(seq) == sorted(seq))
print('Tests passed!')
if __name__ == '__main__':
test_merge_sort()

View File

@ -1,41 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def quick_sort(seq):
if len(seq) < 2: return seq
pivot = seq[0]
left = quick_sort([x for x in seq[1:] if x < pivot])
right = quick_sort([x for x in seq[1:] if x >= pivot])
return left + [pivot] + right
""" we can also divide them into two functions """
def partition(seq):
pi,seq = seq[0],seq[1:]
lo = [x for x in seq if x <= pi]
hi = [x for x in seq if x > pi]
return lo, pi, hi
def quick_sort_divided(seq):
if len(seq) < 2: return seq
lo, pi, hi = partition(seq)
return quick_sort_divided(lo) + [pi] + quick_sort_divided(hi)
def test_quick_sort():
seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
assert(quick_sort(seq) == sorted(seq))
assert(quick_sort_divided(seq) == sorted(seq))
print('Tests passed!')
if __name__ == '__main__':
test_quick_sort()

View File

@ -1,68 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from BT import BT
class BST(BT):
def __init__(self, value=None):
self.value = value
self.left = None
self.right = None
def insert_left(self, new_node):
self.insert(value)
def insert_right(self, new_node):
self.insert(value)
def insert(self, value):
if self.value == None:
self.value = value
else:
if value > self.value:
self.right = self.right and self.right.insert(value) or BST(value)
else:
self.left = self.left and self.left.insert(value) or BST(value)
return self
def find(self, value):
if value == self.value:
return self
elif value > self.value and self.right:
return self.right.find(value)
elif self.left:
return self.left.find(value)
return None
def main():
"""
BST
4
2 6
1 3 5 7
"""
tree = BST()
tree.insert(4)
tree.insert(2)
tree.insert(6)
tree.insert(1)
tree.insert(3)
tree.insert(7)
tree.insert(5)
print(tree.get_right())
print(tree.get_right().get_left())
print(tree.get_right().get_right())
print(tree.get_left())
print(tree.get_left().get_left())
assert(tree.get_left().get_right() == str(1))
assert(tree.find(30) == None)
if __name__ == '__main__':
main()

View File

@ -1,67 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Node(object):
def __init__(self, value):
self.value = value
self.left = None
self.right = None
def __repr__(self):
return '{}'.format(self.value)
class BSTwithNodes(object):
def __init__(self):
self.root = None
def insert(self, value):
if self.root == None:
self.root = Node(value)
else:
current = self.root
while True:
if value < current.value:
if current.left:
current = current.left
else:
current.left = Node(value)
break;
elif value > current.value:
if current.right:
current = current.right
else:
current.right = Node(value)
break;
else:
break
def main():
"""
BST
4
2 6
1 3 5 7
"""
tree = BSTwithNodes()
l1 = [4, 2, 6, 1, 3, 7, 5]
for i in l1: tree.insert(i)
assert(tree.root == '4')
print(tree.root.right)
print(tree.root.right.left)
print(tree.root.right.right)
print(tree.root.left)
print(tree.root.left.left)
print(tree.root.left.right)
if __name__ == '__main__':
main()

View File

@ -1,72 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class BT(object):
def __init__(self, value):
self.value = value
self.left = None
self.right = None
def get_right(self):
return self.right
def get_left(self):
return self.left
def is_leaf(self):
return self.left is None and self.right is None
def set_root(self, obj):
self.value = obj
def get_root(self):
return self.value
def insert_left(self, new_node):
if self.left == None:
self.left = BT(new_node)
else:
t = BT(self.left)
t.left = new_node
self.left = t
def insert_right(self, new_node):
if self.right == None:
self.right = BT(new_node)
else:
t = BT(self.right)
t.right = new_node
self.right = t
def __repr__(self):
return '{}'.format(self.value)
def tests_BT():
"""
1
2 3
4 5 6 7
"""
tree = BT(1)
tree.insert_left(2)
tree.insert_right(3)
tree.get_left().insert_left(4)
tree.get_left().insert_right(5)
tree.get_right().insert_left(6)
tree.get_right().insert_right(7)
assert(tree.get_right().get_right() == str(7))
tree.get_right().get_right().set_root(8)
assert(tree.get_right().get_right() == str(8))
assert(tree.get_right().is_leaf() == False)
assert(tree.get_right().get_right().is_leaf() == True)
print("Tests Passed!")
if __name__ == '__main__':
tests_BT()

View File

@ -1,22 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class BunchClass(dict):
def __init__(self, *args, **kwds):
super(BunchClass, self).__init__(*args, **kwds)
self.__dict__ = self
def main():
bc = BunchClass # notice the absence of ()
tree = bc(left = bc(left="Buffy", right="Angel"), right = bc(left="Willow", right="Xander"))
print(tree)
if __name__ == '__main__':
main()

View File

@ -1,27 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class SimpleTree(object):
def __init__(self, value, children = None):
if children == None: children = []
self.children = children
self.value = value
def __repr__(self, level=0):
ret = "\t"*level+repr(self.value)+"\n"
for child in self.children:
ret += child.__repr__(level+1)
return ret
def main():
st = SimpleTree('a', [SimpleTree('b', [SimpleTree('d'), SimpleTree('e')] ), SimpleTree('c', [SimpleTree('h'), SimpleTree('g')]) ])
print(st)
if __name__ == '__main__':
main()

View File

@ -1,52 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from BST_traversal import TranversalBST
def find_ancestor(path, low_value, high_value):
''' find the lowest ancestor in a BST '''
while path:
current_value = path[0]
if current_value < low_value:
try:
path = path[2:]
except:
return current_value
elif current_value > high_value:
try:
path = path[1:]
except:
return current_value
elif low_value <= current_value <= high_value:
return current_value
return None
def test_find_ancestor():
"""
10
5 15
1 6 11 50
"""
t = TranversalBST()
l1 = [10, 5, 15, 1, 6, 11, 50]
for i in l1: t.insert(i)
path = t.preorder()
assert(find_ancestor(path, 1, 6) == 5)
assert(find_ancestor(path, 1, 11) == 10)
assert(find_ancestor(path, 11, 50) == 15)
assert(find_ancestor(path, 5, 15) == 10)
path = t.inorder()
print(path)
assert(find_ancestor(path, 1, 6) == 5)
assert(find_ancestor(path, 1, 11) == 10)
assert(find_ancestor(path, 11, 50) == 15)
assert(find_ancestor(path, 5, 15) == 10)
print("Tests passsed!")
if __name__ == '__main__':
test_find_ancestor()

View File

@ -1,88 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from BST import BST
class TranversalBST(object):
def __init__(self):
self.bst = BST(None)
self.nodes = []
def insert(self, value):
if not self.bst.value:
self.bst.value = value
else:
self.bst.insert(value)
def contains(self, value):
return bool(self.bst.find(value))
def get(self, index):
for i, value in enumerate(self.inorder()):
if i == index:
return value
def inorder(self):
current = self.bst
self.nodes = []
stack = []
while len(stack) > 0 or current is not None:
if current is not None:
stack.append(current)
current = current.left
else:
current = stack.pop()
self.nodes.append(current.value)
current = current.right
return self.nodes
def preorder(self):
self.nodes = []
stack = [self.bst]
while len(stack) > 0:
curr = stack.pop()
if curr is not None:
self.nodes.append(curr.value)
stack.append(curr.right)
stack.append(curr.left)
return self.nodes
def preorder2(self):
self.nodes = []
current = self.bst
stack = []
while len(stack) > 0 or current is not None:
if current is not None:
self.nodes.append(current.value)
stack.append(current)
current = current.left
else:
current = stack.pop()
current = current.right
return self.nodes
def main():
"""
10
5 15
1 6 11 50
"""
t = TranversalBST()
t.insert(10)
t.insert(5)
t.insert(15)
t.insert(1)
t.insert(6)
t.insert(11)
t.insert(50)
print(t.preorder1())
print(t.preorder())
print(t.inorder())
if __name__ == '__main__':
main()

View File

@ -1,94 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from BST_traversal import TranversalBST
class BSTwithExtra(TranversalBST):
def __init__(self):
self.bst = BST(None)
self.nodes = []
def get_inorder(self, k):
for i, value in enumerate(self.inorder()):
if value == k:
return i
def get_preorder(self, k):
for i, value in enumerate(self.preorder()):
if value == k:
return i
def is_balanced(self, threshold=1):
maxd = self.get_max_depth()
mind = self.get_min_depth()
print('Max depth: ' + str(maxd))
print('Min depth: ' + str(mind))
return maxd -mind
def get_min_depth(self, node=None, initial=1):
if node is None and initial == 1:
node = self.bst
if node.left and node.right:
return 1 + min(self.get_min_depth(node.left, 0),
self.get_min_depth(node.right, 0))
else:
if node.left:
return 1 + self.get_max_depth(node.left, 0)
elif node.right:
return 1 + self.get_max_depth(node.right, 0)
else:
return 0
def get_max_depth(self, node=None, initial=1):
if node is None and initial == 1:
node = self.bst
if node.left and node.right:
return 1 + max(self.get_max_depth(node.left, 0),
self.get_max_depth(node.right, 0))
else:
if node.left:
return 1 + self.get_max_depth(node.left, 0)
elif node.right:
return 1 + self.get_max_depth(node.right, 0)
else:
return 0
def main():
"""
10
5 15
1 6 11 50
60
70
80
"""
t = BSTwithExtra()
l1 = [10, 5, 15, 1, 6, 11, 50, 60, 70, 80]
for i in l1: t.insert(i)
print(t.inorder())
print(t.preorder())
assert(t.get_max_depth() == 5)
assert(t.get_min_depth() == 2)
assert(t.is_balanced() == 3)
assert(t.get_inorder(10) == 3)
assert(t.get_preorder(10) == 0)
"""
1
2 3
4 5 6 7
"""
t2 = BSTwithExtra()
l2 = [1, 2, 3, 4, 5, 6, 7, 8]
for i in l2: t2.insert(i)
print(t2.inorder())
print(t2.preorder())
assert(t2.is_balanced() == 0)
print("Tests Passed!")
if __name__ == '__main__':
main()

View File

@ -1,100 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from BST_with_Nodes import BSTwithNodes, Node
class TraversalBSTwithNodes(BSTwithNodes):
def __init__(self):
self.root = None
def BFS(self):
self.root.level = 0
queue = [self.root]
out = []
current_level = self.root.level
while len(queue) > 0:
current_node = queue.pop(0)
if current_node.level > current_level:
current_level += 1
out.append("\n")
out.append(str(current_node.value) + " ")
if current_node.left:
current_node.left.level = current_level + 1
queue.append(current_node.left)
if current_node.right:
current_node.right.level = current_level + 1
queue.append(current_node.right)
print("".join(out))
def inorder(self, node):
if node is not None:
self.inorder(node.left)
print(node.value)
self.inorder(node.right)
def preorder(self, node):
if node is not None:
print(node.value)
self.preorder(node.left)
self.preorder(node.right)
def postorder(self, node):
if node is not None:
self.postorder(node.left)
self.postorder(node.right)
print(node.value)
def inorder2(self, node):
if node.left is not None:
self.inorder2(node.left)
print(node.value)
if node.right is not None:
self.inorder2(node.right)
def postorder2(self, node):
if node.left is not None:
self.inorder2(node.left)
if node.right is not None:
self.inorder2(node.right)
print(node.value)
def preorder2(self, node):
print(node.value)
if node.left is not None:
self.inorder2(node.left)
if node.right is not None:
self.inorder2(node.right)
def main():
tree = TraversalBSTwithNodes()
l1 = [10, 5, 15, 1, 6, 11, 50]
for i in l1: tree.insert(i)
print('Breadth-First Traversal:')
tree.BFS()
print('Inorder Traversal:')
tree.inorder(tree.root)
tree.inorder2(tree.root)
print('Preorder Traversal:')
tree.preorder(tree.root)
tree.preorder2(tree.root)
print('Postorder Traversal:')
tree.postorder(tree.root)
tree.postorder2(tree.root)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,25 @@
#!/usr/bin/python3
# mari von steinkirch @2014
# steinkirch at gmail
# for hacker school application
'''
Write a program that prints out the numbers 1 to 100 (inclusive). If the number is divisible by 3, print Crackle instead of the number. If it's divisible by 5, print Pop. If it's divisible by both 3 and 5, print CracklePop.
'''
def CracklePop(n):
for i in range(1, n+1):
if i%3 == 0 and i%5 == 0: print('CracklePop!!!')
elif i%3 == 0: print("Crackle!!!")
elif i%5 == 0: print("Pop!!!")
else: print(i)
def main():
CracklePop(100)
if __name__ == '__main__':
main()

View File

@ -1,45 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
'''
The fraction 49/98 is a curious fraction, as an inexperienced mathematician in attempting to simplify it may incorrectly believe that 49/98 = 4/8, which is correct, is obtained by cancelling the 9s.
We shall consider fractions like, 30/50 = 3/5, to be trivial examples.
There are exactly four non-trivial examples of this type of fraction, less than one in value, and containing two digits in the numerator and denominator.
If the product of these four fractions is given in its lowest common terms, find the value of the denominator.
'''
def find_sum_proper_divisors(n):
sum_proper_div = 0
for i in range(1, n):
if n%i == 0:
sum_proper_div += i
return sum_proper_div
def amicable_numbers(N):
sum_div_list = [find_sum_proper_divisors(i) for i in range(1, N+1)]
sum_amicable_numbers = 0
set_div = set()
for a in range(1, N):
da = sum_div_list[a-1]
if da < N:
b = da
db = sum_div_list[b-1]
if a != b and db == a and a not in set_div and b not in set_div:
sum_amicable_numbers += a + b
set_div.add(a)
set_div.add(b)
return sum_amicable_numbers
def main():
print(amicable_numbers(10000))
print('Tests Passed!')
if __name__ == '__main__':
main()

View File

@ -1,76 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
# very dumb version, need to be optimized
'''
We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once; for example, the 5-digit number, 15234, is 1 through 5 pandigital.
The product 7254 is unusual, as the identity, 39 x186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital.
Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.
HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum.
'''
def is_pandigital(n):
size = len(n)
pan = set([x for x in range(1,size + 1)])
for i in n:
if int(i) in pan:
pan = pan - {int(i)}
else:
return False
return True
def find_multiples(n):
multiples = set([1, n])
for i in range(2, n):
if n%i == 0:
multiples.add(i)
multiples.add(n//i)
return multiples
def find_pandigital():
sum_pan = 0
for i in range(10, 987654322):
if i//10 == 0:
continue
digits = set(str(i))
if len(digits) != len(str(i)):
continue
multiples = find_multiples(i)
mult_set = set()
for j in multiples:
for c in str(j):
if c in digits or int(c) == 0:
continue
for c in str(j):
mult_set.add(c)
k = i//j
for c in str(k):
if c in digits or int(c) == 0:
continue
for c in str(k):
mult_set.add(c)
if len(mult_set ) == 9:
sum_pan += j + k + i
return sum_pan
def main():
assert(is_pandigital('15234') == True )
assert(is_pandigital('15233') == False )
print(find_pandigital())
print('Tests Passed!')
if __name__ == '__main__':
main()

View File

@ -1,73 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
'''
We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once; for example, the 5-digit number, 15234, is 1 through 5 pandigital.
The product 7254 is unusual, as the identity, 39 x186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital.
Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.
HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum.
'''
def is_pandigital(n):
size = len(n)
pan = set([x for x in range(1,size + 1)])
for i in n:
if int(i) in pan:
pan = pan - {int(i)}
else:
return False
return True
def find_multiples(n):
multiples = set([1, n])
for i in range(2, n):
if n%i == 0:
multiples.add(i)
multiples.add(n//i)
return multiples
def find_pandigital():
sum_pan = 0
for i in range(10, 987654322):
if i//10 == 0:
continue
digits = set(str(i))
if len(digits) != len(str(i)):
continue
multiples = find_multiples(i)
mult_set = set()
for j in multiples:
for c in str(j):
if c in digits or int(c) == 0:
continue
for c in str(j):
mult_set.add(c)
k = i//j
for c in str(k):
if c in digits or int(c) == 0:
continue
for c in str(k):
mult_set.add(c)
if len(mult_set ) == 9:
sum_pan += j + k + i
return sum_pan
def main():
assert(is_pandigital('15234') == True )
assert(is_pandigital('15233') == False )
print(find_pandigital())
print('Tests Passed!')
if __name__ == '__main__':
main()

View File

@ -1,28 +0,0 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def path_sum_two_ways(m1):
paths = []
row, col = 0, 0
p = len(m1)
while row < len(m1):
print(m1[0:p])
while p:
aux = sum([x for x in m1[0:p]])
paths.append(aux)
p -= 1
row += 1
return max(paths)
def main():
m1 = [[131, 673, 234, 103, 18], [201, 96, 342, 965, 150], [630, 803, 746, 422, 111], [537, 699, 497, 121, 956], [805, 732, 524, 37, 331]]
print(path_sum_two_ways(m1))
if __name__ == '__main__':
main()