Beispiel #1
0
def make_depth_lists(tree):
    """
    Space: O(n)
    Time: O(n)
    :param tree:
    :return:
    """
    if tree.rchild is None and tree.lchild is None:
        return None

    q = Queue()
    level = 0
    q.enqueue((tree, level))
    depth_lists = dict()

    while not q.is_empty():
        node, level = q.dequeue()
        if depth_lists.get(level) is None:
            depth_lists[level] = Cons(node, None)
        else:
            depth_lists[level] = Cons(node, depth_lists[level])

        if node.rchild is not None:
            q.enqueue((node.rchild, level + 1))

        if node.lchild is not None:
            q.enqueue((node.lchild, level + 1))

    return depth_lists
Beispiel #2
0
def BFS(graph, s):
    '''
    Breadth-first search implementation:
    BFS is an algorithm for traversing or searching tree or graph data structures.
    It starts at the tree root and explores the neighbor nodes first, before moving to the next level neighbours.

    :param graph: the graph to be searched, nodes have to be integers
    :param s: the source node, where the search begins
    :return: ordered list of nodes of BFS traversal
    '''

    if graph.count_nodes() == 0:
        return []

    visited = []
    bfs_trav = []

    queue = Queue()
    queue.push(s)
    visited.append(s)

    while not queue.is_empty():
        current = queue.pop()
        bfs_trav.append(current)

        print(current)
        for n in graph[current]:

            if n not in visited:
                print('node: {}'.format(n))
                queue.push(n)
                visited.append(n)

    return bfs_trav
Beispiel #3
0
    def a_to_b(n1, n2):
        q = Queue()
        visited = {n1}
        q.enqueue(n1)

        while not q.is_empty():
            current = q.dequeue()
            if current == n2:
                return True
            for child in current.children:
                if child not in visited:
                    visited.add(child)
                    q.enqueue(child)
        return False
Beispiel #4
0
def sorted_merge(A: list, B: list):
    """
    Time: O(A + B) actually O(2A + 2B), copying then reading back, with O(min(A, B)) comparisons in the worst case
    Space: O(n)
    :param A:
    :param B:
    :return:
    """
    p1, p2 = 0, len(A) - len(B)

    stack_A = Queue(iterable=A[:p2])
    stack_B = Queue(iterable=B)

    for i in range(len(A)):
        if stack_A.is_empty():
            A[i] = stack_B.pop()
        elif stack_B.is_empty():
            A[i] = stack_A.pop()
        elif stack_A.peek() <= stack_B.peek():
            A[i] = stack_A.pop()
        else:
            A[i] = stack_B.pop()
    return A
Beispiel #5
0
def get_unique_adjacent(string: str) -> Optional[str]:
    length = len(string)
    freq = {}
    if length == 0:
        return string

    for i in range(length):
        if string[i] not in freq:
            freq[string[i]] = 0
        freq[string[i]] += 1

    sorted_freq = sorted(freq.items(), key=lambda x: x[1], reverse=True)
    queue = Queue()
    [queue.enqueue(item) for item in sorted_freq]
    result = ""

    if length % 2 == 0 and sorted_freq[0][1] > length // 2:
        return None
    elif length % 2 == 1 and sorted_freq[0][1] > (length // 2) + 1:
        return None

    while not queue.is_empty():
        if len(queue) == 1:
            elem, freq = queue.peek()
            if freq == 2:
                result = elem + result + elem
                break
            elif freq == 1:
                if result[-1] != elem:
                    result += elem
                else:
                    result = elem + result
                break
            return None

        elem1, freq1 = queue.peek()
        elem2, freq2 = None, None
        if len(queue) > 1:
            elem2, freq2 = queue[1]

        result += elem1 + elem2

        queue[0] = elem1, freq1 - 1
        if len(queue) > 1:
            queue[1] = elem2, freq2 - 1
        if len(queue) > 1 and queue[1][1] == 0:
            queue.dequeue()
        if len(queue) > 0 and queue[0][1] == 0:
            queue.dequeue()
    return result
def remove_island(matrix: Matrix, position: Position,
                  grid_shape: GridShape) -> None:
    # using bfs to remove the islands
    queue = Queue()
    queue.enqueue(position)

    while not queue.is_empty():
        curr_position = queue.dequeue()
        i, j = curr_position
        if matrix[i][j] == 1:
            matrix[i][j] = 0
            for neighbour in get_neighbours((i, j), grid_shape):
                y, x = neighbour
                if matrix[y][x] == 1:
                    queue.enqueue(neighbour)
def get_lvl_wise_nodes(tree: BinaryTree) -> List[Node]:
    # using bfs to generate the list of nodes by level
    if not tree.root:
        return []

    queue = Queue()
    queue.enqueue(tree.root)
    ans = []
    while not queue.is_empty():
        node = queue.dequeue()
        if node.left is not None:
            queue.enqueue(node.left)
        if node.right is not None:
            queue.enqueue(node.right)
        ans.append(node.val)
    return ans
Beispiel #8
0
def is_subtree(T1, T2):
    """

    :param T1:
    :param T2:
    :return:
    """
    q = Queue()
    q.enqueue(T1)

    while not q.is_empty():
        node = q.dequeue()
        if node.value == T2.value and treequal(node, T2):
            return True
        for child in node.children:
            q.enqueue(child)
    return False
def is_minimally_connected(graph: GraphUndirectedUnweighted) -> bool:
    graph_copy = GraphUndirectedUnweighted()
    graph_copy.connections, graph_copy.nodes = deepcopy(graph.connections), graph.nodes
    # getting a random node for starting the traversal
    for node in graph.connections:
        start = node
        break
    # running bfs and checking if a node is visited more than once
    # (redundant edges present => not a minimally connected graph)
    visited = set([start])
    queue = Queue()
    queue.enqueue(start)
    while not queue.is_empty():
        node = queue.dequeue()
        for neighbour in graph_copy.connections[node]:
            graph_copy.connections[neighbour].remove(node)
            queue.enqueue(neighbour)
            if neighbour in visited:
                return False
            visited.add(neighbour)
    return True
def bfs_path(graph: GraphUndirectedUnweighted, start: str,
             stop: str) -> List[str]:
    parent_map = {node: None for node in graph.connections}
    # bfs
    queue = Queue()
    seen = set()
    queue.enqueue(start)
    seen.add(start)
    while not queue.is_empty():
        node = queue.dequeue()
        for neighbour in graph.connections[node]:
            if neighbour not in seen:
                parent_map[neighbour] = node
                queue.enqueue(neighbour)
                seen.add(neighbour)
    # generating the path
    path = [stop]
    while parent_map[path[-1]] is not None:
        path.append(parent_map[path[-1]])
        if path[-1] == start:
            break
    return reversed(path)
def get_level_min_sum(tree: BinaryTree) -> int:
    if not tree.root:
        return 0
    # the levels are delimited in the queue by None
    queue = Queue()
    queue.enqueue(tree.root)
    queue.enqueue(None)

    min_level_sum = maxsize
    curr_level_sum = 0
    while not queue.is_empty():
        node = queue.dequeue()
        if node is not None:
            if node.left:
                queue.enqueue(node.left)
            if node.right:
                queue.enqueue(node.right)
            curr_level_sum += node.val
        else:
            min_level_sum = min(curr_level_sum, min_level_sum)
            if len(queue) > 0:
                queue.enqueue(None)
                curr_level_sum = 0
    return min_level_sum
Beispiel #12
0
def simulation(
        num_seconds:int, 
        pages_per_minute:int):
    
    lab_printer = Printer(
            pages_per_minute
            )
    
    print_queue = Queue()
    
    waiting_times = []
    
    #loop through each second
    for current_second in range(num_seconds):
        
        #check if a print task has been created
        ## the code to check that
        ## generates a print task every 180 sec
        if new_print_task():
            
            #print task created
            task = Task(current_second)
            
            #enqueue the atsk
            print_queue.enqueue(task)
        
        #check printer status
        # check if printer is busy
        # Check if print_queue is empty
        if ((not lab_printer.busy()) and 
           (not print_queue.is_empty())):
            
            #printer is idle and tasks in queue
            
            #get next task from qeueue
            next_task = print_queue.dequeue()
            
            #calculate wait time i.e 
            # current_time - task_created_time_stamp
            wait_time = next_task.wait_time(
                    current_second
                    )
            
            #add to list to calculate average wait time
            waiting_times.append(wait_time)
                    
            #start task
            # The printer now does one second of printing
            # also subtracts 1 second 
            # from the time required for that task.
            lab_printer.start_next(next_task)
              
        #manage printer state
        # if no task ..set to idle
        lab_printer.tick()
    
    #calculate average wait time    
    average_wait = \
    sum( waiting_times ) / len(waiting_times)
    print(
            "Average Wait %6.2f secs %3d tasks remaining." \
            %(average_wait, print_queue.size())
            )