Recursos-LCC

Um arquivo de todo material que consegui reunir, pertinente ao curso de LCC da UM.

View on GitHub

LA2 | Treino 2 | Área


'''
Implemente uma função que calcula a área de um mapa que é acessível por
um robot a partir de um determinado ponto.
O mapa é quadrado e representado por uma lista de strings, onde um '.' representa
um espaço vazio e um '*' um obstáculo.
O ponto inicial consistirá nas coordenadas horizontal e vertical, medidas a 
partir do canto superior esquerdo.
O robot só consegue movimentar-se na horizontal ou na vertical. 
'''


def area(p,mapa):
    xi, yi = p

    if mapa[yi][xi] == '*':
        return 0
    else:
        area = 1
        vis = {(xi,yi)}
        queue = [(xi,yi)]
        while queue:
            x,y = queue.pop(0)
            for i in [-1,0,1]:
                for k in [-1,0,1]:
                    if not abs(i)+abs(k)-2:
                        continue
                    if (x+i,y+k) in vis:
                        continue
                    if y + k >= 0 and y + k < len(mapa) and x + i >= 0 and x + i < len(mapa):
                        if mapa[y+k][x+i] == '*':
                            continue
                        vis.add((x+i,y+k))
                        area += 1
                        queue.append((x+i,y+k))

        return area


#############################################
#  Resolução usando algoritmos de travessia  #
#############################################

def build(mapa):
    adj = {}
    length = len(mapa)
    width = len(mapa[0])
    for y in range(length):
        for x in range(width):
            if mapa[y][x] == '*':
                continue
            elif (x, y) not in adj:
                adj[(x, y)] = set()
            for i in [-1, 0, 1]:
                for j in [-1, 0, 1]:
                    if abs(i) + abs(j) == 2:
                        continue
                    if not 0 <= x+i < width:
                        continue
                    if not 0 <= y+j < length:
                        continue
                    if mapa[y+j][x+i] == '*':
                        continue
                    if (x+i, y+j) not in adj:
                        adj[(x+i, y+j)] = set()
                    
                    adj[(x, y)].add((x+i, y+j))
                    adj[(x+i, y+j)].add((x, y))
    return adj

def bfs(adj,o):
    custo = 0
    vis = {o}
    queue = [o]
    while queue:
        v = queue.pop(0)
        for d in adj[v]:
            if d not in vis:
                vis.add(d)
                custo += 1
                queue.append(d)
    return custo+1

def area(p,mapa):
    adj = build(mapa)
    res = bfs(adj, p)
    return res


Testes

# 1
p = (3,2)
mapa = ["..*..",
        ".*.*.",
        "*...*",
        ".*.*.",
        "..*.."]
> Resultado = 5

# 2
p = (3,2)
mapa = ["..*..",
        ".*.*.",
        "*....",
        ".*.*.",
        "..*.."]
> Resultado = 12

retroceder