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.
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.
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.
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:
repetir n vezes: escrever "*"; fim repetir; escrever linha;
repetir m - 2 vezes: (* 2.1 Escrever linha do meio do rectangulo. *) fim repetir;
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?
escrever "*";
repetir n-2 vezes: escrever " "; fim repetir;
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.
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.
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.
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!
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.
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.
{ (* 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.
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.
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 |