Custo, Otimização
e Padrões
Quanto custa rodar um loop dentro de loop? E como transformar essa estrutura em arte no terminal? Hoje, as duas respostas.
Quanto custa rodar um loop dentro de loop? E como transformar essa estrutura em arte no terminal? Hoje, as duas respostas.
Na aula passada você aprendeu a montar e controlar loops aninhados. Agora vai descobrir quanto custa rodá-los e fechar a semana com um laboratório de padrões geométricos.
Calcular o custo de um algoritmo: O(n²) e O(n)
Comparar a eficiência de algoritmos antes da implementação
Criar figuras geométricas via loops aninhados
Combinar se + loops aninhados para padrões mais complexos
Antes de se assustar com a palavra "complexidade", vamos por partes. Quando os programadores falam de eficiência, eles usam duas ideias bem simples:
Tamanho do problema — quantos itens existem na entrada.
Lista com 10 nomes → n = 10
Lista com 100 nomes → n = 100
Quanto cresce o trabalho conforme o problema aumenta.
É uma "etiqueta" que diz se o esforço cresce pouco, médio ou muito quando n aumenta.
n é o tamanho da lista; O(...) diz o quanto o algoritmo demora a mais quando essa lista cresce. Vamos ver as 3 formas mais comuns nos próximos slides.
Não importa se a lista tem 3 nomes ou 1 milhão. O algoritmo faz uma única ação.
nomes = ["Ana", "Carlos", "João"]
print(nomes[0])
Aqui ele só pega o primeiro item da lista. Nada de percorrer tudo.
Sempre 1 ação principal. Por isso: O(1).
Agora o algoritmo percorre todos os nomes, um por um.
nomes = ["Ana", "Carlos", "João"]
for nome in nomes:
print(nome)
Cada nome é impresso uma vez. Se a lista cresce, o trabalho cresce na mesma medida.
Cresce junto com n. Por isso: O(n).
Agora entra o loop aninhado: o de dentro roda inteiro para cada volta do de fora.
for i in range(10):
for j in range(10):
print(i, j)
10 × 10 = 100 operações. Cada nível multiplica o custo.
Cresce muito rápido. Por isso: O(n²).
| Complexidade | Se n = 10 | Se n = 1000 |
|---|---|---|
| O(1) | 1 | 1 |
| O(n) | 10 | 1.000 |
| O(n²) | 100 | 1.000.000 |
Mesma sala, mesmas 30 pessoas. Mas duas regras diferentes:
Cada aluno cumprimenta só o professor.
30 alunos = 30 cumprimentos
Cada aluno cumprimenta TODOS os outros.
30 × 30 = 900 cumprimentos 😅
para aninhados. 1 loop → geralmente O(n). 2 loops aninhados → geralmente O(n²). 3 loops → O(n³). E por aí vai.
Você já entende o custo dos loops aninhados. Agora vai ver o poder estético deles: criar padrões geométricos no terminal, combinando para aninhados com se.
Cada padrão é uma matriz de pixels. Linha por linha, decidimos o que imprimir em cada coluna. O loop interno constrói a linha; o externo avança para a próxima.
cada caractere é uma decisão consciente
Mesmo número de colunas em cada linha. Ambos os loops vão de 1 até 5.
for linha in range(1, 6):
for coluna in range(1, 6):
print("* ", end="")
print()
Combina dois loops internos: um para os espaços que recuam à esquerda, outro para os asteriscos. Os asteriscos crescem em números ímpares (1, 3, 5, 7, 9) para a figura ficar simétrica.
for linha in range(1, 6):
for c in range(5 - linha):
print(" ", end="") # espaços
for c in range(2 * linha - 1):
print("*", end="") # asteriscos
print()
O inverso da pirâmide do slide anterior: os asteriscos diminuem em números ímpares (9, 7, 5, 3, 1) e os espaços aumentam — o pico aponta para baixo.
for linha in range(1, 6):
for c in range(linha - 1):
print(" ", end="") # espaços
for c in range(11 - 2 * linha):
print("*", end="") # asteriscos
print()
Agora o segredo é combinar loops aninhados com se. Imprima * apenas nas bordas (primeira/última linha, primeira/última coluna) e espaço no meio.
for linha in range(1, 6):
for coluna in range(1, 6):
if linha == 1 or linha == 5 or coluna == 1 or coluna == 5:
print("* ", end="")
else:
print(" ", end="")
print()
O se decide cada célula: borda ou vazio
# O que esse código realmente desenha?
for linha in range(1, 6):
for coluna in range(1, 6):
print("* ", end="")
print()
linha.
n é o tamanho da lista; O(...) diz o quanto o trabalho cresce conforme n aumentaO(n); 2 aninhados ≈ O(n²); 3 ≈ O(n³)Você vai aprender vetores (arrays) unidimensionais — uma forma de armazenar várias informações em uma única estrutura, e percorrê-las com loops.
Você passou pela semana inteira de loops aninhados: do conceito ao custo, da teoria à arte no terminal.
Pense num app que você usa todo dia (Instagram, WhatsApp, Spotify, jogos). Onde ele provavelmente usa loops aninhados? Onde a otimização é mais crítica? E onde um padrão visual aparece na tela?