diff --git a/names/names.py b/names/names.py index ea158997f..ac9a55328 100644 --- a/names/names.py +++ b/names/names.py @@ -1,4 +1,5 @@ import time +from singly_linked_list import LinkedList start_time = time.time() @@ -13,10 +14,29 @@ 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) +# for name_1 in names_1: +# for name_2 in names_2: +# if name_1 == name_2: +# duplicates.append(name_1) + +######### +# Using comprehensions +# duplicates = [name for name in names_1 if name in names_2] + +######## +# Using Linked List + +# create a new list +names_1_list = LinkedList() + +# put names_1 in list +for name in names_1: + names_1_list.add_to_head(name) + +# Check to see if each item of list 2 is in list 1 +for name in names_2: + if names_1_list.contains(name): + duplicates.append(name) end_time = time.time() print (f"{len(duplicates)} duplicates:\n\n{', '.join(duplicates)}\n\n") @@ -24,5 +44,5 @@ # ---------- 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. diff --git a/names/singly_linked_list.py b/names/singly_linked_list.py new file mode 100644 index 000000000..b322a4327 --- /dev/null +++ b/names/singly_linked_list.py @@ -0,0 +1,131 @@ +class Node: + def __init__(self, value, next_node = None): + # value that the node is holding + self.value = value + + # ref to the next node in the chain + self.next_node = next_node + + def get_value(self): + ####### + # Method to get the value of a node + ######### + return self.value + + def get_next(self): + ####### + # Method to get the node's next_node + ######### + return self.next_node + + def set_next(self, new_next): + ####### + # Method to update the node's next_node to the new_next + ######### + self.next_node = new_next + +class LinkedList: + def __init__(self): + self.head = None + self.tail = None + + def add_to_head(self, value): + new_node = Node(value, self.head) + self.head = new_node + if self.head is None: + self.tail = new_node + + + def add_to_tail(self, value): + # wrap the value in a new Node + new_node = Node(value) + # check if the Linked List is empty + if self.head is None and self.tail is None: + # set the head and tail to the new node + self.head = new_node + self.tail = new_node + # otherwise the list must have at least one item in there + else: + # update the last node's "next_node" to the new node + self.tail.set_next(new_node) # (last node in chain).next = new_node + # update the "self.tail" to point to the new node that we just added + self.tail = new_node + + def remove_tail(self): + ############################################################ + # remove the last node in the chain and return its value + ############################################################ + # check for empty list + if self.head is None and self.tail is None: + # return None + return None + + # check if the list only has one item + if self.head == self.tail: + # store the value of the node that we are going to remove + value = self.head.get_value() + # remove the node + # set head and the tail to None + self.head = None + self.tail = None + # return the stored value + return value + # otherwise + else: + # store the value of the node that we are going to remove + value = self.tail.get_value() + # we need to set the "self.tail" to the second to last node + # we can only do this by traversing the whole list from beginning to end + + # starting from the head + current_node = self.head + + # keep iterating until the node after "current_node" is the tail + while current_node.get_next() != self.tail: + # keep looping + current_node = current_node.get_next() + # at the end of the iteration set "self_tail" to the current_node + self.tail = current_node + # set the new tail's "next_node" to None + self.tail.set_next(None) + # return Value + return value + + def remove_head(self): + # check for empty list + if self.head is None and self.tail is None: + # return None + return None + + # check if the list only has one item + if self.head == self.tail: + # store the value of the node that we are going to remove + value = self.head.get_value() + # remove the node + # set head and the tail to None + self.head = None + self.tail = None + # return the stored value + return value + # otherwise + else: + # store the old head's value + value = self.head.get_value() + # set self.head to old head's next + self.head = self.head.get_next() + # return the value + return value + + def contains(self, value): + if not self.head: + return False + + current = self.head + + while current: + if current.get_value() == value: + return True + + current = current.get_next() + + return False \ No newline at end of file diff --git a/reverse/reverse.py b/reverse/reverse.py index 6116252d1..d2a99a134 100644 --- a/reverse/reverse.py +++ b/reverse/reverse.py @@ -39,4 +39,27 @@ def contains(self, value): return False def reverse_list(self, node, prev): - pass + # Base Case if list is empty + if self.head is None: + return + + #swap previous and current + prev_node = None + current_node = self.head + + # Loop through all nodes + while current_node is not None: + # keep track of the next node + upcoming = current_node.get_next() + + #overwrite next node with previous + current_node.set_next(prev_node) + + #overwrite prev node with current + prev_node = current_node + + # overwrite current node with original next node + current_node = upcoming + + # make previous node the head + self.head = prev_node diff --git a/ring_buffer/ring_buffer.py b/ring_buffer/ring_buffer.py index 37e9fb0dd..1de95b44f 100644 --- a/ring_buffer/ring_buffer.py +++ b/ring_buffer/ring_buffer.py @@ -1,9 +1,32 @@ class RingBuffer: def __init__(self, capacity): - pass + self.capacity = capacity + self.structure = [] + self.structure_index = 0 def append(self, item): - pass + # fill array once + if len(self.structure) < self.capacity: + self.structure.append(item) + + else: + # make sure the index isn't the same size of capacity + if self.structure_index < self.capacity: + #remove the previous item + self.structure.pop(self.structure_index) + # add to the structure + self.structure.insert(self.structure_index, item) + #increase index by one + self.structure_index += 1 + else: + #reset to zero + self.structure_index = 0 + # remove from index + self.structure.pop(self.structure_index) + # add to the structure + self.structure.insert(self.structure_index, item) + #increase index by one + self.structure_index += 1 def get(self): - pass \ No newline at end of file + return self.structure \ No newline at end of file