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
129 changes: 129 additions & 0 deletions names/binary_search_tree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
"""
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):
# take the current value of our node (self.value)
cur_val = self.value
# compare to the new value we want to insert

if value < cur_val:
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 self.value == target:
return True
if self.value > target:
if self.left is None:
return False
found = self.left.contains(target)

elif self.value <= target:
if self.right is None:
return False
found = self.right.contains(target)
return found

# Return the maximum value found in the tree
def get_max(self):
if self.right is None:
max_val = self.value
return max_val
elif self.right is not None:
if self.right.right is None:
max_val = self.right.value
return max_val
else:
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 is not None:
self.left.for_each(fn)
if self.right is not None:
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 self.left:
self.left.in_order_print(node)
print(self.value)
if self.right:
self.right.in_order_print(node)


# Print the value of every node, starting with the given node,
# in an iterative breadth first traversal
def bft_print(self, node):
queue = []
queue.append(node)
while len(queue) > 0:
first_node = queue.pop(0)
print(first_node.value)
if first_node.left:
queue.append(first_node.left)
if first_node.right:
queue.append(first_node.right)
return queue


# 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:
last_node = stack.pop()
print(last_node.value)
if last_node.left:
stack.append(last_node.left)
if last_node.right:
stack.append(last_node.right)
return stack

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

# Print Pre-order recursive DFT
def pre_order_dft(self, node):

print(self.value)
if self.left:
self.left.pre_order_dft(node)
if self.right:
self.right.pre_order_dft(node)

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

start_time = time.time()

Expand All @@ -13,16 +14,35 @@
duplicates = [] # Return the list of duplicates in this data structure

# 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)
# O(n^2)
# for name_1 in names_1:
# for name_2 in names_2:
# if name_1 == name_2:
# duplicates.append(name_1)

end_time = time.time()
print (f"{len(duplicates)} duplicates:\n\n{', '.join(duplicates)}\n\n")
print (f"runtime: {end_time - start_time} seconds")
# we need to traverse each list and compare the two lists, returning the dupes
# Append the items that exist in both lists to the duplicates list

# initialize BST with a placeholder node
# bst = BSTNode('placeholder')
# for name in names_1:
# bst.insert(name)

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

# 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
# structures, but you may not import any additional libraries that you did not write yourself.

duplicates = set(names_1).intersection(names_2)

end_time = time.time()
print (f"{len(duplicates)} duplicates:\n\n{', '.join(duplicates)}\n\n")
print (f"runtime: {end_time - start_time} seconds")
18 changes: 17 additions & 1 deletion reverse/reverse.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ class LinkedList:
def __init__(self):
self.head = None

def __str__(self):
output = ''
current_node = self.head
while current_node is not None:
output += f'{current_node.value} > '
current_node = current_node.next_node
return output + 'None'

def add_to_head(self, value):
node = Node(value)

Expand All @@ -39,4 +47,12 @@ def contains(self, value):
return False

def reverse_list(self, node, prev):
pass
# we'll need to reference the previous node
# traverse the list and when we get to the end, that node will become the new head
current = self.head
while current is not None:
self.next_node = current.next_node
current.next_node = prev
prev = current
current = self.next_node
self.head = prev
28 changes: 25 additions & 3 deletions ring_buffer/ring_buffer.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
class RingBuffer:
def __init__(self, capacity):
pass
self.capacity = capacity
self.buffer = []
self.oldest = None

def append(self, item):
pass
# if buffer is empty,
if len(self.buffer) == 0:
# add item to list and
self.buffer.append(item)
# make new item the "oldest"
self.oldest = item
return self.oldest
# if buffer is at capacity, replace oldest item with new item
elif len(self.buffer) == self.capacity:
# get the index of the oldest item
index_oldest = self.buffer.index(self.oldest)
# replace the oldest with the new item
self.buffer[index_oldest] = item
if (index_oldest+1) >= len(self.buffer):
self.oldest = self.buffer[0]
else:
self.oldest = self.buffer[index_oldest+1]
# if buffer is not at capacity, add item to end of buffer
elif len(self.buffer) < self.capacity:
self.buffer.append(item)
return item

def get(self):
pass
return self.buffer