Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 126 additions & 0 deletions names/bst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import random
"""
Binary search trees are a data structure that enforce an ordering over
the data they store. That ordering in turn makes it a lot more efficient
at searching for a particular piece of data in the tree.

This part of the project comprises two days:
1. Implement the methods `insert`, `contains`, `get_max`, and `for_each`
on the BSTNode class.
2. Implement the `in_order_print`, `bft_print`, and `dft_print` methods
on the BSTNode class.
"""
class BSTNode:
def __init__(self, value):
self.value = value
self.left = None
self.right = None

# Insert the given value into the tree
def insert(self, value):
if value < self.value:
if self.left is None:
self.left = BSTNode(value)
else:
self.left.insert(value)
else:
if self.right is None:
self.right = BSTNode(value)
else:
self.right.insert(value)

# Return True if the tree contains the value
# False if it does not
def contains(self, target):
if target == self.value:
return True
elif target < self.value:
if self.left:
return self.left.contains(target)
else:
return False
elif target > self.value:
if self.right:
return self.right.contains(target)
else:
return False

# Return the maximum value found in the tree
def get_max(self):
if self:
while self.right is not None:
self = self.right
return self.value

# recursive method
# if not self.right:
# return self.value
# return self.right.get_max()

# Call the function `fn` on the value of each node
def for_each(self, fn):
fn(self.value)

if self.left:
self.left.for_each(fn)
if self.right:
self.right.for_each(fn)

# Part 2 -----------------------

# Print all the values in order from low to high
# Hint: Use a recursive, depth first traversal
def in_order_print(self, node):
if node:
self.in_order_print(node.left)
print(node.value)
self.in_order_print(node.right)

# Print the value of every node, starting with the given node,
# in an iterative breadth first traversal
def bft_print(self, node):
from collections import deque

q = deque()
q.append(node)

while len(q) > 0:
current = q.popleft()

if current.left:
q.append(current.left)
if current.right:
q.append(current.right)
print(current.value)

# Print the value of every node, starting with the given node,
# in an iterative depth first traversal
def dft_print(self, node):
stack = []
stack.append(node)

while len(stack) > 0:
current = stack.pop()

if current.right:
stack.append(current.right)
if current.left:
stack.append(current.left)
print(current.value)

# Stretch Goals -------------------------
# Note: Research may be required

# Print Pre-order recursive DFT
def pre_order_dft(self, node):
if node:
print(node.value)
self.pre_order_dft(node.left)
self.pre_order_dft(node.right)

# Print Post-order recursive DFT
def post_order_dft(self, node):
if node:
self.post_order_dft(node.left)
self.post_order_dft(node.right)
print(node.value)
22 changes: 17 additions & 5 deletions names/names.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import time
from bst import BSTNode

start_time = time.time()

Expand All @@ -12,17 +13,28 @@

duplicates = [] # Return the list of duplicates in this data structure

# O(n) * O(n) -> O(n^2)
# Replace the nested for loops below with your improvements
for name_1 in names_1:
for name_2 in names_2:
if name_1 == name_2:
duplicates.append(name_1)
# for name_1 in names_1:
# for name_2 in names_2:
# if name_1 == name_2:
# duplicates.append(name_1)

# O(n) + O(n) -> O(2n)
bst = BSTNode("money")

for n in names_1:
bst.insert(n)

for n in names_2:
if bst.contains(n):
duplicates.append(n)

end_time = time.time()
print (f"{len(duplicates)} duplicates:\n\n{', '.join(duplicates)}\n\n")
print (f"runtime: {end_time - start_time} seconds")

# ---------- Stretch Goal -----------
# Python has built-in tools that allow for a very efficient approach to this problem
# What's the best time you can accomplish? Thare are no restrictions on techniques or data
# What's the best time you can accomplish? There are no restrictions on techniques or data
# structures, but you may not import any additional libraries that you did not write yourself.
11 changes: 10 additions & 1 deletion reverse/reverse.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,13 @@ def contains(self, value):
return False

def reverse_list(self, node, prev):
pass
if node is None:
return None

if node.next_node == None:
node.next_node = prev
self.head = node
return

self.reverse_list(node.next_node, node)
node.next_node = prev
13 changes: 10 additions & 3 deletions ring_buffer/ring_buffer.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
class RingBuffer:
def __init__(self, capacity):
pass
self.index = 0
self.capacity = capacity
self.storage = []

def append(self, item):
pass
if len(self.storage) == self.capacity:
self.storage[self.index] = item
else:
self.storage.append(item)

self.index = (self.index + 1) % self.capacity

def get(self):
pass
return self.storage