def dfs(stack, seen):
    visit_count = 0
    max_depth = -1
    while stack:
        top = stack.get()
        visit_count += 1
        if is_solution(top['state']):
            print('Found solution {} of {} moves in {} visits'.format(
                top['moves'], len(top['moves']), visit_count))
            break
        for direction in ('U', 'L', 'D', 'R'):
            moves_so_far = top['moves']
            if len(moves_so_far) > max_depth:
                max_depth = len(moves_so_far)
            current_state = top['state']
            if can_move_blank(direction, current_state):
                new_state = new_after_move(direction, current_state)
                if new_state not in seen:
                    seen.add(new_state)
                    new_moves = moves_so_far + direction
                    stack.put({'state': new_state, 'moves': new_moves})

    stack_size = py_mem_prof.total_size(stack)
    seen_size = py_mem_prof.total_size(seen)

    if resource:
        resource_usage = resource.getrusage(resource.RUSAGE_SELF)
        ru_maxrss = resource_usage.ru_maxrss
    else:
        resource_usage = None
        ru_maxrss = None

    return max_depth, stack_size, seen_size, ru_maxrss
def bfs(queue, seen):
    visit_count = 0
    while queue:
        head = queue.get()
        visit_count += 1
        if is_solution(head['state']):
            print('Found solution {} of {} moves in {} visits'.format(
                head['moves'], len(head['moves']), visit_count))
            break
        for direction in ('U', 'L', 'D', 'R'):
            moves_so_far = head['moves']
            current_state = head['state']
            if can_move_blank(direction, current_state):
                new_state = new_after_move(direction, current_state)
                if new_state not in seen:
                    seen.add(new_state)
                    new_moves = moves_so_far + direction
                    queue.put({'state': new_state, 'moves': new_moves})
def a_star(priority_queue, seen):
    visit_count = 0
    while priority_queue:
        t = priority_queue.get()
        lowest = {'state': t[1], 'moves': t[2]}
        visit_count += 1
        if is_solution(lowest['state']):
            print('Found solution {} of {} moves in {} visits'.format(
                lowest['moves'], len(lowest['moves']), visit_count))
            break
        for direction in ('U', 'L', 'D', 'R'):
            moves_so_far = lowest['moves']
            current_state = lowest['state']
            if can_move_blank(direction, current_state):
                new_state = new_after_move(direction, current_state)
                if new_state not in seen:
                    seen.add(new_state)
                    new_moves = moves_so_far + direction
                    total = len(moves_so_far) + heuristic(new_state)
                    priority_queue.put((total, new_state, new_moves))
def is_solution(state):
    # return state == '012345678'
    if state == '012345678':
        return True
    else:
        return False


assert is_solution('012345678')
assert not is_solution('082345671')


def to_2d_list(string):
    outer = []
    for i in range(9):
        if i % 3 == 0:
            inner = [string[i]]
            outer.append(inner)
        else:
            inner = outer[i // 3]
            inner.append(string[i])
    return outer


assert to_2d_list('012345678') == [['0', '1', '2'], ['3', '4', '5'],
                                   ['6', '7', '8']]


def to_str(nested_list):
    string = ''
    for inner in nested_list: