Simule algoritmo no papel

From Applied Science

Na disciplina de introdução à computação o professor pode escrever muito no quadro negro e você muito no papel. O computador só é usado quando você tem que escrever programas, em casa, para nota chamados de exercícios-programa. A menos que a carga horária em alguma universidade também inclua prática em laboratório. As provas também não são feitas num computador, mas à moda antiga, com papel e lápis. Nas provas não são exigidos programas complicados, apenas problemas de contagem e operações aritméticas.

Essencialmente, ler e corrigir algoritmo no papel é fazer o seu cérebro funcionar como um depurador.


  • Pra que serve algoritmo no papel se não tem compilador?

Antes de um diretor de um filme filmar, tem um artista que desenha a cena. Antes de um arquiteto ter uma maquete 3D de uma casa tem um desenho no papel. Algoritmo no papel é pra você prestar atenção na lógica e não ficar "viciado" nos erros e avisos do compilador. O compilador identifica todos os erros de sintaxe, mas não pode fazer nada se o seu código tem operações redundantes que tomam tempo ou você esperava que imprimisse 10 vezes na tela "Olá mundo" mas o programa imprime só 9 vezes.

Simular no papel é o mesmo que acompanhar a execução do algoritmo linha por linha. Um modo de fazermos isso é tendo uma tabela, nas colunas colocamos as variáveis e nas linhas o valor das variáveis a cada operação feita. Isso é uma técnica útil para aprender como funcionam algoritmos feitos por outras pessoas. Se o algoritmo estiver bem documentado e bem escrito isso não é necessário, mas se estiver sem documentação e/ou muito mal escrito é a única forma de sabermos o que ele faz.

Um modo meio grosseiro de acompanhar a execução no computador mesmo é colocar um printf() em cada lugar que tiver uma variável e sempre colocar um antes e um depois de alguma operação, aí você lê a saída de tudo.


  • Uma típica questão de simulação. Diga o que será impresso pelo programa abaixo:
#include <stdio.h>

int main() {
    int matricula, i = 1, digito, inverte = 0, conta;

    printf("Digite o numero da sua matricula: ");
    scanf("%d", &matricula);

    conta = matricula;
    while (conta != 1) {
           conta = conta / 10;
           i = i * 10;
    }

    while (i != 0) {
           digito = matricula % 10;
           inverte = inverte + digito * i;
           printf("%d * ", inverte);

           if (digito % 2 == 0)
               printf("par\n");
           else
               printf("impar\n");

           matricula = matricula / 10;
           i = i / 10;
    }

    return 0;
}

Façamos a simulação. Como exemplo suponha que a matrícula lida é 1234567:

primeiro while
conta i iterações do laço
1234567 1 0 (antes de entrar)
123456 10 1
12345 100 2
... ... ...
1 1000000 6

Se estiver bem adaptado à contagem e à operação de atribuição de valor, não precisa nem perder tempo simulando o primeiro laço do começo ao fim, simplesmente anote o valor do 'i' da última iteração.

Segundo while printf printf
i (antes) matricula digito inverte matricula i (depois) par / ímpar
1.000.000 1234567 7 7000000 123456 100.000 impar
100.000 123456 6 7600000 12345 10.000 par
... ... ... ... ... ... ...
10 12 2 7654320 1 1 par
1 1 1 7654321 0 0 impar

É bom deixar as variáveis ordenadas segundo a ordem de execução, assim evitamos algum erro de confusão entre variáveis ou operação simuladas fora de ordem. Se a variável aparece duas vezes, antes e depois de alguma operação, é bom diferenciar bem esses dois estados. Senão podemos confundir o valor da variável na sequência de iterações.

Se conseguir entender o que o algoritmo faz não precisa nem perder tempo com a tabela de simulação, já escreva a saída de cada chamada da função printf() imediatamente. Perceba: o primeiro laço atribui a 'i' o valor 10i, onde 'i' é o número de dígitos da matrícula menos um. O segundo laço faz a inversão dos dígitos da matrícula. Pega o último e põe no lugar do primeiro. Preenchendo o restante com zeros. A cada dígito removido, o algoritmo testa se o dígito é par ou ímpar.


Erros que as pessoas podem cometer numa prova com um algoritmo desse:

  • Repetir uma vez a mais no primeiro laço. O que invariavelmente leva a um erro de contagem no segundo laço;
  • Não saber como a variável do tipo inteiro lida com números não inteiros. 1234567 / 10 é o mesmo que remover o último dígito;
  • Se a pessoa não entender o que é o sinal de igual, a operação de atribuição, não conseguirá fazer nada na simulação. Num caso desses não é raro a resposta da pessoa conter operações absurdas como multiplicar 1234567 * 10;
  • Não saber qual o resto inteiro da operação x % y quando x < y, ou errar o resto;
  • A cada repetição, a variável 'matricula' diminui de um dígito, enquanto a variável 'i' aumenta de um. Qualquer erro aí mostra falha na leitura do código e/ou falha na execução. A pessoa não acompanhou como deveria as operações aritméticas envolvidas;
  • A impressão de "par" ou "ímpar" pode estar errada. Por algum motivo a pessoa confundiu a variável 'dígito' com a variável 'inverte';
  • Um professor pode, se quiser, forçar uma indentação ruim ou usar nomes de variáveis menos óbvios para dificultar a simulação.


Erros com funções e vetores:

  • Se a pessoa não entende o conceito de função e/ou vetor, não saberá simular a execução do algoritmo;
  • Confundir ponteiros com variáveis, ou não saber o que fazem os ponteiros;
  • Erros de contagem com relação a índices de vetores e matrizes;
  • Não saber como funcionam funções recursivas.