Aula 1 - Resoluções


Exercício 1

Alínea a)

Não é possível a resolução do problema para qualquer valor de m se não se fizer recurso a alguma acção de repetição. Podemos, no entanto, resolver o problema para valores específicos de m. Por exemplo, para m=6 uma solução possível seria:

{   (* Pressupostos: *)
}
{   (* Resultado a atingir: *)
    Deve aparecer escrito:
    ***
    ***
    ***
    ***
    ***
    ***
}
rectangulo_6x3
inicio
    escrever linha; (* para garantir que o cursor comeca no inicio 
                       duma linha *)

    escrever "***", linha;
    escrever "***", linha;
    escrever "***", linha;
    escrever "***", linha;
    escrever "***", linha;
    escrever "***", linha;
fim.

Alínea b)

Usando repetir a solução do problema torna-se genérica, pois funciona para qualquer valor de m:

{   (* Pressupostos: *)
}
{   (* Resultado a atingir: *)
    Deve aparecer escrita m vezes a linha:
    ***
}
rectangulo_mx3
inicio
    inteiro m;

    escrever linha;

    (* Inicializacoes: *)
    m <- 5; (* valor arbitrario *)

    repetir m vezes:
        escrever "***", linha;
    fim repetir;
fim.

Alínea c)

Neste caso as linhas consistem em n asteriscos consecutivos, o que se pode obter facilmente por meio duma segunda repetição:

{   (* Pressupostos: *)
}
{   (* Resultado a atingir: *)
    Deve aparecer escrita m vezes um linha com n asteriscos. Por exemplo, 
    se m = 2 e n = 5 deve aparecer:
    *****
    *****
}
rectangulo_mxn
inicio
    inteiro m, n;

    escrever linha;

    (* Inicializacoes: *)
    m <- 3; (* valor arbitrario *)
    n <- 7; (* valor arbitrario *)

    repetir m vezes:
        repetir n vezes:
            escrever "*";
        fim repetir;
        escrever linha;
    fim repetir;
fim.

Alínea d)

Neste caso o problema pode ser dividido em três sub-problemas:

rectangulo_oco_mxn
inicio
    inteiro m, n;

    escrever linha;

    (* Inicializacoes: *)
    m <- 3; (* valor arbitrario *)
    n <- 7; (* valor arbitrario *)

    (* 1. Escrever topo do rectangulo. *)

    (* 2. Escrever meio do rectangulo. *)

    (* 3. Escrever base do rectangulo. *)
fim.

Em seguida tenta-se resolver cada sub-problema:

  1. Escrever o topo do rectangulo (uma linha com n asteriscos):
        repetir n vezes:
            escrever "*";
        fim repetir;
        escrever linha;
    
  2. Escrever meio do rectângulo. Ou seja, escrever m - 2 linhas do meio do rectângulo:
        repetir m - 2 vezes:
            (* 2.1 Escrever linha do meio do rectangulo. *)
        fim repetir;
    
  3. Escrever a base do rectângulo (de novo uma linha com n asteriscos):
        repetir n vezes:
            escrever "*";
        fim repetir;
        escrever linha;
    

O sub-problema 2., tem um sub-sub-problema (2.1) por resolver. Como escrever uma linha do meio do rectângulo?

  1. Escrever um asterisco:
            escrever "*";
    
  2. Escrever n - 2 espaços:
            repetir n-2 vezes:
                escrever " ";
            fim repetir;
    
  3. Escrever um asterisco seguido dum fim-de-linha:
            escrever "*", linha;
    

Assim, a solução é:

{   (* Pressupostos: *)
    m e n sao maiores do que um (1).
}
{   (* Resultado a atingir: *)
    Deve aparecer escrito um rectangulo oco de m x n asteriscos. Por exemplo, 
    se m = 5 e n = 4 deve aparecer:
    ****
    *  *
    *  *
    *  *
    ****
}
rectangulo_oco_mxn
inicio
    inteiro m, n;

    escrever linha;

    (* Inicializacoes: *)
    m <- 3; (* valor arbitrario *)
    n <- 7; (* valor arbitrario *)

    (* Topo do rectangulo: *)
    repetir n vezes:
        escrever "*";
    fim repetir;
    escrever linha;

    (* Meio do rectangulo: *)
    repetir m - 2 vezes:
        escrever "*";
        repetir n-2 vezes:
            escrever " ";
        fim repetir;
        escrever "*", linha;
    fim repetir;

    (* Base do rectangulo: *)
    repetir n vezes:
        escrever "*";
    fim repetir;
    escrever linha;
fim.

Alínea e)

Como resolver o problema neste caso? A escrita de algoritmos passa muitas vezes por reconhecer a existência de repetições ou de padrões regulares.

Neste caso, vê-se claramente que se uma linha consiste em k asteriscos a linha seguinte consiste em k+1 asteriscos. Vê-se também que a primeira linha consiste em apenas um (1) asterisco.

Assim, o algoritmo consiste em duas repetições, sendo a repetição exterior executada m vezes e a interior k vezes, em que k vai crescendo sucessivamente de 1 até m:

{   (* Pressupostos: *)
}
{   (* Resultado a atingir: *)
    Deve aparecer escrito um triangulo rectangulo de base m com hipotenusa
    a direita. Por exemplo, se m = 5 deve aparecer:
    *
    **
    ***
    ****
    *****
}
triangulo_m
inicio
    inteiro m, k;

    escrever linha;

    (* Inicializacoes: *)
    m <- 7; (* valor arbitrario *)

    k <- 1; (* numero de asteriscos da primeira linha *)
    repetir m vezes:
        (* Escrever linha com k asteriscos: */

        (* Escrever k asteriscos: *)
        repetir k vezes:
            escrever "*";
        fim repetir;

        (* Escrever fim-de-linha: *)
        escrever linha;

        (* A linha seguinte tem mais um asterisco: *)
        k <- k + 1;
    fim repetir;
fim.

Alínea f)

Neste caso o algoritmo é muito semelhante, embora se devam escrever m - k espaços no início de cada linha. Exemplo com m = 5:

    * k = 1, m - k = 4
   ** k = 2, m - k = 3
  *** k = 3, m - k = 2
 **** k = 4, m - k = 1
***** k = 5, m - k = 0
{   (* Pressupostos: *)
}
{   (* Resultado a atingir: *)
    Deve aparecer escrito um triangulo rectangulo de base m com hipotenusa
    a esquerda. Por exemplo, se m = 5 deve aparecer:
        *
       **
      ***
     ****
    *****
}
triangulo_esquerda_m
inicio
    inteiro m, k;

    escrever linha;

    (* Inicializacoes: *)
    m <- 7; (* valor arbitrario *)

    k <- 1;
    repetir m vezes:
        (* Escrever m - k espacos iniciais: *)
        repetir m - k vezes:
            escrever " ";
        fim repetir;

        (* Escrever k asteriscos: *)
        repetir k vezes:
            escrever "*";
        fim repetir;

        (* Escrever fim-de-linha: *)
        escrever linha;

        k <- k + 1; (* proxima linha tem mais um asterisco *)
    fim repetir;
fim.

Exercício 2

Alínea a)

A solução é trivial:

{   (* Pressupostos: *)
}
{   (* Resultado a atingir: *)
    Deve escrever os inteiros de 1 a 10, cada um em sua linha.
}
conta_1_10
inicio
    inteiro n;

    escrever linha;

    n <- 1;
    repetir 10 vezes:
        escrever n, linha;
        n <- n + 1;
    fim repetir;
fim.

Note-se que outra solução seria:

{   (* Pressuposto: *)
}
{   (* Resultado a atingir: *)
    Deve escrever os inteiros de 1 a 10, cada um em sua linha.
}
conta_1_10_alt
inicio
    inteiro n;

    escrever linha;

    n <- 0;
    repetir 10 vezes:
        n <- n + 1;
        escrever n, linha;
    fim repetir;
fim.

A diferença fundamental entre as duas soluções é que, uma vez terminado o ciclo repete, o valor de n é 11 na primeira solução e 10 na segunda. Faça o traçado dos algoritmos para verificar!

Alínea b)

A solução é mais uma vez trivial. No entanto, note que desta vez o ciclo é executado 11 vezes (20 - 10 + 1)!

{   (* Pressupostos: *)
}
{   (* Resultado a atingir: *)
    Deve escrever os inteiros de 10 a 20, cada um em sua linha.
}
conta_10_20
inicio
    inteiro n;

    escrever linha;

    n <- 10;
    repetir 11 vezes:
        escrever n, linha;
        n <- n + 1;
    fim repetir;
fim.

Alínea c)

Note que neste caso o ciclo é executado 6 vezes (10/2 - 0 + 1)!

{   (* Pressupostos: *)
}
{   (* Resultado a atingir: *)
    Deve escrever os inteiros pares de 0 a 10, cada um em sua linha.
}
conta_0_10_2
inicio
    inteiro n;

    escrever linha;

    n <- 0;
    repetir 6 vezes:
        escrever n, linha;
        n <- n + 2;
    fim repetir;
fim.

Alínea d)

{   (* Pressupostos: *)
}
{   (* Resultado a atingir: *)
    Deve escrever os inteiros pares de 10 a 0, cada um em sua linha.
}
conta_10_0_2
inicio
    inteiro n;

    escrever linha;

    n <- 10;
    repetir 6 vezes:
        escrever n, linha;
        n <- n - 2;
    fim repetir;
fim.

Alínea e)

Note-se o número de iterações utilizado (n - m + 1):

{   (* Pressupostos: *)
    n > m
}
{   (* Resultado a atingir: *)
    Deve escrever os inteiros de m a n, cada um em sua linha.
}
conta_m_n
inicio
    inteiro m, n;

    escrever linha;

    m <- 11; (* valor arbitrario *)
    n <- 17; (* valor arbitrario *)

    repetir n - m + 1 vezes:
        escrever m, linha;
        m <- m + 1;
    fim repetir;
fim.

A solução apresentada utiliza a variável m para fazer a contagem. Caso fosse desejável não alterar o valor de m poder-se-ia usar uma variável auxiliar:

{   (* Pressupostos: *)
    n > m
}
{   (* Resultado a atingir: *)
    Deve escrever os inteiros de m a n, cada um em sua linha.
}
conta_m_n_alt
inicio
    inteiro m, n, k;

    escrever linha;

    m <- 11; (* valor arbitrario *)
    n <- 17; (* valor arbitrario *)

    k <- m;
    repetir n - m + 1 vezes:
        escrever k, linha;
        k <- k + 1;
    fim repetir;
fim.

Alínea f)

Mais uma vez, para resolver este problema é necessario atentar à repetição de padrões:

m^0 = 1
m^1 = m
m^2 = m x m
m^3 = m x m x m
...

Ou ainda:

m^0 = 1
m^1 = m^0 x m
m^2 = m^1 x m
m^3 = m^2 x m
...
m^n = m^(n-1) x m

Tendo isto em conta, o algoritmo surge naturalmente como:

{   (* Pressupostos: *)
    n >= 0
}
{   (* Resultado a atingir: *)
    Deve escrever a potencia n de m.
}
potencia_m_n
inicio
    inteiro m, n, pot;

    escrever linha;

    m <- 4; (* valor arbitrario *)
    n <- 3; (* valor arbitrario *)

    pot <- 1;
    repetir n vezes:
        pot <- pot * m;
    fim repetir;

    escreve m, "^", n, " = ", pot, linha; 
fim.

Sugere-se que o leitor faça o traçado do algoritmo para perceber a evolução do valor das variáveis.


Página concebida e mantida por Eng. Manuel Menezes de Sequeira (última actualização 2006/07/07)
Copyright © 1996-2001 ISCTE