Example #1
0
class TestIntersection(unittest.TestCase):
    def setUp(self):
        # Case without intersection
        self.a = SinglyLinkedList()
        self.b = SinglyLinkedList()
        self.b.append(1)
        self.b.append(2)

        # Case with intersection
        self.n1 = Node(1)
        self.n2 = Node(2)
        self.n1.next = self.n2

        self.c = SinglyLinkedList()
        self.c.append('not a match')
        self.c.head.next = self.n1
        self.d = SinglyLinkedList()
        self.d.head = self.n1

    def test_intersection(self):
        self.assertIsNone(intersection(self.a, self.b))  # no intersection
        self.assertEqual(intersection(self.c, self.d), self.n1)  # intersection

    def test_intersection_fast(self):
        self.assertIsNone(intersection_fast(self.a, self.b))  # no intersection
        self.assertEqual(intersection_fast(self.c, self.d),
                         self.n1)  # intersection
Example #2
0
def sum_lists_reverse(*args):
    """
    Sums singly linked lists. Each node is a digit stored in reverse order.

    :param args: SinglyLinkedLists to be summed.
    :return SinglyLinkedList: sum of inputs
    """
    sum_list = SinglyLinkedList()
    nodes = list(map(lambda x: x.head, args))  # head node of each SinglyLinkedList
    carryover = 0

    while True:
        # Sum data from each list
        summation = carryover
        for i, node in enumerate(nodes):
            if node is None:
                continue
            summation += node.data
            nodes[i] = node.next

        # Account for addition carryover
        carryover, summation = divmod(summation, 10)
        sum_list.append(summation)

        # Check for end of all lists
        if all(map(lambda x: x is None, nodes)) and carryover == 0:
            break

    return sum_list
Example #3
0
def sum_lists_forward(*args):
    """
    Sums singly linked lists. Each node is a digit stored in forward order.

    :param args: SinglyLinkedLists to be summed.
    :return SinglyLinkedList: sum of inputs
    """
    #TODO: move some of this logic to other functions. Too wordy / complex.
    sum_list = SinglyLinkedList()

    # pad lists
    lengths = list(map(len, args))
    max_length = max(lengths)
    for i, arg in enumerate(args):
        pad_linked_list(arg, max_length - lengths[i])

    # sum lists
    nodes = list(map(lambda x: x.head, args))
    while True:
        # Sum data from each list
        summation = 0
        for i, node in enumerate(nodes):
            summation += node.data
            nodes[i] = node.next
        sum_list.append(summation)

        # Check if the end of a list is reached (all lists are the same length)
        if node.next is None:
            break

    # account for carryover
    while True:
        exit_flag = True
        runner = sum_list.head
        while runner.next is not None:
            carry, keep = divmod(runner.next.data, 10)
            runner.data += carry
            runner.next.data = keep
            runner = runner.next
            if carry > 0:
                exit_flag = False

        # check that head value isn't >=10
        carry, keep = divmod(sum_list.head.data, 10)
        if carry > 0:
            sum_list.head.data = keep
            pad_linked_list(sum_list, 1, value=carry)
            exit_flag = False

        if exit_flag:
            break

    return sum_list
Example #4
0
    def setUp(self):
        # setUp for remove_dups:
        #
        # SinglyLinkedList with duplicates
        self.sll = SinglyLinkedList()
        linked_list_data = [1, 1, 2, 3, 2, 3, ['abc'], ['abc']]
        for data in linked_list_data:
            self.sll.append(data)

        # Solution (duplicates removed)
        self.sll_solution = SinglyLinkedList()  # solution for non-hashable case
        linked_list_solution_data = [1, 2, 3, ['abc']]
        for data in linked_list_solution_data:
            self.sll_solution.append(data)

        # setUp for remove_dups_hashable:
        #
        # SinglyLinkedList with hashable data
        self.sll_hashable = SinglyLinkedList()
        hashable_linked_list_data = [1, 1, 2, 3, 2, 3, ('abc', 'def'), ('abc', 'def')]
        for data in hashable_linked_list_data:
            self.sll_hashable.append(data)

        # Hashable solution (duplicates removed)
        self.sll_hashable_solution = SinglyLinkedList()  # solution for non-hashable case
        linked_list_solution_data = [1, 2, 3, ('abc', 'def')]
        for data in linked_list_solution_data:
            self.sll_hashable_solution.append(data)
Example #5
0
    def setUp(self):
        # No loop
        self.a = SinglyLinkedList()
        self.a.append(1)
        self.a.append(2)
        self.a.append(3)

        # Empty list (no loop)
        self.b = SinglyLinkedList()

        # Loop
        self.c = SinglyLinkedList()
        self.n1 = Node(1)
        self.n2 = Node(2)
        self.n3 = Node(3)
        self.n1.next = self.n2
        self.n2.next = self.n3
        self.n3.next = self.n1
        self.c.append('not part of loop')
        self.c.append('also not part of loop')
        self.c.head.next.next = self.n1
Example #6
0
    def test_k_to_last(self):
        # Create SinglyLinkedList
        sll = SinglyLinkedList()
        sll.append(1)
        sll.append(2)
        sll.append(3)
        sll.append(4)

        # Find last element
        data = k_to_last(sll, 1)
        self.assertEqual(data, 4)

        # Find 2nd to last element
        data = k_to_last(sll, 2)
        self.assertEqual(data, 3)

        # Find first element
        data = k_to_last(sll, 4)
        self.assertEqual(data, 1)

        # Check if it raises ValueError when k > len(sll)
        self.assertRaises(ValueError, k_to_last, sll, 10)

        # Check if it raises ValueError when k = 0
        self.assertRaises(ValueError, k_to_last, sll, 0)
Example #7
0
    def test_partition(self):
        # Create SinglyLinkedList
        sll = SinglyLinkedList()
        for i in [3, 5, 8, 5, 10, 2, 1]:
            sll.append(i)

        # Solution
        solution = SinglyLinkedList()
        for i in [3, 2, 1, 5, 8, 5, 10]:
            solution.append(i)

        # Check if partition produces the solution
        partition(sll, 5)
        self.assertEqual(solution, sll)
Example #8
0
class TestRemoveDups(unittest.TestCase):

    def setUp(self):
        # setUp for remove_dups:
        #
        # SinglyLinkedList with duplicates
        self.sll = SinglyLinkedList()
        linked_list_data = [1, 1, 2, 3, 2, 3, ['abc'], ['abc']]
        for data in linked_list_data:
            self.sll.append(data)

        # Solution (duplicates removed)
        self.sll_solution = SinglyLinkedList()  # solution for non-hashable case
        linked_list_solution_data = [1, 2, 3, ['abc']]
        for data in linked_list_solution_data:
            self.sll_solution.append(data)

        # setUp for remove_dups_hashable:
        #
        # SinglyLinkedList with hashable data
        self.sll_hashable = SinglyLinkedList()
        hashable_linked_list_data = [1, 1, 2, 3, 2, 3, ('abc', 'def'), ('abc', 'def')]
        for data in hashable_linked_list_data:
            self.sll_hashable.append(data)

        # Hashable solution (duplicates removed)
        self.sll_hashable_solution = SinglyLinkedList()  # solution for non-hashable case
        linked_list_solution_data = [1, 2, 3, ('abc', 'def')]
        for data in linked_list_solution_data:
            self.sll_hashable_solution.append(data)

    def test_remove_dups(self):
        # Test remove_dups function
        self.assertNotEqual(self.sll, self.sll_solution)
        remove_dups(self.sll)
        self.assertEqual(self.sll, self.sll_solution)

    def test_remove_dups_hashable(self):
        # Test remove_dups hashable function
        # Requires hashable data
        self.assertNotEqual(self.sll_hashable, self.sll_hashable_solution)
        remove_dups_hashable(self.sll_hashable)
        self.assertEqual(self.sll_hashable, self.sll_hashable_solution)
Example #9
0
class TestLoopDetection(unittest.TestCase):
    def setUp(self):
        # No loop
        self.a = SinglyLinkedList()
        self.a.append(1)
        self.a.append(2)
        self.a.append(3)

        # Empty list (no loop)
        self.b = SinglyLinkedList()

        # Loop
        self.c = SinglyLinkedList()
        self.n1 = Node(1)
        self.n2 = Node(2)
        self.n3 = Node(3)
        self.n1.next = self.n2
        self.n2.next = self.n3
        self.n3.next = self.n1
        self.c.append('not part of loop')
        self.c.append('also not part of loop')
        self.c.head.next.next = self.n1

    def test_loop_detection(self):
        # No loop
        self.assertIsNone(loop_detection(self.a))

        # Empty list (no loop)
        self.assertIsNone(loop_detection(self.b))

        # Loop
        self.assertIs(loop_detection(self.c), self.n1)

    def test_loop_detection_fast(self):
        # No loop
        self.assertIsNone(loop_detection_fast(self.a))

        # Empty list (no loop)
        self.assertIsNone(loop_detection_fast(self.b))

        # Loop
        self.assertIs(loop_detection_fast(self.c), self.n1)
Example #10
0
    def setUp(self):
        # Case without intersection
        self.a = SinglyLinkedList()
        self.b = SinglyLinkedList()
        self.b.append(1)
        self.b.append(2)

        # Case with intersection
        self.n1 = Node(1)
        self.n2 = Node(2)
        self.n1.next = self.n2

        self.c = SinglyLinkedList()
        self.c.append('not a match')
        self.c.head.next = self.n1
        self.d = SinglyLinkedList()
        self.d.head = self.n1
Example #11
0
    def test_delete_middle_node(self):
        # Create SinglyLinkedList
        sll = SinglyLinkedList()
        sll.append(1)
        sll.append(2)
        sll.append(3)
        sll.append(4)

        # Solution
        solution = SinglyLinkedList()
        solution.append(1)
        solution.append(3)
        solution.append(4)

        # Check if delete_middle_node produces the solution
        node = sll.head.next  # node 2
        delete_middle_node(node)
        self.assertEqual(solution, sll)
Example #12
0
    def test_palindrome(self):
        # Case 1: (1, 2, 3, 2, 1) = Palindrome (True)
        p = SinglyLinkedList()
        p.append(1)
        p.append(2)
        p.append(3)
        p.append(2)
        p.append(1)
        self.assertTrue(palindrome(p))

        # Case 2: (1) = Palindrome (True)
        p = SinglyLinkedList()
        p.append(1)
        self.assertTrue(palindrome(p))

        # Case 3: (9, 9) = Palindrome (True)
        p = SinglyLinkedList()
        p.append(9)
        p.append(9)
        self.assertTrue(palindrome(p))

        # Case 4: ('a', 'b', 'c', 'a') != Palindrome (False)
        p = SinglyLinkedList()
        p.append('a')
        p.append('b')
        p.append('c')
        p.append('a')
        self.assertTrue(palindrome(p))

        # Case 5 (empty case): () = Palindrome (True)
        self.assertTrue(palindrome(SinglyLinkedList()))