def problem_2_5(node):
    """ Given a circular linked list, implement an algorithm which returns the
    node at the beginning of the loop.

    DEFINITION
    Circular linked list: A (corrupt) linked list in which a node’s next pointer
    points to an earlier node, so as to make a loop in the linked list.
    EXAMPLE
    input: A -> B -> C -> D -> E -> C [the same C as earlier]
    output: C

    SOLUTION:
    - start two node traversals, one moving one node at a time, the other two
    nodes at a time.
    - if they meet, then the list has a loop, otherwise no loop.
    - the place where they meet is k nodes aways from the start of the loop,
    where k is the number of nodes from the begining of the list to the start of the loop.
    - move one traverser on the begining of the list
    - move both traversers one node at a time until they meet, this is the start of the loop.
    """
    n1 = node # moves one node at a time.
    n2 = node # moves two nodes at a time.

    # Advance to the meeting point or reach the end of the list.
    while n1 != None:
        n1 = n1.next
        # This works all the time, we are given that the list has a loop.
        n2 = n2.next.next
        if n1 == n2:
            break

    # If either n1 or n2 are None, then we found no loop.
    if n1 == None or n2 == None:
        return None

    # Find the starting point of the loop.
    n1 = node # n2 is still in the point where they met.
    while n1 != n2:
        n1 = n1.next
        n2 = n2.next

    return n1