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
34 changes: 34 additions & 0 deletions names/bst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
class BinarySearchTree:
def __init__(self, value):
self.value = value
self.left = None
self.right = None

def insert(self, value):

if value >= self.value:
if self.right is not None:
self.right.insert(value)
else:
self.right = BinarySearchTree(value)

elif value < self.value:
if self.left is not None:
self.left.insert(value)
else:
self.left = BinarySearchTree(value)

def contains(self, target):
if self.value == target:
return True

if target > self.value:
if self.right is not None:
return self.right.contains(target)

elif target < self.value:
if self.left is not None:
return self.left.contains(target)

else:
return False
33 changes: 23 additions & 10 deletions names/names.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
import time
from bst import BinarySearchTree

start_time = time.time()

f = open('names_1.txt', 'r')
names_1 = f.read().split("\n") # List containing 10000 names
f.close()
with open('./names/names_1.txt', 'r') as f:
names_1 = f.read().split("\n") # List containing 10000 names
f.close()

f = open('names_2.txt', 'r')
names_2 = f.read().split("\n") # List containing 10000 names
f.close()
with open('./names/names_2.txt', 'r') as f:
names_2 = f.read().split("\n") # List containing 10000 names
f.close()

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_1 in names_1:
for name_2 in names_2:
if name_1 == name_2:
duplicates.append(name_1)
duplicates.append(name_1)'''

# not sure we could apply anything but a bst
bst = BinarySearchTree('duplicates')

for the_names in names_1:
bst.insert(the_names)

for the_names_2 in names_2:
if bst.contains(the_names_2):
duplicates.append(the_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")
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
Expand Down
18 changes: 17 additions & 1 deletion reverse/reverse.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def get_next(self):
def set_next(self, new_next):
self.next_node = new_next


class LinkedList:
def __init__(self):
self.head = None
Expand Down Expand Up @@ -39,4 +40,19 @@ def contains(self, value):
return False

def reverse_list(self, node, prev):
pass
if self.head == None: # empty list test
return None
else:
cur_node = self.head # take head node and save value
next_node = cur_node.next_node # set next node to current heads next node value
# set current heads or node next attribute to none as it will become tail in reverse
cur_node.set_next(None)
self.tail = cur_node # set tail to the cur node
while next_node is not None: # while we still have nodes in the list
prev_node = cur_node # prev or first node was our current
cur_node = next_node # set cur node to our saved next
next_node = cur_node.next_node # set our next to the currents next
# point node to the new tail or new node depending on loop
cur_node.set_next(prev_node)

self.head = cur_node # last node before loop breaks will now be our head
191 changes: 191 additions & 0 deletions ring_buffer/dll.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
class ListNode:
def __init__(self, value, prev=None, next=None):
self.prev = prev
self.value = value
self.next = next

def get_value(self):
return self.value

def get_next(self):
return self.next

def set_next(self, new_next):
self.next = new_next

def get_prev(self):
return self.prev

def set_prev(self, new_prev):
self.prev = new_prev

def delete_node(self):
if self.prev:
self.prev.next = self.next
if self.next:
self.next.prev = self.prev


"""
Our doubly-linked list class. It holds references to
the list's head and tail nodes.
"""


class DoublyLinkedList:
def __init__(self, node=None):
self.head = node
self.tail = node
self.length = 1 if node is not None else 0

def __len__(self):
return self.length

"""
Wraps the given value in a ListNode and inserts it
as the new head of the list. Don't forget to handle
the old head node's previous pointer accordingly.
"""

def add_to_head(self, value):
new_node = ListNode(value)
if not self.head and not self.tail: # our list is empty
self.head = new_node
self.tail = new_node
else:
# take current head and set its prev to the new node
self.head.set_prev(new_node)
# set the new nodes next to the current head
new_node.set_next(self.head)
self.head = new_node # set the head to the new node

self.length += 1

"""
Removes the List's current head node, making the
current head's next node the new head of the List.
Returns the value of the removed Node.
"""

def remove_from_head(self):
if not self.head and not self.tail:
return None
elif self.head == self.tail:
value_removed = self.head.get_value()
self.head = None
self.tail = None
self.length -= 1
return value_removed
else:
value_removed = self.head.get_value()
self.head = self.head.get_next()
self.head.prev = None
self.length -= 1
return value_removed

"""
Wraps the given value in a ListNode and inserts it
as the new tail of the list. Don't forget to handle
the old tail node's next pointer accordingly.
"""

def add_to_tail(self, value):
new_node = ListNode(value)
if not self.head and not self.tail:
self.head = new_node
self.tail = new_node
else:
self.tail.set_next(new_node)
new_node.set_prev(self.tail)
self.tail = new_node
self.length += 1

"""
Removes the List's current tail node, making the
current tail's previous node the new tail of the List.
Returns the value of the removed Node.
"""

def remove_from_tail(self):
if not self.tail and not self.head:
return None
elif self.head == self.tail:
value_removed = self.tail.get_value()
self.tail = None
self.head = None
self.length -= 1
return value_removed
else:
value_removed = self.tail.get_value()
self.tail = self.tail.get_prev()
self.tail.set_next(None)
self.length -= 1
return value_removed

"""
Removes the input node from its current spot in the
List and inserts it as the new head node of the List.
"""

def move_to_front(self, node):
self.delete(node)
self.add_to_head(node.value)

"""
Removes the input node from its current spot in the
List and inserts it as the new tail node of the List.
"""

def move_to_end(self, node):
self.delete(node)
self.add_to_tail(node.value)

"""
Deletes the input node from the List, preserving the
order of the other elements of the List.
"""

def delete(self, node):
if not self.tail and not self.head:
return None
elif self.tail == self.head:
self.tail = None
self.head = None

elif node.prev == None: # if the node is the head so i could say if node is self.head
node.next.prev = None
self.head = node.next
# node.delete_node()

elif node.next == None: # if node is the tail or 'if node is self.tail' which would have a next of none
node.prev.next = None
self.tail = node.prev
# node.delete_node()

else: # node in middle
node.prev.next = node.next
node.next.prev = node.prev
# node.delete_node()

self.length -= 1

"""
Finds and returns the maximum value of all the nodes
in the List.
"""

def get_max(self):
if not self.head and not self.tail:
return None
elif self.tail == self.head:
return self.head.get_value()
else:
currentMax = self.head.get_value()
theHead = self.head

while theHead.get_next() is not None:
neighborNode = theHead.get_next()
if neighborNode.get_value() > currentMax:
currentMax = neighborNode.get_value()
theHead = theHead.get_next()
return currentMax
45 changes: 42 additions & 3 deletions ring_buffer/ring_buffer.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,48 @@
from dll import DoublyLinkedList


class RingBuffer:
def __init__(self, capacity):
pass
self.capacity = capacity
self.storage = DoublyLinkedList()
self.tracking = None

def append(self, item):
pass
if len(self.storage) < self.capacity:
self.storage.add_to_tail(item)
self.tracking = self.storage.head
elif len(self.storage) == self.capacity:
value_to_delete = self.storage.head
self.storage.remove_from_head()
self.storage.add_to_tail(item)
if value_to_delete == self.tracking:
self.tracking = self.storage.tail

def get(self):
pass

buffer_list = []
tracking_node = self.tracking
buffer_list.append(tracking_node.value)

if tracking_node.next is not None:
another_node = tracking_node.next
else:
another_node = self.storage.head

while another_node is not tracking_node:
buffer_list.append(another_node.value)
if another_node.next is not None:
another_node = another_node.next
else:
another_node = self.storage.head

return buffer_list


r = RingBuffer(3)
r.append(1)
r.append(2)
r.append(3)
r.append(4)

print(r.get())