Será que resolvemos problemas da maneira certa?

Hoje em dia é normal a ideia do programador resolver problemas, mas como que nós fazemos isso?

Gabriel Albuquerque (Albuca)
5 min readJan 6, 2021
David J. Malan em CS50x 2021

CS50x

O CS50x é um programa gratuito disponibilizado por Harvard que visa ensinar o básico Ciência da Computação para futuros profissionais da área. Foi através da primeira aula, ministrada majestosamente por David J. Malan que obtive essa reflexão a respeito de resolução de problemas.

Qual a qualidade da sua solução?

David Malan e seu ‘phone book’

O algorítmo do livro

Suponhamos que você precisa entrar em contato com o David Malan, mas você não tem internet e somente um livro de contatos, um livro com mais de 2.000 páginas com nomes ordenados alfabeticamente e suas respectivas informações de contato.

Existem algumas maneiras de procurar o David nesse livrão, a primeira é simplesmente folheando-o página por página até encontrar o seu nome. E aí eu te pergunto, você acha que esse “algorítmo” de busca está correto?

Sim, claro que está. Se passarmos folha por folha em algum momento vamos acabar esbarrando com a seção de nomes D, e lá provavelmente estará o nome dele.

Mas esse algorítmo tem um problema sério: o tempo gasto. Vai demorar muito folhear página por página até chegarmos no nome do David, e além disso, estamos desperdiçando tempo ao paginar folhas onde temos certeza que não vamos encontrar nada (por exemplo: folhear a seção B). O que quero dizer é: funcionar não é o suficiente.

Outra maneira também seria através da paginação, porém pulando de duas em duas páginas, desse modo diminuiriamos o tempo de busca pela metade. Então te pergunto novamente, será que esse algorítmo de busca está correto?

Com certeza não, apesar de ser mais rápido que o primeiro, em qualquer momento poderíamos acabar pulando o nome do David do livro ao pular a folha onde ele se encontra, esse algorítmo tem um bug e é defeituoso em todas suas possíveis implementações.

Depois de pensar bastante, poderíamos dizer que a maneira mais adequada seria fazer da seguinte maneira: abrir o livro ao meio, estariamos na seção M, sabemos que o D fica para trás, então, passamos a ignorar todas as páginas que são MAIORES do que a que acabamos de abrir (todas as seções de M para frente). Agora considerando que temos um phone book muito menor, vamos abrir ao meio novamente, estamos na seção G, sabemos que D fica para trás de G, então repetimos todo o processo novamente até encontrarmos o David no livro.

O algorítmo do livro em pseudocódigo

A qualidade (ou tempo) da resolução

Existe uma relação entre o tempo da nossa resolução para o tamanho do problema, na ilustração ao lado, o primeiro algorítmo é a linha em vermelha, ele representa n ou seja, o tempo de solução do algorítmo varia diretamente com o tamanho do problema, quanto maior o problema, maior o tempo necessário, por exemplo: se quisermos procurar o nome do tio Zeca, passariamos página por página até chegar no Z, demoraria uma eternidade, diferente se procurássemos o nome do Anderson da farmácia, por exemplo.

O primeiro algorítmo realmente funciona, porém não é a melhor solução.

A linha amarela representa n/2 isso significa que esta também varia diretamente com o tamanho do problema, porém leva metade do tempo.

A linha verde log²n representa o terceiro algorítmo, perceba que os outros são uma linha reta para cima, esse já é diferente, ele cresce um pouco no início e depois sobe gradativamente, quase numa linha horizontal.

Isso significa que se o livro dobrar de tamanho e conter 4.000 páginas, e precisarmos encontrar o tio Zeca, o tempo de solução do algorítmo vai variar o mínimo possível, enquanto no primeiro algorítmon o tempo de solução iria dobrar junto com a quantidade de páginas.

Vale lembrar que nesse caso estamos medindo a qualidade do algorítmo pelo seu tempo de resolução, mas na vida real existem vários fatores que devem ser levados em conta como performance geral, segurança, escalabilidade, mantenabilidade e outros.

Reflexão

Agora responda sinceramente para você mesmo:

  • Quantas vezes você já deixou o código “assim mesmo” porque estava rodando e “funcionando” mas você nem sabia o porquê?
  • Quantas vezes você escolheu rotas alternativas para resolver um problema por que não soube resolver?
  • Você sabe se o seu código é performático?
  • Você sabe quanto seu código é performático?
  • Você sabe o que aquele código do stack overflow faz?
  • Qual foi a última vez que você se preocupou com segurança?
  • Você sabe se existem maneiras melhores de fazer o que você já fez?
  • Você sabe se virar sem aquela lib?

Como programador, entendo que temos a responsabilidade de desenvolver o melhor sistema possível, para isso temos que saber exatamente o que ele está fazendo e como ele está fazendo, caso contrário, corremos o risco de desenvolver o primeiro algorítmo, aquele que apenas roda.

Não estou aqui pra apontar o dedo, eu mesmo me peguei no erro na maioria dessas perguntas e ainda estou trabalhando nisso. Trabalhamos no ramo da ciência, nosso código tem que seguir a ciência, e onde está a ciência em “deixar como tá, porque tá rodando”? Lembre-se: funcionar não é o suficiente.

Sempre que escrever um método, uma classe, um componente, ou uma linha de código se pergunte se o que você está fazendo é igual ao primeiro ou ao terceiro algorítmo do livro.

Conclusão

Agradeço se leu até aqui! Espero que eu tenha conseguido “plantar uma semente” na sua cabeça, um senso de autocrítica necessário para que posssamos melhorar cada vez mais.

Os links estão abaixo:
Caso queira saber mais sobre o CS50x.
Refletindo sobre RESOLUÇÃO de Problemas do Fabio Akita também é uma ótima reflexão sobre o assunto.

Bons estudos!

--

--

No responses yet