diff --git a/main.py b/main.py index 24deec5e85617c2cb0deb1a984eaac4a457b00f2..897b3677b6585de36940d0dfe7c4323434cb5d08 100755 --- a/main.py +++ b/main.py @@ -1,14 +1,18 @@ #!/usr/bin/python3 -""" Find beginning of overlapping list """ -""" Wrote my own linked list for this. There is no error checking and all +""" Find beginning of overlapping list +Wrote my own linked list for this. There is no error checking and all assumptions are optimistic. This may be a fun project to flesh out with -some exception handling and proper error checking. """ +some exception handling and proper error checking. +""" class Node: """ The node will be the basis of a singly linked list """ - def __init__(self, val, next=None): - self.val = str(val); - self.next = next + def __init__(self, val, next_node=None): + self.val = val + self.next = next_node + + def __str__(self): + return str(self.val) class LList: @@ -17,97 +21,79 @@ class LList: self.head = head self.current = head - def rewind(self): - """ return current pointer to the head of the list """ + def __iter__(self): self.current = self.head - return self.current + return self - def next(self): - """ advance the current pointer """ + def __next__(self): + temp = self.current + if not temp: + raise StopIteration self.current = self.current.next - return self.current - - def show(self): - """ ouput in list format a linked list """ - n = self.head - print("[", end = '') - comma = '' - while n: - print(comma, n.val if n.val[0] != '~' else n.val[1:], end = '') - comma = ',' - n = n.next - print(" ]") - - def reverse(self): - """ reverse a list in place """ - prev = None - n = self.head - while n: - temp = n.next - n.next = prev - prev = n - n = temp - if n: - self.head = n + return temp + + def __str__(self): + return '[ ' + ' -> '.join([str(node) for node in self]) + ' ]' def main(): """ Main driver create lists, reverse them, find beginning overlap """ # This is just setup - cnode = Node(8,Node(10)) - mlist = LList(Node(3,Node(7,cnode))) - nlist = LList(Node(99,Node(1,cnode))) + cnode = Node(8, Node(10)) + mlist = LList(Node(3, Node(7, cnode))) + nlist = LList(Node(99, Node(1, cnode))) + +# nlist = LList(Node(99,Node(1))) +# +# cnode = Node(3, Node(7, Node(8, Node(10)))) +# mlist = LList(cnode) +# nlist = LList(cnode) - mlist.show() - nlist.show() + print(mlist) + print(nlist) + non_destructive_find(mlist, nlist) + destructive_find(mlist, nlist) - # solution using 2 "pointers" solves the O(m+n) in constant space - # aspect of the problem. + +def non_destructive_find(mlist, nlist): + """" + solution using 2 "pointers" solves the O(m+n) in constant space + aspect of the problem. + """ mwalker = mlist.head nwalker = nlist.head - while mwalker.val != nwalker.val: + count_rollovers = 0 + while mwalker != nwalker: mwalker = mwalker.next nwalker = nwalker.next if not mwalker: mwalker = nlist.head + count_rollovers += 1 if not nwalker: - nwalker = mlist.heead - print("The overlap = ", nwalker.val); - - # Getting the actual list, though not part of the problem - # is pretty much free - print("The overlap list is:", end ='') - LList(nwalker).show(); - - # this solution is partially destructive in that it - # modifies the val. For this I changed it to a string - # and added a ~ to ones visited in one list. when traversing - # the other list finding the ~ shows the overlap. The show() - # was modified to not show the ~. Certainly a cleanup could be - # employed to go through an remove all the ~. - # This is also O(n+m) - mnode = mlist.rewind() - while mnode: - mnode.val = "~" + str(mnode.val) - mnode = mnode.next - - nnode = nlist.rewind() - while nnode.val[0] != '~': - nnode = nlist.next() - overlap = nnode - print("The overlap = ", overlap.val[1:]) - print("The overlap list : ", end ='') - LList(overlap).show() - - - - # this solution is destructive as it sets - # all the "next" pointers to None so once the - # overlap is found you are done, but you no longer - # have the rest of the list - mnode = mlist.rewind() + nwalker = mlist.head + count_rollovers += 1 + if count_rollovers > 2: + print("There was no overlap") + break + else: + print("The overlap = ", nwalker) + + # Getting the actual list, though not part of the problem + # is pretty much free + print("The overlap list is:", end='') + print(LList(nwalker)) + + +def destructive_find(mlist, nlist): + """ + this solution is destructive as it sets + all the "next" pointers to None so once the + overlap is found you are done, but you no longer + have the rest of the list + """ + mnode = mlist.head while mnode: temp = mnode.next mnode.next = None @@ -115,16 +101,15 @@ def main(): # constant space # O(m+n) time - nnode = nlist.rewind() overlap = None - while nnode.next: - nnode = nlist.next() - overlap = nnode + for overlap in nlist: + pass + - print("The overlap = ", overlap.val[1:]) - print("The overlap list : ", end ='') - LList(overlap).show() + print("The overlap = ", overlap.val) + print("The overlap list : ", end='') + print(LList(overlap)) if __name__ == "__main__":