def test_is_palindrome(func, llist):
    ll = LinkedList()
    ll.generate_nodes(llist.value)
    result = func(ll)
    assert result is llist.expected, (
        f"{func.__name__} with '{llist.value}' as input returned {result}, "
        f"but {llist.expected} expected")
Пример #2
0
def sum_lists_followup2(llist1, llist2):
    """
    Algorithmic solution using base 10.

    :param llist1: First linked list.
    :param llist2: Second linked list.
    :return: Reversed sum of linked lists' reversed numbers.
    """
    len_l1, len_l2 = len(llist1), len(llist2)
    if len_l1 > len_l2:
        for i in range(len_l1 - len_l2):
            llist2.add_to_beginning(Node(0))
    else:
        for i in range(len_l2 - len_l1):
            llist1.add_to_beginning(Node(0))
    power = len(
        llist1
    ) - 1  # take any of two as we equalized length by filling with zeros the shorter list
    head1, head2 = llist1.head, llist2.head

    sum_ = 0
    while head1 is not None and head2 is not None:
        sum_ = sum_ + head1.data * (10**power) + head2.data * (10**power)
        power -= 1
        head1, head2 = head1.next_node, head2.next_node

    result_ll = LinkedList()
    result_ll.generate_nodes(int(n) for n in str(sum_))
    return result_ll
Пример #3
0
def test_add_to_end_when_head_is_none():
    llist = LinkedList()
    appended_node = Node("a")
    llist.add_to_end(appended_node)
    assert llist.head == appended_node, (
        f"After appending node {appended_node} to empty list its head must change to "
        f"{appended_node}")
    assert llist.head.next_node is None, "Next node of head now should be None"
Пример #4
0
def test_add_to_beginning_when_head_is_none():
    llist = LinkedList()
    inserted_node = Node("a")
    llist.add_to_beginning(inserted_node)
    assert llist.head == inserted_node, (
        f"After inserting node {inserted_node} to empty list its head must change to "
        f"{inserted_node}")
    assert llist.head.next_node is None, "Next node of head now should be None"
def test_kth_to_the_last(func, llist):
    ll = LinkedList()
    ll.generate_nodes(llist.input_list)

    result = func(ll, llist.k)
    assert result == llist.expected, (
        f"{func.__name__} with '{llist.input_list}-{llist.k}' as input returned {result}, "
        f"but {llist.expected} expected"
    )
def looped_llist():
    ll = LinkedList()
    ll.generate_nodes("abcdefgh")

    loop_node = ll.head.next_node

    last = ll.head
    while last.next_node is not None:
        last = last.next_node

    last.next_node = loop_node  # Append to last node loop node
    return ll, loop_node
Пример #7
0
def sum_lists_followup(llist1, llist2):
    """
    Solution using type conversions.

    :param llist1: First linked list.
    :param llist2: Second linked list.
    :return: Reversed sum of linked lists' reversed numbers.
    """
    first_num = int("".join(str(n) for n in list(llist1)))
    second_num = int("".join(str(n) for n in list(llist2)))
    sum_ = [int(s) for s in list(str(first_num + second_num))]
    sum_llist = LinkedList()
    sum_llist.generate_nodes(sum_)
    return sum_llist
def _prepare_llists_for_test():
    """Prepare test data."""
    ll1, ll2 = LinkedList(), LinkedList()
    ll1.generate_nodes("defg")
    ll2.generate_nodes("abc")

    ll2.head.next_node.next_node = ll1.head  # intersect lists in the middle
    positive = [(ll1, ll2, ll1.head), (ll1, ll1, ll1.head)]

    neg_ll = LinkedList()
    neg_ll.generate_nodes("abc")
    negative = [(ll1, neg_ll, None), (ll2, neg_ll, None)]
    return positive + negative
Пример #9
0
def test_delete_middle_node(data_for_test):
    llist = LinkedList()
    llist.generate_nodes(data_for_test.begin_nodes)
    middle_node = Node(data_for_test.middle)
    llist.add_to_end(middle_node)
    llist.generate_nodes(data_for_test.end_nodes)
    delete_middle_node(middle_node)
    result = "".join(l.data for l in llist)
    assert result == data_for_test.expected, (
        f"Linked list: {data_for_test.begin_nodes}, remove node: {data_for_test.middle}' as input"
        f" produced '{result}', but '{data_for_test.expected}' expected")
Пример #10
0
def sum_lists2(llist1, llist2):
    """
    Algorithmic solution using divmod operation.

    :param llist1: First linked list.
    :param llist2: Second linked list.
    :return: Reversed sum of linked lists' reversed numbers.
    """
    head1, head2 = llist1.head, llist2.head
    result_ll = LinkedList()
    remainder = 0

    while head1 is not None or head2 is not None:
        result = remainder
        if head1 is not None:
            result += head1.data
            head1 = head1.next_node
        if head2 is not None:
            result += head2.data
            head2 = head2.next_node

        remainder, node_data = divmod(result, 10)
        result_ll.add_to_end(Node(node_data))

    if remainder:
        result_ll.add_to_end(Node(remainder))

    return result_ll
Пример #11
0
def do_partition(llist, partition):
    """
    Partition linked list around provided pivot. This implementation collects all nodes that
    are less than a pivot, and builds new partitioned linked list.

    :param llist: Instance of `LinkedList`.
    :param partition: Value of pivot to partition linked lists' smaller values
    :return: Partitioned linked list.
    """
    if llist.head is None:
        print("Cannot find in empty list")
        return llist

    less = more = None
    current = llist.head
    last_less = None  # needed to remember the last Node of less before None

    while current is not None:
        remembered_next = current.next_node
        if current.data < partition:
            if less is None:
                less = Node(current.data)
                last_less = less
            else:
                less, less.next_node = current, less
        else:
            if more is None:
                more = Node(current.data)
            else:
                more, more.next_node = current, more
        current = remembered_next

    last_less.next_node = more

    partitioned = LinkedList()
    partitioned.head = less
    return partitioned
def test_get_loop_node_negative():
    ll = LinkedList()
    ll.generate_nodes("abc")  # No loop
    assert detect_loop_node(ll) is None, "None expected, because there's no loop in the linked list"
Пример #13
0
def llist_data(request):
    ll_data, expected = request.param
    ll = LinkedList()
    ll.generate_nodes(ll_data)
    return ll, expected
Пример #14
0
def test_raises_when_remove_from_empty_list():
    with pytest.raises(ValueError) as err:
        LinkedList().remove_node("some-node")
        assert "List is empty!" in str(
            err), "Exception is expected about empty list"
Пример #15
0
def singly_llist():
    llist = LinkedList()
    llist.generate_nodes("abc")
    return llist
Пример #16
0
def followup_data(request):
    ll1, ll2 = LinkedList(), LinkedList()
    ll1.generate_nodes(request.param.ll1)
    ll2.generate_nodes(request.param.ll2)
    return ll1, ll2, request.param.expected
Пример #17
0
def llist_data(request):
    ll = LinkedList()
    ll.generate_nodes(request.param.llist)
    return ll, request.param.pivot