Beruflich Dokumente
Kultur Dokumente
2
CONCEITOS BSICOS
1.1 INTRODUO
Neste curso o leitor estar se envolvendo com a aprendizagem de conceitos e
mtodos bsicos para a construo de programas de computador. A abordagem
que daremos est voltada para o envolvimento do aprendiz com a soluo de
problemas ao invs da atitude passiva de ver o que os outros fizeram. Uma
questo central que permeia o curso a de que construir programas uma tarefa
de engenharia, e que, portanto produzir artefatos com os quais o ser humano
ter de conviver. Artefatos estes que devem satisfazer requisitos de qualidade e
serem, portanto, passveis de constatao.
Optamos desenvolver o curso orientado descrio de funes, um
formalismo bastante conhecido por todos os que chegam a este curso.
Esperamos, com isso, atenuar algumas dificuldades tpicas do ensino introdutrio
de programao. Nas sees seguintes apresentamos alguns conceitos bsicos
que nos parecem importantes ter em mente antes de iniciarmos um curso de
programao.
1.2. COMPUTADORES
Denominamos de computador uma mquina de processar dados, numricos ou
simblicos, que funciona atravs da execuo de programas. Ao contrrio das
inmeras mquinas que conhecemos, tais como: mquina de lavar roupa,
liquidificador, enceradeira, aspirador de p, e tantas outras, que realizam uma
nica funo, o computador uma mquina multiuso. Podemos us-lo como uma
mquina de escrever sofisticada, como uma mquina de fax, como uma prancheta
de desenho sofisticada, como um fichrio eletrnico, como uma planilha de
clculos e de tantas outras formas. exatamente como o nosso conhecido
videogame: para mudar de jogo basta trocar o cartucho. No videogame, cada novo
jogo determinado por um novo programa.
Em linhas gerais podemos entender um computador como uma mquina
capaz de:
a)
b)
3
Ex 2: Informar a uma mquina as regras de conjugao de verbos. Com este
conhecimento a mquina pode determinar a forma correta para um determinado
tempo e pessoa de um verbo especfico.
Ex 3: Traduo de textos;
Ex 4: Classificao de textos quanto sua natureza: romance, poesia,
documentrio, entrevista, artigo cientfico;
Ex 5: Manipulao de expresses algbricas, resoluo de integral
indefinida, etc;
Ex 6: Programao automtica: dada uma certa especificao, gerar um
programa eficiente;
Ex 7: Monitoramento de pacientes em um Centro de Tratamento Intensivo;
Ex8: Identificao de tumores no crebro a partir da comparao de imagens
com padres conhecidos de anormalidade;
Ex 9: Roteamento inteligente de mensagens.
1.3. PROGRAMAO
tarefa de identificar o conhecimento necessrio para a descrio de um
conceito, organiz-lo e codific-lo de modo a ser entendido pela mquina damos o
nome de programao de computadores. Ao conhecimento codificado, produto
final da tarefa de programao d-se o nome de programa.
A programao de computadores uma atividade que compreende vrias
outras atividades, tais como: entendimento do problema a ser resolvido,
planejamento de uma soluo, formalizao da soluo usando uma linguagem de
programao, verificao da conformidade da soluo obtida com o problema
proposto.
1.4. LINGUAGEM DE PROGRAMAO
A descrio de conhecimento para um agente racional qualquer (seja uma
mquina ou um humano) subentende a existncia de padres segundo os quais o
agente possa interpretar o conhecimento informado. A esses padres, quando
rigorosamente elaborados, damos o nome de formalismo. Um formalismo
composto de dois aspectos: a sintaxe e a semntica. A sintaxe permite ao agente
reconhecer quando uma "seqncia de smbolos" que lhe fornecida est de
acordo com as regras de escrita e, portanto representa um programa. A semntica
permite que o agente atribua um significado ao conhecimento descrito pela
"seqncia de smbolos". Por exemplo, quando um agente humano (com
determinado grau de escolaridade) encontra a seguinte seqncia de smbolos {3,
4} U {5, 9, 15}, ele por certo reconhecer como uma expresso algbrica escrita
4
corretamente e, se lembrar dos fundamentos da teoria dos conjuntos, associar
esta cadeia como a descrio de um conjunto composto pela unio dos elementos
de dois conjuntos menores.
Eis aqui algumas observaes importantes sobre a necessidade de
linguagens de programao:
5
As regras que permitem a associao de significados s "seqncias de smbolos"
obedecem a certos princpios. Existem vrias manifestaes destes princpios e a
cada uma delas denominamos de paradigma.
Um paradigma pode ser entendido informalmente como uma forma
especfica de se "pensar" sobre programao. Existem trs grandes grupos de
paradigmas para programao: o procedimental, o funcional e o lgico. Os dois
ltimos so freqentemente referidos como sendo subparadigmas de um outro
mais geral, o paradigma declarativo. O paradigma procedimental subentende a
organizao do conhecimento como uma seqncia de tarefas para uma mquina
especfica. O paradigma lgico requer o conhecimento de um formalismo
matemtico denominado de lgica matemtica. O paradigma funcional baseia-se
no uso dos princpios das funes matemticas. De uma forma geral, os
paradigmas declarativos enfatizam o aspecto correo e o procedimental os
aspectos de desempenho. Vejam que falamos em "enfatizam", o que quer dizer
que apresentam facilidades para descrio e verificao da propriedade
considerada. Entretanto, em qualquer caso, o programador dever sempre
garantir que os dois aspectos (correo e desempenho) sejam atendidos.
1.7. PROGRAMAO FUNCIONAL
Para os fins que aqui nos interessam neste primeiro momento, podemos entender
o computador, de uma forma simplificada, como uma mquina capaz de:
a) avaliar expresses escritas segundo regras sintticas bem definidas, como
a das expresses aritmticas que to bem conhecemos (ex. 3 + 5 - 8)
obedecendo semntica das funes primitivas das quais ela dotada (por
exemplo: as funes aritmticas bsicas como somar, subtrair, multiplicar e
dividir);
b) aceitar a definio de novas funes e posteriormente consider-las na
avaliao de expresses submetidas sua avaliao.
Por enquanto, denominaremos o computador de mquina funcional. A seguir
apresentamos um exemplo de interao de um usurio com a nossa Mquina
Funcional.
usurio: 3 + 5 / 2
sistema: 5,5
usurio: f x y = (x + y) / 2
sistema: definio de f foi aceita
usurio: (f 3 5) + (f 10 40)
sistema: 29
6
denominou de f e que o sistema acatou a nova definio. Na terceira interao o
usurio solicita a avaliao de uma nova expresso aritmtica usando o conceito
recentemente definido e que o sistema faz a avaliao usando corretamente o
novo conceito.
1.8. EXPRESSES ARITMTICAS
A nossa mquina funcional hipottica entende a sintaxe das expresses
aritmticas, com as quais todo aluno universitrio j bem familiarizado e capaz
de avali-las usando essas mesmas que regras que j conhecemos.
Sintaxe - Todo operador aritmtico pode ser entendido, e aqui o ser, como
uma funo que possui dois parmetros. A notao usual para as operaes
aritmtica a infixada, ou seja, smbolo funcional colocado entre os dois
operandos. Nada impede de pensarmos nele escritos na forma prefixada, que a
notao usual para funes com nmero de parmetros diferente de 2. Por
exemplo, podemos escrever "+ 3 2" para descrever a soma do nmero 3 com o
nmero 2. As funes definidas pelo programador devem ser escritas de forma
prefixada, como no exemplo de interao acima apresentado. Combinando essas
duas formas, infixada e prefixada, podemos escrever expresses bastante
sofisticadas.
Avaliao - As expresses aritmticas, como sabemos, so avaliadas de
acordo com regras de avaliao bem definidas, efetuando as operaes de acordo
com suas prioridades. Por exemplo, na expresso "3 + 5 / 2" o primeiro operador a
ser avaliado ser o de diviso (/) e posteriormente o de adio. Se desejarmos
mudar essa ordem, podemos usar parnteses em qualquer quantidade, desde que
balanceados e em posies apropriadas. Por exemplo, na expresso "(3 + 5) / 2",
a utilizao de parnteses determina que a sub-expresso 3 + 5 ter prioridade na
avaliao.
1.9. FUNES
Podemos entender o conceito de funes como uma associao entre elementos
de dois conjuntos A e B de tal forma que para cada elemento de A existe apenas
um elemento de B associado. O conjunto A conhecido como o domnio da
funo, ou ainda como o conjunto de entrada, e o conjunto B o contra-domnio
ou conjunto de sada. Para ser mais preciso, podemos afirmar que uma funo f ,
que associa os elementos de um conjunto A aos elementos de um conjunto B,
um conjunto de pares ordenados onde o primeiro elemento do par pertence a A o
segundo a B. Exemplos:
a) Seja a funo T que associa as vogais do alfabeto com os cinco primeiros
inteiros positivos.
T = {(a,1), (e,2), (i,3), (o,4), (u,5)}
7
b) Seja a funo Q, que associa a cada nmero natural o seu quadrado.
Q = {(0,0), (1,1), (2,4), (3,9), (4,16), ...}
Podemos observar que a funo T um conjunto finito e que a funo Q
um conjunto infinito.
1.10. DESCRIES FUNCIONAIS
Podemos descrever um conjunto, de duas formas: extensional, onde explicitamos
todos os elementos que so membros do conjunto, como no caso do conjunto T
apresentado anteriormente; ou na forma intencional, onde descrevemos um
critrio de pertinncia dos membros do conjunto. Por exemplo, o conjunto Q acima
apresentado poderia ser reescrito da seguinte forma:
Q = {(x, y) | x natural e y = x.x} que pode ser lido da seguinte maneira:
Q o conjunto dos pares ordenados (x, y) tal que x um nmero
natural e y o produto de x por x.
Quando descrevemos uma funo para fins computacionais, estamos
interessados em explicitar como determinar o segundo elemento do par ordenado,
conhecido o primeiro elemento do par. Em outras palavras, como determinar y
conhecendo-se o valor de x. Normalmente dizemos que queremos determinar y
em funo de x. Nesta forma de descrio, omitimos a varivel y e explicitamos o
primeiro elemento que denominado ento de parmetro da funo. No caso
acima teramos ento:
Qx=x.x
1.11. Por que comear a aprendizagem de programao atravs do
paradigma funcional?
Tendo em vista a prtica vigente de comear o ensino de programao utilizando
o paradigma procedimental, apresentamos a seguir alguns elementos que
baseiam nossa opo de comear o ensino de programao usando o paradigma
funcional.
1)
2)
8
3)
4)
5)
6)
ii)
iii)
7)
8)
9)
10)
9
uma boa resposta a este problema, visto que com linguagens
funcionais podemos nos concentrar mais na soluo do problema do
que nos detalhes de um computador especfico, o que aumenta a
produtividade.
11)
12)
Exerccios:
1. Conceitue programao de computadores.
2. Quais os principais paradigmas de programao e o que os diferenciam.
3. Faa uma descrio intencional da funo: F = {1,3,5,7,...}.
4, Faa uma listagem de outros exemplos de programas de computador que so
usados hoje em diferentes reas do conhecimento e por diferentes profissionais.
5. Apresente exemplo de outras linguagens tcnicas usadas pelo ser humano para
descrever conhecimento.
6. Os conceitos de correo e de desempenho, se aplicam a qualquer artefato.
Escolha 3 artefatos quaisquer e discuta os dois conceitos.
7. Apresente uma descrio informal da funo que conjuga os verbos regulares
da 1a. conjugao.
1
1
v t
parmetros
interface da funo
v*t
expresso aritmtica que define a
relao que h entre os parmetros
corpo da definio
1
2
geral. No jargo de programao com a linguagem Haskell, um conjunto de
definies denominado de script.
A alimentao de novas definies indicada ao sistema atravs de um
comando que usado no lugar de uma expresso, quando o sistema exibe o seu
pedido de tarefa (o smbolo de interrogao. Para indicar que estaremos dando
um comando usamos o smbolo " : " (dois pontos) seguido do nome do comando
(existem vrios). Para a tarefa que temos neste instante utilizamos o comando
load (oportunamente veremos outros).
Por exemplo, podemos escrever um conjunto de definies em um arquivo
denominado pf0001.hs. Para alimentar este arquivo no ambiente HUGS podemos
escrever:
> :load pf001.hs
A partir deste momento, todas as definies contidas no arquivo informado
estaro disponveis para uso. Podemos entender isso como fazer uma extenso
da mquina Haskell. Na figura 2.1 apresentamos um esquema de utilizao do
ambionete HUGS e de um editor de textos para provimento de novas definies.
Editor
de texto
Arquivo com
definies
Interpretador
HUGS
programador
1
3
2.3. UM EXEMPLO: Considere que queremos descrever uma funo para
determinar as razes de uma equao do segundo grau.
Sabemos que pela nossa clssica frmula as razes so descritas
genericamente por:
=
=
=
=
=
x*x
sqrt ( quad b - 4.0 * a * c )
2.0 * x
((-b) + raizdelta a b c) / dobro a
((-b) - raizdelta a b c) / dobro a
1
4
standard.prelude
eq2g.gs
> eq2g1 2.0 5.0 2.0
-0.5
> eq2g2 2.0 5.0 2.0
-2.0
> eq2g1 3.0 4.0 5.0
Program error: {sqrt (-44.0)}
Podemos observar que houve um problema com a avaliao da expresso
eq2g1 3.0 4.0 5.0
Este um erro semntico, provocado pela tentativa de extrair a raiz
quadrada de um nmero negativo. A funo que definimos portanto uma
funo parcial, ou seja, ela no est definida para todo o domnio dos
reais. Neste caso o sistema apenas acusa o problema ocorrido.
2.4. DEFINIES LOCAIS: As definies que discutimos anteriormente so
globais, no sentido de que esto acessveis ao uso direto do usurio e tambm
disponveis para uso em qualquer outra definio. Por exemplo, se temos o script:
quad x = x * x
hipo x y = sqrt ( quad x + quad y)
Podemos utilizar a definio quad tanto externamente pelo usurio quanto
internamente pela definio hipo.
Se no entanto desejamos construir subdefinies para uso em uma
definio especfica, podemos defini-las internamente, restringindo o seu contexto
A maneira de introduzir definies locais utilizando a clusula where. Vamos
modificar o script acima para que quad s possa ser usado no interior de hipo.
hipo x y
= sqrt ( k1 + k2)
where
k1 = x * x
k2 = y * y
1
5
Note que apesar de x e y no serem parmetros de k1 e k2 eles foram
utilizados em suas definies. Isto possvel porque x e y tm validade em todo o
lado direito da definio.
Temos que considerar ainda que nada impede que em uma definio local
tenhamos uma outra definio local e dentro desta outra, e assim sucessivamente.
hipo x y
sqrt k
where
k = quad x + quad y
where
quad x = x * x
expresso
hipo 3 5 + hipo 4 4
sqrt (3 * 3 + 5 * 5) + hipo 4 4
sqrt (3 * 3 + 5 * 5) + sqrt (4 * 4 + 4 * 4)
reduo
aplicada
expresso
inicial
def de hipo
def de
quad
def de
quad
def de hipo
def de
quad
def de
8
9
10
11
12
13
14
15
16
sqrt (9 + 5 * 5) + sqrt (4 * 4 + 4 * 4)
sqrt (9 + 25) + sqrt (4 * 4 + 4 * 4)
sqrt 34 + sqrt (4 * 4 + 4 * 4)
5.83095 + sqrt (4 * 4 + 4 * 4)
5.83095 + sqrt (16 + 4 * 4)
5.83095 + sqrt (16 + 16)
5.83095 + sqrt (32)
5.83095 + 5.65685
11.4878
6
quad
*
*
+
sqrt
*
*
+
sqrt
+
1
7
Em Haskell poderamos ter a seguinte definio:
ma3 x y z = (x + y + z) / 3.
usual tambm dizer R X R X R R o tipo da funo ma3.
Para simplificar o trabalho com funes o matemtico Haskell Cury criou uma
nova notao, que considera que qualquer funo tem sempre um nico
parmetro de entrada. Segundo ele, o resultado de aplicar uma funo sobre um
parmetro produz uma nova funo que pode ser aplicada a outro parmetro, e
assim sucessivamente. Por exemplo, nesta notao, a funo ma3 teria a
seguinte assinatura:
ma3 :: R R R R
Podemos ler da seguinte maneira: ma3 uma funo que mapeia um numero real
em uma nova funo cuja assinatura :
ma3 :: R R R.
A funo ma3 por sua vez mapeia um nmero real em uma nova funo cuja
assinatura :
ma3 :: R R.
A funo ma3 por sua vez mapeia um nmero real em uma nova funo cuja
assinatura :
ma3 :: R.
Que uma funo constante.
Em captulos posteriores veremos as vantagens desta notao introduzida por
Haskell, conhecida por notao Curry. Por enquanto podemos afirmar que essa
facilidade vem do fato que nesta notao as funes possuem propriedades
equivalentes s dos dados.
1
8
3. A Arte de Resolver Problemas
3.1. INTRODUO: O grande objetivo deste curso criar oportunidades para que
o estudante desenvolva suas habilidades como resolvedor de problemas. Mais
especificamente estamos interessados na resoluo de problemas usando o
computador, entretanto, temos certeza, que as idias so gerais o suficiente para
ajudar a resolver qualquer problema.
Embora muitas pessoas j tenham discutido sobre este assunto ao longo da
histria, nosso principal referencial ser o professor George Polya, que escreveu
um livro sobre este assunto, com o mesmo nome deste captulo, voltado para a
resoluo de problemas de matemtica do ensino fundamental. Todos os alunos
deste curso tero grande proveito se lerem este livro.
As idias ali apresentadas com certeza se aplicam com muita propriedade
resoluo de problemas com o computador. Na medida do possvel estaremos
apresentando aqui algumas adaptaes que nos parecem apropriadas neste
primeiro contato com a resoluo de problemas usando o computador.
3.2. DICAS INICIAIS: apresenta-se a seguir algumas orientaes:
3.2.1. S se aprende a resolver problemas atravs da experincia. Logo o
aluno que est interessado em aprender deve trabalhar, buscando resolver por si
mesmo, os problemas propostos antes de tentar o auxlio do professor ou de outro
colega;
3.2.2. A ajuda do professor no deve vir atravs da apresentao pura e
simples de uma soluo. A ajuda deve vir atravs do fornecimento de pistas que
ajudem o aluno a descobrir a soluo por si mesmo;
3.2.3. muito importante no se conformar com uma nica soluo. Quanto
mais solues encontrar, mais hbil o estudante ficar, e alm disso, poder
comparar as vrias alternativas e escolher a que lhe parecer mais apropriada. A
escolha dever sempre ser baseada em critrios objetivos.
3.2.4. Na busca pela soluo de um problema, nossa ferramenta principal o
questionamento. Devemos buscar formular questes que nos ajudem a entender o
problema e a elaborar a soluo.
3.2.5. Aprenda desde cedo a buscar um aprimoramento da sua tcnica para
resolver problemas, crie uma sistematizao, evite chegar na frente de um
problema como se nunca tivesse resolvido qualquer outro problema. Construa um
processo individual e v aperfeioando-o cada vez que resolver um novo
problema.
3.3 COMO RESOLVER UM PROBLEMA: O professor Polya descreve a
resoluo de um problema como um processo complexo que se divide em quatro
etapas, as quais apresentamos aqui, com alguma adaptao. Segundo nos
recomenda Polya, em qualquer destas etapas devemos ter em mente trs
questes sobre o andamento do nosso trabalho, que so: Por onde comear esta
etapa? O que posso fazer com os elementos que disponho? Qual a vantagem de
proceder da forma escolhida?
1
9
Etapa 1 - Compreenso do Problema
impossvel resolver um problema sobre o qual no tenhamos um
entendimento adequado. Portanto, antes de correr atrs de uma soluo,
concentre-se um pouco em identificar os elementos do problema. Faa perguntas
tais como: Quais so os dados de entrada? O que desejamos produzir como
resultado? Qual a relao que existe entre os dados de entrada e o resultado a ser
produzido? Quais so as propriedades importantes que os dados de entrada
possuem?
Etapa 2 - Planejamento
Nesta fase devemos nos envolver com a busca de uma soluo para o
problema proposto. Pode ser que j o tenhamos resolvido antes, para dados
ligeiramente modificados. Se no o caso, pode ser que j tenhamos resolvido
um problema parecido. Qual a relao que existe entre este problema que temos e
um outro problema j conhecido? Ser que podemos quebrar o problema em
problemas menores? Ser que generalizando o problema no chegaremos a um
outro j conhecido? Conhecemos um problema parecido, embora mais simples, o
qual quando generalizado se aproxima do que temos?
Etapa 3 - Desenvolvimento
Escolhida uma estratgia para atacar o problema, devemos ento caminhar
para a construo da soluo. Nesta fase, devemos considerar os elementos da
linguagem de programao que iremos usar, respeitando os elementos
disponibilizados pela linguagem, tais como tipos, formas de definio,
possibilidades de generalizao e uso de elementos anteriormente definidos. A
seguir, devemos codificar cada pedao da soluo, e garantir que cada um esteja
descrito de forma apropriada. Em outras palavras, no basta construir, temos que
ser capazes de verificar se o resultado de nossa construo est correto. Isto
pode ser realizado pela identificao de instncias tpicas, da determinao dos
valores esperados por estas, da submisso dessas instncias ao avaliador e
finalmente, da comparao dos resultados esperados com os resultados
produzidos pela avaliao de nossas definies. Alm disso, devemos garantir
que a definio principal tambm est correta.
Em sntese, a fase de desenvolvimento compreende as seguintes subfases:
1. construo da soluo;
2. planejamento do teste;
3. teste com o computador de mesa;
4. codificao da soluo;
5. teste com o uso do computador.
Etapa 4 - Avaliao do Processo e seus resultados
O trabalho do resolvedor de problemas no pra quando uma soluo est
pronta. Devemos avaliar a qualidade da soluo, o processo que realizamos e
questionar as possibilidades de uso posterior da soluo obtida e tambm do
prprio mtodo utilizado. Novamente devemos fazer perguntas: Este foi o melhor
caminho que poderia ter sido usado? Ser que desdobrando a soluo no
obtenho componentes que poderei usar mais facilmente no futuro? Se esta
2
0
soluo for generalizada possvel reus-la mais facilmente em outras situaes?
Registre tudo, organize-se para a resoluo de outros problemas. Anote suas
decises, enriquea a sua biblioteca de solues e mtodos.
3.4. UM PEQUENO EXEMPLO:
Enunciado: Deseja-se escrever um programa que permita determinar a menor
quantidade de cdulas necessrias para pagar uma dada quantia em Reais.
Etapa 1 Compreenso
Questo: Quais os dados de entrada?
Resposta: A quantia a ser paga.
Questo: Qual o resultado a ser obtido?
Resposta: A menor quantidade de cdulas.
Questo: Qual a relao que existe entre a entrada e a sada?
Resposta: O somatrio dos valores de cada cdula utilizada deve ser igual
quantia a ser paga.
Questo: Existe algum elemento interno, ou seja, uma dado implcito?
Resposta: Sim, os tipos de cdulas existentes.Considere que o Real possui
apenas as seguintes cdulas: 1, 5, 10, 50 e 100. importante observar que
qualquer cdula um mltiplo de qualquer uma das menores.
Etapa 2 - Planejamento
Conheo algum problema parecido? Existe um problema mais simples?
Podemos entender como um problema mais simples um que busque
determinar quantas cdulas de um dado valor so necessrias para pagar a
quantia desejada. Por exemplo, para pagar R$ 289,00 poderamos usar 289
cdulas de R$ 1,00. Ou tambm poderamos usar 5 notas de R$ 50,00, mas
neste caso ficariam ainda faltando R$ 39,00. Claro que no queremos que
falte nem que sobre e, alm disso, desejamos que a quantidade seja mnima.
Parece uma boa estratgia comear vendo o que d para pagar com a
maior cdula e determinar quando falta pagar. O restante pode ser pago com
uma cdula menor, e por a afora. Explorando a instncia do problema j
mencionada, vamos fazer uma tabela com estes elementos.
Expresso para
determinar
a
Quantidade
quantidade de cdulas
cdulas
de um determinado
valor.
289 / 100
de
Quantia a Pagar
289,00
89,00
2
1
89/ 50
39/ 10
9/ 5
4/ 1
TOTAL
1
3
1
4
11
39,00
9,00
4,00
0,00
Etapa 3 - Desenvolvimento
Soluo 1 - Considerando a tabela acima descrita, codificando cada linha
como uma subexpresso da definio.
ncedulas q
(div q 100) +
(div (mod q 100) 50) +
(div (mod (mod q 100) 50) 10) +
(div (mod (mod (mod q 100) 50) 10) 5)+
(div (mod (mod (mod (mod q 100) 50) 10) 5) 1)
=
=
=
=
=
=
=
=
=
=
2
2
Supondo que no queremos generalizar todas as funes menores ainda
poderamos escrever o programa usando definies locais.
ncedulas q
2
3
O sbio comea pelo fim, o tolo termina no comeo.
Etapa 2 : Planejamento da soluo.
A perseverana a me da boa sorte.
No se derruba um carvalho com uma s machadada.
Se no princpio no conseguir, continue tentando.
Experimente todas as chaves do molho.
Veleja-se conforme o vento.
Faamos com pudermos se no pudermos fazer como queremos.
O sbio muda de opinio, o tolo nunca.
Mantenha duas cordas para um arco.
Faa e refaa que o dia bastante longo.
O objetivo da pescaria no lanar o anzol mas sim pegar o peixe.
O sbio cria mais oportunidades do que as encontra.
O sbio faz ferramentas daquilo que lhe cai s mos.
Fique sempre de olho na grande ocasio.
Etapa 3: Construo da soluo.
Olhe antes de saltar.
Prove antes de confiar.
Uma demora prudente torna o caminho seguro.
Quem quiser navegar sem risco, no se faa ao mar.
Faa o que puder e espere pelo melhor.
fcil acreditar naquilo que se deseja.
Degrau a degrau sobe-se a escada.
O que o tolo faz no fim, o sbio faz no princpio.
Etapa 4: Avaliao da soluo.
No pensa bem quem no repensa.
mais seguro ancorar com dois ferros.
Exerccios
1)
Compare as duas definies para a funo que descreve o nmero
mnimo de cdulas para pagar uma quantia q, ncedulas e ncedulas2;
2)
Desenvolva a soluo para o problema da cdulas considerando o
fato de que o Real possui notas de 2 e notas de 20. O que muda?
3)
Apresente trs problemas semelhante ao das cdulas;
2
4)
4
Desenvolva uma soluo para o problema considerando que para
cada tipo de cdula existe um quantidade limitada (maior ou igual a
zero);
2
5
4. ABSTRAO, GENERALIZAO, INSTANCIAO E MODULARIZAO
4.1. INTRODUO: Na busca por resolver um problema podemos usar vrios
princpios, cada um evidentemente ter uma utilidade para a resoluo do
problema, ou para garantia de sua correo ou ainda para facilitar os usos
posteriores da soluo que obtivermos. Apresentamos a seguir alguns deles.
4.2. ABSTRAO: Quando escrevemos uma expresso e no damos nome a
ela, o seu uso fica limitado quele instante especfico. Por exemplo, suponha que
desejamos determinar a hipotenusa de um tringulo retngulo com catetos 10 e 4.
Como conhecemos o teorema de Pitgoras (a2 = b2 + c2), podemos usar
diretamente nossa mquina funcional para avaliar a seguinte expresso:
> sqrt ((10.0 * 10.0)+ (4.0 * 4.0))
10.7703
>
A expresso que codificamos serve apenas para esta vez. Se em algum
outro instante precisarmos avalia-lateremos que codific-la novamente.
Para evitar isso, que damos nomes s nossas expresses, para que
possamos us-las repetidamente, apenas referenciando-as pelo seu nome. No
caso acima, poderamos escrever a definio:
hipotenusa = sqrt ((10.0 * 10.0)+ (4.0 * 4.0))
De posse dessa definio nossa mquina poder avaliar a expresso
sempre que dela precisarmos., basta escreve-la:
> hipotenusa
10.7703
Voc pode agora estar se perguntando, porque no trocamos a definio
para usar diretamente o valor 10.7703?
hipotenusa = 10.7703
Agindo assim a mquina no precisaria avaliar a expresso sqrt ((10.0 *
10.0)+ (4.0 * 4.0)) a cada uso. Por outro lado no ficaria registrada a origem do
valor 10.7703., com o tempo perderamos esta informao. De qualquer forma,
teramos criado uma abstrao qual denominamos hipotenusa.
Outra pergunta pode estar rondando a sua cabea, por que escrever uma
definio que sempre avaliada para o mesmo valor, por que no generaliza-la?
Bom, este foi apenas um recurso didtico para separar os dois conceitos, a
abstrao que acabamos de apresentar a generalizao que apresentaremos a
seguir. No entanto convm lembrar que algumas definies so realmente
constantes e que no so de grande utilidade, como o caso da seguinte definio:
2
6
pi = 3.1416
4.3. GENERALIZAO: Quando uma abstrao se aplica a vrios valores
podemos generaliz-la. Assim, alm de us-la vrias vezes para os mesmos
valores, podemos tambm us-la para valores diferentes. Esta ultima alternativa
evidentemente facilita o seu reuso.
Vamos apresentar duas formas para fazer isso.
a) Elaborando a definio usando outras definies constantes. Por exemplo,
no caso da definio acima para a hipotenusa, poderamos escrever as definies
a seguir:
b = 10.0
c = 4.0
hipotenusa = sqrt (( b * b) + ( c * c))
Aqui, hipo se aplica a dois valores quaisquer b e c, os quais so objetos de
outras definies.
b)Uma forma mais geral atravs do conceito de parametrizao. Esta
consiste em indicar no cabealho da definio (lado esquerdo da igualdade) quais
so os objetos da generalizao. Para o exemplo que estamos trabalhando,
podemos escrever:
hipotenusa b c = sqrt (( b * b) + ( c * c))
Temos ento descrito a funo paramtrica hipotenusa cujos parmetros
so b e c.
4.3.1 INSTANCIAO: A parametrizao permite que usemos a mesma definio
para diferentes instncias do problema. Por exemplo, suponha que desejamos
determinar a hipotenusa de trs tringulos retngulos. O primeiro com catetos 10 e
4, o segundo com catetos 35 e 18 e o terceiro com catetos 9 e 12. Podemos
instanciar a definio paramtrica para estabelecer a seguinte interao:
> hipo 10.0 4.0
10.7703
(5 reductions, 42 cells)
> hipo 35.0 18.0
39.3573
(5 reductions, 43 cells)
> hipo 9.0 12.0
15.0
(5 reductions, 38 cells)
>
2
7
4.4. MODULARIZAO: Em geral, nossos problemas no sero to simples e
diretos quanto o exemplo acima. Quando nos deparamos com problemas maiores,
um bom princpio :
Divida para facilitar a conquista.
Basicamente este princpio consiste em quebrar o problema inicial em
problemas menores, elaborar a soluo para cada um dos problemas menores e
depois combin-las para obter a soluo do problema inicial. A cada um dos
subproblemas encontrados podemos reaplicar o mesmo princpio. Segundo Polya,
esta uma heurstica muito importante qual ele denomina de Decomposio e
Combinao. Antes de pensar em codificar a soluo em uma linguagem de
programao especfica, podemos represent-la atravs de um esquema grfico
denominado de estrutura modular do problema (veja a representao para o
problema a seguir).
4.6. MODULARIZANDO: Considere o problema de descrever rea da figura Fig
4.1 abaixo.
2
8
Podemos fazer vrias tentativas, como por exemplo, as ilustradas nas figuras
Fig. 4.2 a, Fig. 4.2 b e Fig. 4.2 c.
a
b
c
Figura 4.2 Possveis subdivises do polgono
apresentado na Figura 4.1.
Podemos tentar descrever a rea das figuras menores em cada uma das
figuras apresentadas. Nas figuras 4.2. b e 4.2 c, parece que precisaremos
subdividir novamente. Em 4.2 b a casinha em verde pode ser transformada em um
retngulo e um tringulo. Em 4.2 c a casinha azul (meia-gua) que pode ser
dividida em um retngulo e um tringulo, como na Figura 4.3. E a figura Fig. 4 a,
que podemos dizer?
=
=
Quando escolhemos as reas acima citadas, no foi por acaso. A escolha foi
baseada na simplicidade do subproblema. Podemos usar este conhecimento para
chegar a um outro. Trs das reas que precisamos calcular so de forma
2
9
retangular. Ou seja, so especializaes de um conceito mais geral. A quarta
rea, tambm pode ser obtida pela especializao do conceito de tringulo
retngulo.
Vamos agora aproximar nossas definies da linguagem de programao.
Portanto podemos escrever:
a_retangulo x y = x * y
O
a_t_retangulo x y = (x * y) / 2.0
A determinao da rea vermelha nos traz uma pequena dificuldade, no
nos foi informado qual o comprimento da base do retngulo. E agora? Observando
bem a figura podemos concluir que a base do retngulo igual hipotenusa do
tringulo retngulo de catetos a e d.
Podemos escrever ento:
atotal a b c d e
a_azul x y z
hipo x y
a_retangulo x y
a_t_retangulo x y
=
=
=
=
=
3
0
Soluo 1: Vamos comear pela Figura 4.6. Uma rpida anlise nos leva a
identificar duas partes. Na parte inferior temos um paraleleppedo, sobre o qual se
assenta um cilindro. Vamos supor que so macios. Chamemos de a, b e c as
dimenses do paraleleppedo, de r o raio da base do cilindro e de h a sua altura. O
volume total da pea pode ser determinado pela soma do volume das duas peas
menores. Chamemos a funo de volfig46, e tentemos uma definio.
volfig46 a b c r h = (a * b * c) + (3.1416 * r * r * h)
3
1
Vamos ento tratar da pea descrita na figura 4.7. Agora identificamos uma
pea apenas. Um paraleleppedo com um furo no centro. Chamemos de a, b e c
as dimenses do paraleleppedo, de r o raio do buraco. Para descrever o volume
da pea devemos subtrair do volume do paraleleppedo o volume correspondente
ao buraco. Chamemos a funo de volfig47, e tentemos uma definio.
Volfig47 a b c r = (a * b * c) - (3.1416 * r * r * c)
Soluo 2: A soluo 1, apesar de resolver o problema, deixa de contemplar
algumas prticas importantes. No tratamento da primeira pea (Figura 4.6), apesar
de identificadas duas peas menores, estas abstraes no foram descritas
separadamente. Ou seja, deixamos de registrar formalmente a existncia de duas
abstraes e com isso no pudemos modularizar a descrio da funo principal.
Podemos tentar ento um outro caminho, contemplando as abstraes para o
cilindro e para o paraleleppedo:
volcil r h
volpar a b c
Volfig46 a b c r h
= 3.1416 * r * r * h
=a*b*c
= volpar a b c + volcil r h
= pi * r * r
3
2
aret a b = a * b
Podemos reescrever o volume do cilindro e do paraleleppedo da seguinte
maneira:
volcil r h = acir r * h
volpar a b c = aret a b * c
Soluo 3: Se aprofundarmos a anlise podemos observar que as duas
figuras podem ser abstradas como uma s! O cilindro que aparece na primeira,
como um volume que deve ser acrescentado pode ser entendido como o mesmo
cilindro que deve ser subtrado na segunda. Alm disso, podemos estender a
soluo para furos que no vazem a pea, pois a altura do cilindro pode ser
qualquer.
volfig a b c r h = volpar a b c + volcil r h
Podemos observar que esta a mesma definio apresentada anteriormente
para a figura 4.6. O que muda o uso. Para calcular o volume da Figura 4.6
usamos um h positivo e para Figura 4.7 um h negativo.
> volfig 6.0 8.0 2.0 2.0 5.0
158.832
> volfig 6.0 8.0 2.0 2.0 (-2.0)
70.8673
Exerccios:
1)
2)
3)
4)
5)
6)
3
3
5. Tipos de Dados Numricos
5.1. INTRODUO:
Denominamos de Tipo de Dado a um conjunto de valores, munido de um conjunto
de operaes sobre esses valores. Por exemplo, podemos denominar de T1 ao
tipo de dados formado por um conjunto S de valores idntico aos nmeros
naturais ( S = {0,1,2,3, ...]) e munido das operaes de adio (a) e multiplicao
(m). Cada operao possui uma tipo, indicando o domnio e o contradomnio. Por
exemplo, para o tipo T1, o domnio de a S X S e o contradomnio S. A notao
a seguir usualmente utilizada e em geral denominada de a assinatura da
operao.
a :: S X S S
m :: S X S S
Como visto no captulo 2, em Haskell escreveramos:
a :: S S S
m :: S S S
Em Haskell, conhecendo-se o tipo dos valores de uma expresso podemos
determinar o tipo do valor que dela resultar, ou seja, o seu contra-domnio. Em
linguagens de programao isto equivale a dizer que a linguagem fortemente
tipada. Dizemos ainda que os tipos so elementares ou estruturados. Os
numricos so elementares, assim como tambm o so os tipos lgico e os
caracteres. Neste captulo trataremos dos tipos numricos, os demais viro em
captulos posteriores.
Os nmeros formam um tipo de dados fundamental na computao. Aqui nos
interessa subdividi-los em inteiros e reais. Antes de irmos alm, importante que
se saiba que, sendo o computador composto de elementos finitos, algumas
adaptaes e simplificaes precisam ser feitas para o tratamento de nmeros.
Em HUGS, quando estamos submetendo expresses para avaliao, podemos
desejar que o tipo do resultado seja exibido. Para que isso ocorra, podemos dar
um comando ao HUGS. Para obtermos este comportamento do ambiente,
podemos usar o comando :set, que ativa ou desativa parmetros do ambiente.
Para ativiar um parmetro usamos uma letra correspondente ao parmetro,
precedido do smbolo +. Para desativar usamos o smbolos -. Para saber sobre
outros parametros, experimente submeter apenas o comando :set. A sequencia
de interaes a seguir ilustra a ativao e desativao da exibio do tipo dos
resultados.
> :set +t
> 2^20
3
4
1048576 :: Integer
> :set -t
> 2^100
1267650600228229401496703205376
3
5
O conjunto de operaes associadas ao domnio pode variar, entretanto, em
geral so fornecidas as seguintes operaes primitivas:
Nome
Descrio
Adio
Multiplicao
Subtrao
div
diviso inteira
Potncia
rem
mod
abs
valor absoluto
signum
Exemplos
> 13 + 15 + 21 + 24 + 27 + 31
131 :: Integer
> 20 * 10 * 98
19600 :: Integer
> 1234 - 4321
-3087 :: Integer
> div 12834 10
1283 :: Integer
> 2^20
1048576 :: Integer
> rem 12834 10
4 :: Integer
> rem (12834 10)
-4 :: Integer
> mod 12834 10
4 :: Integer
> mod (-12834) 10
6 :: Integer
> abs 123
123 :: Integer
> abs (-123)
123 :: Integer
> signum (-3888876527829798)
-1 :: Integer
> signum 0
0 :: Integer
> signum 3
1 :: Integer
3
6
tem precedncia sobre a adio (+) e portanto realizada antes da
adio. Esta precedncia pode ser modificada pelo uso de parntesis.
> (5 + 12) * 3
51 :: Integer
c) A operao div (diviso) parcial, ou seja, no se aplica quando o
denominador nulo. Quando submetemos uma expresso com esta
caracterstica, o HUGS no avalia a expreso e sinaliza que h um
erro.
> div 398 0
Program error:
divide by zero
> 0.1234567890123456789012345678901234567890::Float
0.1234568 :: Float
O conjunto de operaes aqui tambm pode variar, entretanto, em geral as
listadas no quadro abaixo so providas.
3
7
Nome
pi
+
*
/
^
sin
cos
tan
sqrt
log
exp
Descrio
Exemplos
> pi
3.14159265358979 :: Double
> 2.5 + 3.3216 + 0.389458
Adio
6.211058 :: Double
> 3.2 * 1.23 * 0.208
Multiplicao
0.818688 :: Double
> 3.456789 - 1.344499089877
Subtrao
2.112289910123 :: Double
> 9.345988 / 234569.34
Diviso
3.98431781408431e-005 :: Double
potncia (o expoente tem que ser Int > 1.5324^10
e positivo)
71.4038177956654 :: Double
> sin pi
Seno
1.22460635382238e-016 :: Doubl
> cos pi
Coseno
-1.0 :: Double
> tan ( pi / 4.0)
Tangente
1.0 :: Double
> sqrt 8.5
raiz quadrada
2.91547594742265 :: Double
> log 2.71828182845905
logaritmo na base e
1.0 :: Double
> exp 1.0
potncia na base e
2.71828182845905 :: Double
a constante 3.14159...
Da mesma forma como ocorre nos nmeros inteiros, nos reais tambm
podemos combinar operaes para construir operaes mais complexas. Tambm
vale para os reais a precedncia de operadores, como nos inteiros podemos usar
parntesis para controlar a ordem em que as operaes sero realizadas.
5.4. CONVERSO DE TIPOS: Em Haskell os inteiros so tratados como um
subconjunto dos reais. Assim, quando temos nmeros reais misturados com
nmeros inteiros em uma mesma expresso, os nmeros inteiros so
automaticamente tratados como reais.
>3+5
8 :: Integer
> 3 + 5.0
8.0 :: Double
Existem funes especficas para converso de tipos:
3
8
a) a funo truncate converte um real x para o menor inteiro menor ou igual x.
> truncate pi
3 :: Integer
b) a funo round converte um real x para o inteiro mais prximo de x, ou seja:
round x = truncate (x + 0.5)
> round pi
3 :: Integer
> round (exp 1)
3 :: Integer
3
9
comentrio: a ordem de avaliao foi alterada pelo uso dos parntesis. A
seqncia de avaliao portanto:
(2 + 3) * 5 5 * 5 25
> 3 * mod 10 4 + 5
11
comentrio: a primeira prioridade para avaliao do operador mod, seguida da
avaliao do operador * e finalmente do operador +. Podemos escrever a seguinte
seqncia de avaliao:
3 * mod 10 4 + 5 3 * 2 + 5 6 + 5 11
> 3 ^ mod 10 4
9
comentrio : A primeira avaliao do operador mod e em seguida avaliado o
operador ^. A seqncia de avaliao :
3 ^ mod 10 4 3 ^ 2 9
4
0
O uso adequado das noes de precedncia e associao serve tambm
para escrevermos expresses com economia de parntesis.
Observaes:
1. O operador unrio - deve ser sempre representado entre parnteses
quando utilizado junto com outro operador.
1. (- x)^y ou - (x^y) e nunca -x^y ou x^-y.
2. A exponenciao quando repetida em uma expresso avaliada da direita
para a esquerda.
1. 2^3^3 = 2^(3^3).
3. Os demais operadores, na situao acima, so avaliados da esquerda para
a direita.
1. 2 - 3 - 5 = (2 - 3) - 5
2. 2 + 3 + 3 = (2 + 3) + 3
Exemplos:
>3 - 7 - 2
-6
>3*7+4
25
> 3 * ( 7 + 4)
33
> 3 ^ ( 1 + 3)
81
5.6. TIPOS DE NOVAS DEFINIES: Ao definir novas funes, o fazemos
tomando por base os tipos de dados existentes na linguagem. O corpo dessas
definies tem por base a composio das operaes fornecidas por estes tipos
bsicos. Assim, o tipo do dado resultante da avaliao de uma aplicao desta
nova funo, pode ser antecipado por um analisador de tipos, antes mesmo de
avaliar a expresso.
Observe as duas definies a seguir:
media x y = (x + y) / 2
media' x y = truncate ((x + y) / 2)o tipo de dado resultante pela aplicao de
media real, uma vez que a operao / (diviso), s se aplica a nmeros reais.
Da mesma forma, o tipo resultante pela aplicao da funo media inteiro,
4
1
dado que a ultima operao a ser realizada, a truncate, converte reais para
inteiros.
Podemos conferir isso nas submisses de avaliao a seguir:
> media 3 4
3.5 :: Double
5.6. HIERARQUIA DE NMEROS: At agora dissemos que a linguagem Haskell
trabalha com dois tipos numricos, os reais e os inteiros. Isto uma verdade
irrefutvel. Ao avaliar uma expresso numrica o resultado ser sempre um
nmero real ou um nmero inteiro. Entretanto, para facilitar a construo de um
sistema de tipos adequado para a avaliao do tipo de uma expresso, antes
mesmo que ela seja avaliada, tornou-se necessrio a criao de uma hierarquia
de tipos, conforme mostraremos agora.
4
2
>
Exerccios
Qual o tipo resultante da avaliao da definio:
media' x y = div (x + y) 2
O que ocorre na avaliao de uma expresso que usa a definio:
media' x y = div (x + y) 2.0
4
3
6. EXPRESSES LGICAS E O TIPO BOOLEAN
4
4
pode ser avaliada imediatamente, conferindo o que elas afirmam com o mundo
sobre o qual elas se referem.
Sentenas Abertas: Um outro tipo de proposio importante so as sentenas
abertas. Nestas, alguns personagens no esto devidamente explicitados e,
portanto a sentena no pode ser avaliada. Quando tratamos sentenas abertas,
antes necessrio instanci-las para algum valor. Por exemplo, a sentena
matemtica,
x + 5 > 10
nem sempre verdadeira, depende do valor que atribuirmos varivel x. Quando
atribumos valores s variveis de uma sentena dizemos que estamos
instanciando a sentena.
No caso acima, podemos instanciar a sentena para os valores 3 e 10, entre
outros, obtendo as seguintes instncias:
1. 3 + 5 > 10
2. 10 + 5 > 10
Agora podemos avali-las e concluir que a segunda verdica e a primeira no.
O mesmo poderia ocorrer com afirmaes de outra natureza, como por exemplo:
4
5
fenmenos de um determinado universo. Elas so denominadas de palavras
lgicas, visto que a sua funo na linguagem possibilitar a articulao entre as
proposies do discurso.
A composio de uma proposio pode envolver vrias palavras lgicas, como
nos exemplos a seguir:
1. Dois menor que trs e maior que um mas no maior que a soma de
trs com dois;
2. Maria gosta de Pedro e de Joana mas no gosta de Antonio.
Avaliao de Sentenas Compostas: Para avaliar sentenas simples, vimos que
bastava inspecionar o mundo ao qual ela se refere e verificar se a situao
expressa pela sentena ocorre ou no. E como proceder para as sentenas
compostas? Um caminho que parece confivel apoiar essa avaliao no papel
representado por cada uma das palavras lgicas.
Assim, quando ao considerarmos a proposio:
Hoje fui ao cinema e ao teatro,
s poderemos dizer que ela verdica se tanto a proposio Hoje fui ao cinema
quanto a proposio Hoje fui ao teatro forem avaliadas como verdicas.
Para a proposio composta
Maria foi a missa ou ao cinema,
devemos consider-la como verdica se uma das duas proposies:
1. Maria foi a missa
2. Maria foi ao cinema
forem avaliadas como verdica. E se as duas forem avaliadas como verdicas? No
discurso cotidiano tendemos a pensar nesta situao como inverdica visto que
queramos uma ou outra. A linguagem natural no estabelece se devemos ou no
explicitar que no estamos falando do caso em que ambas podem ser
constatadas. Podemos assumir, portanto, que a nossa sentena composta usando
ou ser avaliada como verdica quando pelo menos uma das duas proposies
que a compe for avaliada com verdica.
No caso da sentena composta usando a palavra lgica no, como em
Hoje no choveu
diremos que ela ser avaliada como verdica quando a proposio Hoje choveu
no puder ser constatada e como inverdica no caso oposto.
4
6
6.3. O TIPO DE DADOS BOOLEAN: Podemos agora discutir sobre a natureza do
valor resultante da avaliao de uma sentena. A avaliao de natureza
funcional, ou seja, dada uma sentena s ela ser mapeada em um de dois valores
distintos. Ento, o contradomnio de uma avaliao um conjunto com apenas
dois valores, um para associar com avaliaes verdicas e outras com as
inverdicas. Podemos escolher um nome para esses valores. Historicamente, as
linguagens de programao os tem denominado de True e False. O primeiro para
associar com as proposies que podem ser constatadas no mundo considerado e
a segunda com as no constatveis.
O tratamento das proposies compostas pode tambm receber um
tratamento formal. Cada uma das palavras lgicas associamos uma funo
matemtica cujo domnio e contradomnio ser o conjunto que acabamos de
definir com as constantes True e False.
aval :: <sentena> {True, False}
Em Hugs nossos operadores so representados por:
Palavra
lgica
e
ou
no
Smbolo em
Hugs
&&
||
not
4
7
s2 s1 && s2
True
True
False False
True
False
False False
s1
True
True
False
False
s2
s1 || s2
True
True
False
True
True
True
False False
s1
not s1
True False
False True
exemplo
(2 + 3) == (8 3)
5 /= (4 * 2 -3)
(2 + 3) < 6
(2 * 3) <= 6
(4 + 2) > (2 * 3)
(8 3 * 2) >= (15 div 3)
resultado
True
False
True
True
False
False
4
8
> 5 > 4
True :: Bool
> 4 /= (5 + 3)
True :: Bool
> (mod 5 2) == (rem 5 2)
True :: Bool
> (mod (-5) 2) == (rem (-5) 2)
False :: Bool
> (div 5 2) <= truncate(5.0 / 2.0)
True :: Bool
par x = (mod x 2) == 0
Vejamos alguns exemplos ilustrados abaixo:
> par 5
False
> par 148
True
> par 0
True
> par (truncate ((5 + 2) / 2))
False
4
9
Outros exemplos de definies:
Verificar se a mltiplo
de b
Verificar se a divisor
de b
Verificar se uma
distncia d igual
diagonal de um
quadrado de lado a
Verificar se um nmero
um quadrado perfeito
Verificar se dois
nmeros a e b so
termos consecutivos de
uma P.A. de razo r
multiplo a b = (mod a b) == 0
divisor a b = multiplo b a
spa a b r = (a + r) == b
Verificar se um
determinado ponto do
pquad x y = (x > 0) && (y > 0)
espao cartesiano
est no primeiro
quadrante
Verificar se 3 nmeros
a, b e c, so lados de
um tringulo retngulo
5
0
Podemos modificar esta ordem utilizando parntesis como nas expresses
aritmticas. A expresso acima poderia ser reescrita como:
(P || Q) && R
E agora, para que ela seja avaliada para verdadeira preciso que R seja
avaliada para verdadeira.
Vejamos mais um exemplo de definio:
Verificar se x est fora
do intervalo definido por
fxab
= ((x <=a) || (x >= b)) && (a <= b)
a e b e a e b esto em
ordem no decrescente
Verificar se x menor
que a ou se x maior
g x a b = (x <=a) || (x >= b) && (a <= b)
que b e a e b esto em
ordem no decrescente
5
1
Para que um ponto esteja dentro do retngulo necessrio que sua
ordenada esteja entre as ordenadas dos dois cantos. Sabemos tambm que a
abscissa precisa estar entre as abscissas dos dois cantos. Isso basta? Para
combinar as solues percebemos que suficiente que as duas primeiras estejam
satisfeitas.
Etapa 3 [Construindo a Soluo] Construindo a soluo - Anteriormente j
elaboramos a definio de pertinncia a um intervalo linear, vamos us-la aqui.
pert x a b
=
(x>=a) && (x <= b)
pertinncia linear
pertinncia de
pertsup x y x1 y1 x2 y2 = (pert x x1 x2) && (pert y y2 y1)
superfcie
E o teste, para que valores interessam testar?
Etapa 4 [Analisando a Soluo]: Existem outras maneiras de resolver o
problema? Esta soluo se aplica as outras dimenses?
5
2
7. Definies Condicionais
5
3
contribuinte no paga imposto, e a partir de ento o rendimento dividido em
faixas (intervalos), aos quais se aplicam diferentes taxas. Suponha a tabela
hipottica abaixo.
Faixa
inferior ou igual a 10.800
entre 10.801 e 20.000
entre 20.001 e 30.000
acima de 30.000
alquota
0
10
20
25
Desconto
0
1000
1500
1800
5
4
<expresso lgica>
<expresso1> e
<expresso2>
Para a funo que calcula o valor da passagem area podemos ento construir a
seguinte definio:
vpass x = if x < 60 then 600 else 360
rvore de deciso: Podemos representar as expresses condicionais atravs de
uma notao grfica denominada de rvore de deciso. importante considerar
que este tipo de representao uma ferramenta importantssima para
estruturarmos a soluo de problemas que requerem expresses condicionais.
expresso
-x
x
5
5
Como s temos duas possibilidades, podemos codificar da seguinte maneira:
absoluto x
funo
ir1 s
ir2 s
ir3 s
ir4 s
ir s = if s <= 10800
then ir1
else if pert s 10800 20000
then ir2
else if pert s 20001 30000
then ir3
else ir4
where
ir1 = 0
ir2 = s * 0.1 - 1000
ir3 = s * 0.2 - 1500
ir4 = s * 0.25 - 1800
pert x a b = x>=a && x<=b
7.2.1 USANDO O IF
EXEMPLO 1: Considere um mapeamento de valores numricos onde o domnio
se divide em 4 regies, cada uma das quais possui diferentes formas de
mapeamento. As regies so apresentadas na figura abaixo, numeradas da
5
6
esquerda para direita. Observe ainda que as extremidades so abertas. Considere
ainda a seguinte tabela de associaes:
regio
regio 1
regio 2
regio 3
regio 4
mapeamento desejado
o dobro de x
o sucessor de x
o quadrado de x
o simtrico do quadrado de x
X<0
True
X < -15
True
False
False
X > 10
True
False
5
7
O que nos levar seguinte definio:
f x = if x < 0
then if x
then
else
else if x
then
else
<
2
x
<
x
-
(-15)
* x
+ 1
10
^2
(x ^ 2)
if a > b
then if a > c
then a
else
c
else if b > c
then
b
else
c
5
8
7.3 DEFINIES PROTEGIDAS (guarded commands): A estrutura IF foi
apresentada por primeiro por questes histricas, por tratar-se de uma forma
pioneira de escrever definies condicionais. Entretanto, algumas vezes podemos
lanar mo de estruturas mais simples e mais legveis.
As definies protegidas, tambm conhecidas por guarded commands permitem
que se escreva para uma mesma funo, vrias definies, cada uma delas
protegida por uma expresso lgica.
= <definio 1>
= <definio 2>
= <definio 3>
= <definio n>
= <definio n + 1> ]
A ltima clausula da definio opcional, por este motivo est apresentada dentro
de colchetes.
Vejamos como podemos reescrever a definio da nossa funo ir para clculo
do imposto de renda.
ir' s | s<=10800
= ir1
| pert s 10800 20000 = ir2
| pert s 20001 30000 = ir3
|otherwise
= ir4
where
ir1 = 0
ir2 = s * 0.1 - 1000
ir3 = s * 0.2 - 1500
ir4 = s * 0.25 - 1800
Exerccios
1. Reescreva, usando definies protegidas. a definio da funo que
determina o maior de 3 nmeros inteiros fornecidos.
5
9
8. O TESTE DE PROGRAMAS
8.1. INTRODUO: No basta desenvolver um programa para resolver um dado
problema. preciso garantir que a soluo esteja correta. Muitos erros podem
ocorrer durante o desenvolvimento de um programa e, portanto temos que garantir
que o programa que ir ser executado est livre de todos eles. Ao conceber a
soluo podemos nos equivocar e escolher caminhos errados, precisamos
eliminar esses equvocos. Ao codificarmos a nossa soluo podemos cometer
outros erros ao no traduzirmos corretamente nossa inteno. Esses erros podem
ocorrer por um mau entendimento dos elementos da linguagem ou at mesmo por
descuido, o certo que eles ocorrem. Uma estratgia muito til, mas no infalvel,
o teste de programa.
Em sua essncia, o teste de programa consiste em submeter um programa
ao exerccio de algumas instncias do problema e comparar os resultados
esperados com os resultados obtidos.
8.2. O PROCESSO DE TESTE: Em primeiro lugar devemos escolher as
instncias apropriadas, no basta escolh-las aleatoriamente. A seguir devemos
determinar, sem o uso do programa, qual o valor que deveria resultar quando o
programa for alimentado com essas instncias. O passo seguinte consiste em
submeter cada instncia ao programa e anotar o resultado produzido por ele.
Finalmente devemos comparar cada valor esperado com o valor produzido e
descrever qual o tipo de ocorrncia.
Um exemplo: Considere o problema de identificar se um dado ponto est
ou no localizado no primeiro quadrante do espao cartesiano. Considere ainda
que concebemos a seguinte definio:
primquad x y
6
0
x
-5
-2
5
resultado resultado
diagnstico
esperado obtido
-2
False
-5
False
5
True
y
6
1
seguida digitar e submeter esta mesma quantidade de instncias do problema
para o sistema e ainda depois conferir um a um os resultado obtidos com os
esperados. Enfim, um trabalho imenso. Imagine agora se fossem dois
parmetros? A quantidade de pares seria da ordem de 4.29497 x 10^09 (algo da
ordem de quatro bilhes). E para 3 parmetros? E para n parmetros? Nmeros
cada vez mais enormes. Por este caminho, testar programas seria invivel.
Felizmente no precisamos de todos eles, basta identificar as classes
distintas que importam para o problema, ou seja, as classes de equivalncia
relevantes. Isto pode ser obtido analisando o enunciado estendido do problema.
No caso de nosso exemplo anterior, analisando melhor a definio,
podemos identificar que por definio espao cartesiano se divide em quatro
regies. A primeira, onde ambos as coordenadas so positivas, denominamos de
primeiro quadrante. A segunda, onde a coordenada x negativa e a y positiva,
denominamos de segundo quadrante. O terceiro quadrante o espao onde
ambas as coordenadas so negativas. Ainda temos o quarto quadrante onde a
coordenada x positiva e a y negativa. E os pontos que ficam em um dos eixos
ou na interseo destes, qual a classificao que eles tm? Bom, podemos
convencionar que no esto em nenhum dos 4 quadrantes descritos. Resumindo,
nosso plano de teste deve contemplar estas situaes, conforme ilustra-se na
tabela a seguir.
x
positivo
negativo
negativo
negativo
nulo
qualquer
no nulo
nulo
y
quadrante
positivo
primeiro
positivo
segundo
negativo
terceiro
positivo
quarto
qualquer
eixo das ordenadas
no nulo
nulo
nulo
origem
bom observar ainda que este plano pode e deve ser preparado antes
mesmo de elaborar o programa, para faz-lo, precisamos apenas da especificao
detalhada. Alm disso, este plano no precisa ser feito pelo programador
responsvel pela elaborao da soluo, qualquer outro programador, de posse
do enunciado detalhado, pode se encarregar da tarefa. Este tipo de plano serve
para alimentar o teste denominado de caixa preta. Esta denominao se deve ao
fato de no ser necessrio conhecermos a estrutura da soluo para elaborar o
plano. Um outro aspecto positivo da elaborao do plano o mais cedo possvel
que contribu para um melhor entendimento do problema.
6
2
Voltando ao nosso exemplo, podemos agora elaborar a nossa planilha de
teste considerando as classes de equivalncia a serem definidas. Uma questo
que surge como escolhemos o representante de uma classe? Existem melhores
e piores? No nosso caso, como pode ser qualquer valor positivo ou negativo,
podemos escolher valores de um dgito apenas, no mnimo escreveremos e
digitaremos menos.
x
2
-2
-2
2
0
0
2
-2
0
3
3
-3
-3
3
-3
0
0
0
resultado
esperado
True
False
False
False
False
False
False
False
False
resultado
obtido
diagnstico
6
3
Voltemos agora para nossa planilha e vamos preench-la na coluna de resultado
obtido e diagnstico.
x
2
-2
-2
2
0
0
2
-2
0
resultado resultado
esperado obtido
3
True
True
3
False
False
-3
False
False
-3
False
False
3
False
True
-3 False
False
0
False
True
0
False
False
0
False
True
y
diagnstico
sucesso
sucesso
sucesso
sucesso
falha
sucesso
falha
sucesso
falha
Podemos ento modific-la para obter uma nova definio, que esperamos
que esteja correta.
6
4
primquad x y
6
5
9. RESOLVENDO PROBLEMAS - OS MOVIMENTOS DO CAVALO
m3
m3
m3
m3
m3
m3
m3
M3
m2
m4
m1
C
m5
m8
m6
m7
5
9.2. PROBLEMA 1: Escreva uma funo que determina se, a partir de uma dada
posio, o cavalo pode ou no realizar o primeiro movimento. Vamos cham-la de
pmov, e denominar seus parmetros (a posio corrente), de x e y. Eis alguns
exemplos de uso de nossa funo e os valores esperados:
instncia
pmov 5 4
pmov 8 1
pmov 1 1
pmov 1 8
resultado
True
False
True
False
6
6
9.2.2. TESTANDO A SOLUO - Como j discutimos anteriormente, para
verificar a correo de nossa soluo, devemos submet-la a um teste. Para tanto
devemos escolher as classes de equivalncias relevantes e, a partir delas,
produzir a nossa planilha de teste. Olhando para a especificao do problema,
podemos identificar 4 conjuntos de valores que se equivalem para os fins do
nosso programa, como podemos observar na figura abaixo:
8
7
6
5
4
3
2
1
1
=
=
=
=
=
=
=
=
=
=
=
f (x + 2 ) && f( y + 1)
f (x + 1) && f (y + 2)
g (x - 1) && f (y + 2)
6
7
qmov x y
qtmov x y
sxmov x y
stmov x y
omov x y
fw
gw
=
=
=
=
=
=
=
g (x - 2) && f (y + 1)
g (x - 2) && g (y 1)
g (x - 1) && g (y 2)
f (x + 1 ) && g (y 2)
f (x + 2) && g (y 1)
w <= 8
w >= 1
9.2.5. Anlise da Soluo - O que ser que ganhamos com esta nova forma
de descrever a nossa soluo? Podemos indicar pelo menos trs indcios de
vantagem na nova soluo:
1. Clareza - Na medida em que agora est explicitado, que todas as oito
funes para verificar os movimentos possuem estrutura semelhante e que
todas esto usando funes para verificar a ultrapassagem das bordas;
2. Manuteno - Se nosso tabuleiro mudasse, ou seja, passasse a ter 9 linhas
por nove colunas, bastaria alterar a funo f e tudo estaria modificado, ao
invs de termos que alterar as oito definies.
3. Reuso - As duas funes que testam as bordas poderiam ser usadas para
construir funes para avaliar o movimento de outras peas do jogo de
xadrez.
9.3. PROBLEMA 2: Sabemos que para cada posio alguns movimentos podem
ser realizados e outros no. Como ordenamos os movimentos no sentido antihorrio, gostaramos de obter, para uma dada posio, dos movimentos que
podem ser realizados, aquele que possui o menor ndice. Vejamos o esquema
abaixo.
8 m4
m1 m3 m3 C1
7
C3
m5
6 m5
m8
m6
5
m6
m7
4
3
m2
m3
2
m1
m4
1 C4
C2
1
2
3
4
5
6
7
8
Podemos observar que o cavalo C1 s pode fazer os movimentos m5 e m6
e que o de menor ndice m5. J o cavalo C2 s pode fazer os movimentos m3 e
m4 e que o de menor ndice o m3. Enquanto isso o cavalo C3 pode fazer os
6
8
movimentos m1, m4, m5, m6, m7 e m8. Para este caso o movimento de menor
ndice o m1.
Vamos chamar esta funo de qualmov e, como no problema anterior, os
parmetros sero as coordenadas da posio atual do cavalo. Eis alguns
exemplos de uso de nossa funo:
Instncia
qualmov 8 1
qualmov 8 8
qualmov 3 7
qualmov 1 1
resultado
3
5
1
1
6
9
= if pmov x y then 1
else if smov x y then 2
else if tmov x y then 3
else if qmov x y then 4
else if qtmov x y then 5
else if sxmov x y then 6
else if stmov x y then 7
else if omov x y then 8
else 0
7
0
caso, bastaria verificar se os dois esto no intervalo [1, 8]. Vamos construir aqui
uma funo que avalia a pertinncia de um valor a um intervalo numrico,
conforme definio a seguir:
pert x a b
= if not (pert x 1 8)
|| not (pert y 1 8) then 0
else if pmov x y then 1
else if smov x y then 2
else if tmov x y then 3
else if qmov x y then 4
else if qtmov x y then 5
else if sxmov x y then 6
else 7
7
1
Na verdade estamos interessados em destacar que a pequena diferena nos
nomes sugere que temos uma mesma funo e que existe um parmetro oculto.
Que tal explicit-lo? Podemos agora ter uma funo com 3 parmetros, sendo o
primeiro deles para indicar o nmero do movimento que nos interessa. A interface
agora seria:
mov m x y
Agora, por exemplo, para solicitar a avaliao do stimo movimento para um
cavalo em (3, 4), escrevemos:
? mov 7 3 4
True
?
Muito bem, e como codificaremos isso?
9.4.1. SOLUO - Precisamos encampar em nossa soluo o fato de que a
nossa funo possui diferentes formas de avaliao, para diferentes valores do
domnio, algo parecido com a soluo do problema 2, ou seja, a nossa funo no
continua e portanto temos que selecionar qual a definio apropriada para um
determinado valor de m. Devemos construir uma rvore de deciso. Aqui
deixamos esta tarefa a cargo do leitor e passamos direto codificao conforme
apresentamos a seguir:
mov m x y
= if not (pert m 1 8)
False
else if m == 1 then
else if m == 2 then
else if m == 3 then
else if m == 4 then
else if m == 5 then
else if m == 6 then
else if m == 7 then
else omov
where
pmov = ...
smov = ...
tmov = ...
...
then
pmov
smov
tmov
qmov
qtmov
sxmov
stmov
7
2
internas do problema e explor-las adequadamente. Qual a influncia desta ordem
na eficincia da avaliao de uma expresso submetida ao HUGS? Para
responder, basta lembrar que as condies so avaliadas seqencialmente. Por
exemplo, se m=8, teremos que avaliar 8 condies, se m=1 faremos 2 avaliaes
e se m est fora do domnio faremos uma avaliao. Ou seja, no pior caso
faremos 8 avaliaes e no melhor caso uma (1). Em mdia, ao longo do uso da
funo, assumindo uma distribuio uniforme dos valores de m, faremos 4
avaliaes. E se o intervalo fosse de 100 elementos distintos, quantas avaliaes
de condies faramos em mdia? Ser possvel elaborar solues onde este
nmero de avaliaes seja menor?
A resposta sim! J que a ordem das avaliaes no importa, podemos
buscar uma ordem mais conveniente para reduzir o nmero de avaliaes por
cada instncia avaliada.
A idia geral para estes casos obtida a partir de um conceito de vasta
utilidade na Computao. Falamos de rvore binria e o leitor por certo ouvir
falar muito dela ao longo da vida enquanto profissional da rea.
O caminho consiste em dividir intervalo considerado ao meio e fazer a
primeira pergunta, por exemplo, m<=4? Dividindo em 2 o intervalo de
comparaes, para cada um destes podemos novamente dividir ao meio, at que
no mais tenhamos o que dividir, como ilustramos no diagrama a seguir, onde
cada linha representa um passo da diviso dos intervalos.
<1
<1
<1
1
1
1
2
2
2
3
3
3
4
4
4
5
5
5
6
6
6
7
7
7
8
8
8
>8
>8
>8
7
3
A codificao ficar ento:
mov m x y = if not (pert m 1 8)
then False
else if m <= 4
then if m<= 2
then if m== 1
then pmov
else smov
else if m==3
then tmov
else qmov
else if m<= 6
then if m==5
then qtmov
else sxmov
else if m == 7
then stmov
else omov
where
pmov = ...
smov = ...
tmov = ...
...
esquema linear
(nmero mdio)
8
50
500
500000
esquema binrio
(nmero mximo)
4
7
10
20
7
4
10. TUPLAS
10.1. INTRODUO: At ento trabalhamos com valores elementares. Ou seja,
valores atmicos, indivisveis a nvel das operaes de seu tipo de dados. Por
exemplo, True, 523, 8.234, so valores elementares dos tipos Boolean, Integer e
Float, respectivamente. No podemos, por exemplo, nos referir, dentro da
linguagem, ao primeiro algarismo do valor 523. Dizemos que esses so tipos
primitivos da linguagem. Alm desses trs, o Hugs prov ainda o tipo char. O
elenco de tipos primitivos de uma linguagem pode ser entendido como o alicerce
da linguagem para a descrio de valores mais complexos, que so denominados
genericamente de valores estruturados.
Os problemas que pretendemos resolver esto em universos mais ricos em
abstraes do que esse das linguagens. Para descrever esses mundos,
precisamos usar abstraes apropriadas para simplificar nosso discurso. Por
exemplo, quando quero saber onde algum mora, eu pergunto: Qual o seu
endereo? Quando quero saber quando um amigo nasceu, eu pergunto: Qual a
data do seu nascimento? E quando quero saber para onde algum vai deslocar o
cavalo no jogo de xadrez, eu pergunto: Qual a nova posio? Os nomes
endereo, data e posio designam valores estruturados. Uma data tem trs
partes: dia, ms e ano. Um endereo pode ter quatro: rua, nmero, complemento
e bairro. J a posio no tabuleiro tem duas partes, linha e coluna.
Para possibilitar a descrio de valores dessa natureza, o Hugs dispe de
um construtor denominado tupla. Podemos definir uma tupla como um agregado
de dados, que possui quantidade pr-estabelecida de componentes (dois ou
mais), e onde cada componente da tupla pode ser de um tipo diferente (primitivo
ou no).
10.2. DEFINIO DO CONCEITO: A representao de uma tupla feita com a
seguinte sintaxe:
(t1, t2, t3, ..., tn)
Onde cada ti um termo da tupla.
Se Ti o tipo de ti, ento o universo de uma tupla dado por:
TT = T1 x T2 x ... x Tn
Sabendo-se que os conjuntos bases dos tipos Ti so ordenados, tambm os
elementos de TT o sero.
7
5
Exemplos de Tuplas:
1
2
Inteno
uma data
uma posio no
tabuleiro de xadrez
uma pessoa
4
5
6
7
um ponto no espao
uma carta de baralho
Representao
(15, 05, 2000)
(3, 8)
("Maria Aparecida", "solteira",
(3, 02, 1970))
(3.0, 5.2, 34.5)
(7, "espada")
(True, 3)
(False, div 5 2)
(x/=0 && y /= 0,
(x > y, if x*y /= 0
8
then if x > y
then div x y
else div y x
else 0)
(x, y, x + y)
7
6
triplaS a b = ( b, a, a + b )
7
7
Exemplo 4: Voltemos aos movimentos do cavalo no jogo de xadrez. Vamos
definir uma funo que produza a nova posio, usando o primeiro movimento
vlido segundo o que se discutiu em Resolvendo Problemas - Os Movimentos do
Cavalo.
qPos x y = if f x2 && f y1
then (x2,y1)
else if f x1 && f y2
then (x1,y2)
else if g x1e && f y2
then (x1e,y2)
else if g x2e && f y1
then (x2e,y1)
else if g x2e && g y1e
then (x2e,y1e)
else if g x1e && g y2e
then (x1e,y2e)
else if f x1 && f y2e
then (x1,y2e)
else (0,0)
where
x1
= x + 1
x2
= x + 2
y1
= y + 1
y2
= y + 2
x1e
= x - 1
x2e
= x - 2
y1e
= y - 1
y2e
= y - 2
f w
= w <= 8
g w
= w >= 1
7
8
Observe
a
elegncia
da
definio
da
tupla
(x1,
y1)!
Por anlise da definio, sabemos que o tipo de p1 e p2 tupla de 2 termos.
Quando submetemos a avaliao de uma instncia, o sistema casa p1 com um
par de valores e a partir da pode determinar o valor de cada termo de nossa tupla
(x1, y1).
? dist (0.0,0.0) (5.0,5.0)
-- o sistema casa p1 com (0.0,0.0)
-- e p2 com (5.0,5.0)
-- logo x1=0.0, y1=0.0, x2=5.0 e y2=5.0
7.07107
3. Explicitando os componentes:
dist (x1,y1) (x2,y2) = sqrt (dx^2 + dy^2)
where
dx
= x1 - x2
dy
= y1 - y2
7
9
11. VALIDAO DE DADOS
11.1. INTRODUO: Como sabemos, toda funo tem um domnio e um
contradomnio. Em Hugs, quando tentamos avaliar uma instncia de uma
definio, usando valores fora desse domnio, podemos receber como resposta
mensagens nem sempre esclarecedoras. Quando se trata do usurio de nosso
programa, esta situao se mostra mais indesejvel ainda. Aqueles que
constroem a definio podem discernir com mais facilidade a natureza dos
problemas que ocorrem durante o seu desenvolvimento. O mesmo no se pode
esperar de algum que no tem conhecimento dos elementos internos de nossas
definies.
Tipicamente os erros sero de duas naturezas. Pode ser que o tipo da
instncia esteja correto mas nossa definio use alguma funo primitiva que no
se aplica ao valor da instncia. Por exemplo, se temos a definio:
f x y z = div x y + z
f 5 1.0 3
1.0
Float
Int
8
0
11.2. CARACTERIZANDO A SITUAO - Voltemos definio anteriormente
apresentada:
f x y z = div x y + z
Neste caso, o tipo inferido pela linguagem para os dois primeiros parmetros
o tipo Integer, visto que o operador div s se aplica a valores deste tipo.
Portanto o universo ser formado por todos os possveis ternos de valores onde
os dois primeiros so do tipo Integer e o ltimo, do tipo obtido pela unio dos tipos
Float e Integer. Chamemo-lo de T. Entretanto, o domnio de nossa funo no
exatamente o conjunto de constantes de T, posto que a funo no est definida
para as constantes de T cujo segundo elemento nulo.
Desejamos construir uma funo que seja uma extenso da funo original e
ao mesmo tempo lhe sirva como uma casca de proteo contra as violaes de
domnio. Precisamos escolher um contradomnio da funo estendida (fx). Um
candidato natural o contradomnio da funo original (f).
E a imagem de nossa funo, o que podemos dizer dela? Ser que ela
igual ao contradomnio? Ou ser que temos um subconjunto para o qual no
exista um mapeamento?
11.3. CASO GERAL (IMAGEM IDNTICA AO CONTRADOMNIO): No caso
geral, podemos encontrar duas situaes: ou o contradomnio idntico
imagem, ou a determinao dos elementos que no pertencem imagem pode
no ser fcil. Com isto no dispomos de valores no contradomnio que possam ser
utilizados para mapearmos os valores que violam o domnio de f. Neste caso
podemos estender o contradomnio (CD) de tal modo que o novo escolhido
incorpore um valor que ser a imagem da extenso de f.
Uma soluo geral bastante conveniente construir um novo contradomnio
(NCD) para fx (extenso de f), formado por pares onde o primeiro elemento do
tipo boolean e o segundo do contradomnio de f. Temos ento a seguinte
estrutura:
8
1
NCD(fx) = (boolean, CD(f))
Para valores de x no domnio de f, teremos:
fx x = (True, fx )
Para os valores de x fora do domnio teremos:
fx x = (False, k )
onde k um valor qualquer pertencente ao contradomnio de f.
Para o nosso exemplo inicial teramos ento:
fx x y z = if invalido x y z
then (False,0)
else (True, f x y z)
where
invalido x y z = ...
f x y z = div x y + z
8
2
Podemos ento definir a funo movx da seguinte forma:
movx m x y = if not validom
then if not validop
then (3, False)
else (1, False)
else if not validop
then (2, False)
else (0, mov m x y)
8
3
11.6. UM EXEMPLO - RAIZES DE UMA EQUAO DO 2O. GRAU: Voltemos ao
problema de determinar as razes de uma equao do segundo grau. J sabemos
que elas so duas e que podemos fazer uma nica funo para descrev-las,
usando tupla.
Sabemos ainda que o universo definido pelos tipos dos 3 parmetros (a, b,
c), maior que o domnio da funo. Ou seja, a funo no est definida para
instncias de a, b e c, onde se verifica a seguinte desigualdade:
(b ^ 2) + (4 * a * c) < 0
11.7. Exerccios
1. Explique por que no existe o valor k que apie a definio da funo fx;
2. Jpojpoj
3. Pojpoj
4. Pojpoij
8
4
12. LISTAS
12.1. INTRODUO: A maioria dos itens de informao de nosso interesse esto
agrupados, dando origem a um conceito muito importante para a resoluo de
problemas, o agrupamento. Freqentemente estamos interessados em manipular
esses agrupamentos para extrair informaes, definir novos itens ou avaliar
propriedades desses agrupamentos.
Tratamos anteriormente das tuplas, que so agrupamentos de tamanho
predefinido e heterogneo, ou seja, cada elemento que participa do agrupamento
pode ser de um tipo diferente. Agora estamos interessados em explorar um outro
tipo de agregao, as listas. Este novo tipo, em HUGS, caracteriza-se por agregar
quantidades variveis de elementos desde que todos eles sejam de um mesmo
tipo.
Vivemos cercados de listas. Elas esto em qualquer lugar onde precisamos
registrar e processar dados. Vejamos alguns exemplos:
1. Lista de nmeros pares;
2. Lista dos livros lidos por uma pessoa;
3. Lista dos amigos que aniversariam em um dado ms;
4. Lista dos presidentes corruptos;
5. Lista dos vereadores decentes;
6. Lista das farmcias enganadoras;
7. Lista das disciplinas que j cursei;
8. Lista dos Lugares que visitei;
9. Lista dos nmeros feios;
10. Lista dos nmeros primos;
11. Lista das posies para as quais um cavalo pode se deslocar;
12. Lista das palavras de um texto;
13. Lista dos bug provocados pelo Windows;
14. Lista dos prmios Nobel ganhos pelo Bertrand Russel.;
15. Lista dos ttulos conquistados pelo Nacional Futebol Clube;
16. Listas dos funks compostos pelo Noel Rosa.
Destas, algumas so vazias, outras so finitas e algumas infinitas.
12.2. CONCEITOS BSICOS: Uma lista uma seqncia de zero ou mais
elementos de um mesmo tipo.
Entende-se por seqncia uma quantidade qualquer de itens dispostos
linearmente.
Podemos representar uma lista pela enumerao dos seus elementos,
separados por vrgulas e cercados por colchetes.
[ e1, e2, .., en]
8
5
Por exemplo:
1.
2.
3.
4.
5.
[]
[1,3,5,7,9]
['a', 'e', 'i', 'o', 'u']
[(22,04,1500), (07,09,1822), (31,03,1964)]
[[1,2,5,10], [1,11], [1,2,3,4,6,12], [1,13], [1,2,7,14], [1,3,5,15]]
8
6
Exemplos: abaixo listamos algumas submisses de listas definidas por intervalo e
as correspondentes respostas do sistema HUGS.
1 Prelude> [1..5]
[1,2,3,4,5]
2 Prelude> [-2..2]
[-2,-1,0,1,2]
3 Prelude> [10..5]
[]
4 Prelude> [-5.0..5.0]
[-5.0,-4.0,-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0,4.0,5.0]
5 Prelude> [-1..-5]
ERROR: Undefined variable "..-"
6 Prelude> [-1..(-5)]
[]
7 Prelude> [1.6..10.0]
[1.6,2.6,3.6,4.6,5.6,6.6,7.6,8.6,9.6]
8 Prelude> [1.5..10.0]
[1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5]
8
7
[5]
8 Prelude> [3,7..1]
[]
elem 5 [-5..15]
elem (-10) [-5..15]
elem 20 [-5..15]
elem 15 [-5..15]
8
8
1 Prelude> [3,4,6,74,45]!!0
3
2 Prelude> [3,4,6,74,45]!!4
45
3 Prelude> [1,5..20]!!3
13
4 Prelude> [[[1],[2,3,4]]]!!0!!1!!2
4
5 Prelude> [3,4,6,74,45]!!3
74
6 Prelude> [3,4,6,74,45]!!3 + [2,3]!!0
76
7 Prelude> [3,4,6,74,45]!!(0+1)
4
8 Prelude> [3,4,6,74,45]!!(i+j) where i=3; j=0
74
9 Prelude> [84,76,23,124,763,23]!!([0,1,2,3]!!2)
23
10 Prelude> [1,5..20]!!5
Program error: Prelude.!!: index too large
concat : descreve uma nova lista obtida pela concatenao de uma lista de
listas.
concat <lista de listas>
Exemplos:
1 Prelude>concat [[1..5],[1,10..100],[9]]
[1,2,3,4,5,1,10,19,28,37,46,55,64,73,82,91,100,9]
(473 reductions, 747 cells)
2 Prelude>concat [[1]]
[1]
(25 reductions, 35 cells)
3 Prelude> length (concat [[1..5],[1,10..100],[9]])
18
(451 reductions, 638 cells)
4 Prelude> concat [[length [10,87..500]], [length
[10,87,500]]]
[7,3]
(228 reductions, 309 cells)
5 Prelude> length (concat [[length [10,87..500]],
[length
[10,87,500]]])
2
(30 reductions, 35 cells)
8
9
1 Prelude> [1] ++ [1]
[1,1]
(33 reductions, 48 cells)
2 Prelude> [1] ++ []
[1]
(23 reductions, 33 cells)
3 Prelude> [ ] ++ [ ]
ERROR: Cannot find "show" function for:
*** Expression : [] ++ []
*** Of type
: [a]
4 Prelude> [1..5] ++ [1,10..100] ++ [9]
[1,2,3,4,5,1,10,19,28,37,46,55,64,73,82,91,100,9]
(467 reductions, 738 cells)
Teorema importante:
head xs : (tail xs) = xs
9
0
Teorema importante:
9
1
termos variveis que satisfazem condies de pertinncia estabelecidas pela
segunda parte.
expresso
varivel
pertinncia
x^2
x
x pertence a N e x <10
9
2
Por exemplo, se na expresso acima, primeiro colocssemos a expresso
booleana "odd x", o sistema acusaria um erro, visto que ao tentar a avaliar "odd x",
a varivel "x" ainda no estaria definida.
Prelude> [x | odd x, x<-[1,4..100]]
ERROR: Undefined variable "x"
[34,67,99,23,12,3,67,99]
9
3
Main> lmenor 100 [1,5,6,86,34,76,12,34,86,99]
[1,5,6,86,34,76,12,34,86,99]
9
4
--- Determinar a lista dos pontos do plano dentro da
-- regiao definida pela origem, a cordenada (eixo y)
-- 5 e a abscissa (eixo x) 3. Considere apenas os
-- pontos onde x impar e y par.
-pontos1 = [ (x,y) | x <- [0..3], odd x, y <- [0..5], even y ]
...
Main> pontos1
[(1,0),(1,2),(1,4),(3,0),(3,2),(3,4)]
-------
-paresE1
...
Main> paresE1
[(7,1),(13,1),(19,1),(25,1),(25,5),(31,1),(37,1),
(43,1),(49,1),(55,1),(55,5),(61,1),(67,1),(73,1),
(79,1),(85,1), (85,5),(85,17),(91,1),(91,13),(97,1)]
5
o predicado odd poderia ser colocado em qualquer lugar mais a frente,
entretanto o desempenho cairia, visto que iramos produzir valores
desnecessrios para "y";
a expresso (x/=1 || y/= 1) desnecessria visto que s ser falsa quando
ambos, x e y, forem iguais a 1, mas nesse caso eles sero iguais e portanto
falsificariam a expresso a seguir x/=y;
podemos reescrever a expresso x <- [1,4..100] de tal maneira que gere
apenas valores impares e assim descartar a expresso odd x. Para tanto
basta mudar a P.A. para [1,7..100];
pode-se observar que os valores de y que interessam so sempre menores
que os de x ( j que y divisor de x). Portanto, a segunda P.A poderia ser
substituda por [1,5..(x-1)]. Acontece que agora poderemos geram valores
para y maiores que 50 e isto no interessa. O que fazer? Que tal substitula por:
[1, 5..(if x < 50 then (x-1) else 50)]
9
6
Agora podemos ainda inspecionar o que de fato acontece com o
desempenho das trs verses.
Main> paresE1
[(7,1),(13,1),(19,1),(25,1),(25,5),(31,1),(37,1),(43,1),
(49,1),(55,1),(55,5),(61,1),(67,1),(73,1),(79,1),(85,1),
(85,5),(85,17),(91,1),(91,13),(97,1)]
(22894 reductions, 32210 cells)
Main> paresE2
[(7,1),(13,1),(19,1),(25,1),(25,5),(31,1),(37,1),(43,1),
(49,1),(55,1),(55,5),(61,1),(67,1),(73,1),(79,1),(85,1),
(85,5),(85,17),(91,1),(91,13),(97,1)]
(15124 reductions, 22014 cells)
redues clulas
22894 32210
15124 22014
16878 23992
...
main> paresE4
[(7,1),(13,1),(19,1),(25,1),(25,5),(31,1),(37,1),(43,1),
(49,1),(55,1),(55,5),(61,1),(67,1),(73,1),(79,1),(85,1),
(85,5),(85,17),(91,1),(91,13),(97,1)]
(16878 reductions, 23992 cells)
9
7
Na verdade podemos escrever uma descrio geral para take e drop usando
listas por compreenso. Alm disso, sabemos que a concatenao de take e drop
para um certo k, aplicado uma lista xs, igual prpria lista.
9
8
takeWhile pred xs - define uma lista com os primeiros elementos de uma lista xs
satisfazendo o predicado pred.
dropWhile pred xs - define uma lista com os elementos de xs, a partir do primeiro
elemento que no satisfaz o predicado pred.
Vejamos a ilustrao a seguir.
Prelude> takeWhile even [1..10]
[]
Prelude> takeWhile odd [1..10]
[1]
Prelude> dropWhile odd [1..10]
[2,3,4,5,6,7,8,9,10]
Prelude> dropWhile even [1..10]
[1,2,3,4,5,6,7,8,9,10]
Prelude> takeWhile (<5) [1..10]
[1,2,3,4]
Prelude> dropWhile (<5) [1..10]
[5,6,7,8,9,10]
Prelude> takeWhile (<5) [1..10] ++
dropWhile (<5) [1..10] == [1..10]
True
Exerccios:
Kjoj
Ionopi
Oijoip
Joij
Oioi
Iojo
9
9
13. Resolvendo Problemas com Listas
Neste captulos desenvolveremos a soluo para alguns problemas mais
complexos. A inteno apresentar o uso de estratgias de propsito geral que
podem ser teis na resoluo de novos problemas. Discutimos tambm algumas
questes relativas ao desempenho das solues.
13.1
1
00
outras palavras, podemos dizer que a coleo de elementos de S que so maiores
que seus sucessores vazia.
--- lista dos maiores que os sucessores
-lms1 xs = [ xs!!i | i <-[0..length xs j <-[i+1..length xs
xs!!i > xs!!j]
--- a seqncia est ordenada se a lista
-- que so maiores que algum sucessor
-ord1 xs = (lms1 xs) == []
...
2],
- 1],
dos elementos
vazia
1
01
Vejamos ento a implementao em Haskell e sua aplicao s mesmas
instncias do problema:
--- lista dos elementos maiores que o sucessor imediato
-lms2 xs = [ xs!!i | i <-[0..length xs - 2],
xs!!i > xs!!(i+1)]
-ord2 xs = (lms2 xs) == []
...
Main> ord2 [1..10]
True
(2236 reductions, 2885 cells)
Main> ord2 [10,9..1]
False
(314 reductions, 449 cells)
1
02
-- A nova funo para definir lista dos maiores
-- que os sucessores. Agora trabalharemos com os pares
-lms3 ps = [ (x,y) | (x,y) <- ps, x>y]
--- A nova verso de 'ord'
-ord3 xs = lms3 (adjacentes xs) == []
...
Main> ord3 [1..10]
True
(313 reductions, 483 cells)
Main> ord3 [10,9..1]
False
(82 reductions, 145 cells)
1
03
14. Paradigma Aplicativo
nova expresso
reduo
5 + 9 = 14
3 + 8 = 11
15 + 16 = 31
14 + 11 = 25
25 + 31 = 56
56
1
04
exemplo, da esquerda para a direita, usando em cada nova reduo o elemento
resultante da reduo anterior.
Expresso
nova expresso
Reduo
5 + 9 = 14
14 + 3 = 17
17 + 8 = 25
25 + 15 = 40
40 + 16 = 56
56
nova expresso
1
05
<alfa> -> <beta> -> <beta>
onde :
<alfa> pode ser do mesmo tipo de <beta>;
<beta> tem que ser do tipo dos componentes
da lista;
o valor especial do tipo <alfa>
OBS:
1. Os operadores infixados so indicados entre parntesis.
2. O valor especial o zero, visto que no desejamos que o valor
especial modifique o resultado da soma de todos os elementos.
Entretanto, ele joga um papel muito especial quando a lista for vazia.
prelude> sum []
0
1
Sabemos que: O fatorial de um nmero
ao produto de todos os nmeros naturais de 1 at n.
natural
n>0
06
igual
Exemplo 02: Podemos usar a disjuno (or) generalizada para definir uma
funo que avalia se em uma dada lista de nmeros pelo menos um deles
impar.
--- pelo menos um impar
-umImpar xs = or [odd x | x <- xs]
...
? umImpar [2,2,2,2,2,2,2,2]
False
? umImpar [2,2,2,1,2,2,2,2]
True
? umImpar []
False
1
07
--- menores descreve os elementos menores que um
-- dado x em uma lista xs
-menores x xs = [ y | y <- xs, y < x]
-- minimo descreve a sublista de xs dos elementos
-- que no possuem menores que eles em xs
-minimos xs = [ k | k <- xs, menores k xs == [] ]
--- Como eles so todos idnticos podemos tomar o
-- primeiro deles
-- como soluo de nosso problema.
-menorL0 xs = head (menores xs)
1
08
breve passagem pelo assunto, sem, contudo nos aprofundarmos nas questes de
eficincia, que central no seu estudo.
Ser que podemos usar o conceito de generalizao de uma operao para
descrever a ordenao de uma lista? Que operao seria essa?
14.4.1. INSERO EM LISTA ORDENADA - Vamos comear discutindo
uma outra questo mais simples: dada uma lista, com seus elementos j dispostos
em ordem no decrescente, como descrever uma lista na mesma ordem,
acrescida de um elemento tambm fornecido?
Podemos observar que se a lista xs est em ordem no decrescente, com
respeito ao elemento x (dado), podemos descrev-la atravs de dois segmentos:
xs = <menores que x> ++ <maiores ou iguais a x>
Para acrescentar x a xs, basta concatenar x entre os dois segmentos,
obtendo a nova lista ys, assim:
ys = <menores que x em xs> ++ [x] ++ <maiores ou iguais a x em xs>
--- insero ordenada
--insord xs x = takeWhile (< x) xs
++ [x]
++ dropWhile (< x) xs
...
Main> insord [] 10
[10]
(27 reductions, 49 cells)
Main> insord [10] 20
[10,20]
(54 reductions, 84 cells)
Main> insord [10,20] 30
[10,20,30]
(79 reductions, 119 cells)
Main> insord [10,20,30] 5
[5,10,20,30]
(71 reductions, 110 cells)
Main> insord [5,10,20,30] 25
[5,10,20,25,30]
(126 reductions, 183 cells)
1
09
paulatinamente construda, j ordenada. Vamos seguir o exemplo acima, onde
desejamos ordenar a lista [10,20,30,5,25]:
lista parcial
[]
[10]
[10,20]
[10,20,30]
[5, 10, 20, 30]
novo
elemento
10
20
30
5
25
reduo
[10]
[10,20]
[10,20,30]
[5, 10, 20, 30]
[5, 10, 20, 25, 30]
O ponto de partida, neste caso, a lista vazia. Vamos tomar ento a lista
vazia como o valor especial. Vejamos como fica ento nossa definio para
ordenao de listas.
--- ordenao
-ordena xs = foldl insord [] xs
...
Main> ordena [10,20,30,5,25]
[5,10,20,25,30]
(220 reductions, 344 cells)
Main> ordena [1..10]
[1,2,3,4,5,6,7,8,9,10]
(1055 reductions, 1505 cells)
Main> ordena [10,9..1]
[1,2,3,4,5,6,7,8,9,10]
(448 reductions, 712 cells)
14.5. INVERSO DE UMA LISTA: Dada uma lista xs, desejamos descrever a lista
formada pelos elementos de xs tomados em ordem inversa.
Para resolver o problema precisamos inventar uma funo bsica passvel de
generalizao.
Vamos comear descrevendo a funo insAntes.
1
10
--- Insere um elemento antes do primeiro elemento
-- de uma dada lista. Funo similar ao operador
-- (:) exceto pela ordem invertida dos parmetros
-insAntes xs x = x : xs
...
Main> insAntes [1..5] 0
[0,1,2,3,4,5]
(171 reductions, 255 cells)
Main> insAntes [] 0
[0]
(22 reductions, 29 cells)
novo
elemento
0
1
2
3
4
reduo
[0]
[1, 0]
[2, 1, 0]
[3, 2, 1, 0]
[4, 3, 2, 1, 0]
1
11
Observe a similaridade entre o desempenho da funo reverse, pr-definida,
com o desempenho da inverte que acabamos de definir.
Andamento
em xs
[2, 4, 6, 8]
[2, 4, 6, 8]
[ 4, 6, 8]
[ 4, 6, 8]
[6, 8]
[6, 8]
[ 8]
[]
Andamento
em ys
[1, 3, 5]
[3, 5]
[3, 5]
[5]
[5]
[]
[]
[]
Reduo
[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6, 8]
1
12
--- Descrio de um passo do Balance Line.
-- 1) Quando uma das duas listas for vazia a
-outras diretamente concatenada no final
-da lista em construo.
-passoBL (xs,ys,zs) = if (ys == [])
then ([],[],zs++xs)
else if (xs == [])
then ([],[],zs++ys)
else if (head xs <= head ys)
then (tail xs,ys,zs++[head xs])
else (xs, tail ys,zs++[head ys])
...
... aplicao sucessiva da funo passoBL intercalao
... das listas acima propostas
...
Main> passoBL ([2,4,6,8],[1,3,5],[])
([2,4,6,8],[3,5],[1])
(121 reductions, 219 cells)
Main> passoBL ([2,4,6,8],[3,5],[1])
([4,6,8],[3,5],[1,2])
(122 reductions, 222 cells)
Main> passoBL ([4,6,8],[3,5],[1,2])
([4,6,8],[5],[1,2,3])
(123 reductions, 225 cells)
Main> passoBL ([4,6,8],[5],[1,2,3])
([6,8],[5],[1,2,3,4])
(124 reductions, 228 cells)
Main> passoBL ([6,8],[5],[1,2,3,4])
([6,8],[],[1,2,3,4,5])
(128 reductions, 239 cells)
Main> passoBL ([6,8],[],[1,2,3,4,5])
([],[],[1,2,3,4,5,6,8])
(116 reductions, 223 cells)
...
Main> passoBL ([1..5],[],[])
([],[],[1,2,3,4,5])
(190 reductions, 329 cells)
Main> passoBL ([],[1..5],[])
([],[],[1,2,3,4,5])
(193 reductions, 339 cells)
Main> passoBL ([1..3],[4..5],[])
([2,3],[4,5],[1])
(219 reductions, 371 cells)
1
13
--- Funo para Intercalar duas listas ordenadas
-- 1) a funo passoBL repetidamente aplicada, sobre
-o resultado obtido no passo anterior;
-- 2) a funo passoBL binria, como exigido por foldl;
-- 3) a aplicao sucessiva controlada pelo comprimento
-da lista resultante;
-- 4) o resultado final obtido pela seleo do terceiro
-elemento da tripla atravs da primitiva "thd3"
-baLine xs ys = thrd3 (baLine3 xs ys)
-thrd3 (x,y,z) = z
-baLine3 xs ys = foldl passoBL (xs,ys,[]) [1..tr]
where
tr = (length xs)+(length ys)
--- Descrio de um passo do Balance Line.
-- 1) Quando uma das duas listas for vazia a
-outras diretamente concatenada no final
-da lista em construo.
-- 2) O parmetro k apenas para estabelecer o tipo
-binrio exigido por foldl
-passoBL (xs,ys,zs) k = if (ys == [])
then ([],[],zs++xs)
else if (xs == [])
then ([],[],zs++ys)
else if (head xs <= head ys)
then (tail xs,ys,zs++[head xs])
else (xs, tail ys,zs++[head ys])
...
Main> thrd3 (10,20,30)
30
(11 reductions, 12 cells)
Main> baLine3 [1..3] [4..6]
([],[],[1,2,3,4,5,6])
(514 reductions, 896 cells)
Main> baLine [1..3] [4..6]
[1,2,3,4,5,6]
(485 reductions, 784 cells)
Main> baLine [1..5] [3..7]
[1,2,3,3,4,4,5,5,6,7]
(807 reductions, 1326 cells)
Main> baLine [2, 4, 6, 8] [1, 3, 5]
[1,2,3,4,5,6,8]
(425 reductions, 696 cells)
Exerccios:
1. Sdknfvlnlc
2. Fsponmposfdnponsdf
3. psnmfdponmposds
1
14
15. Processamento de Cadeias de Caracteres primeiros passos
1
15
2 Main> f 5
(5,'a')
3 Main> f a
ERROR - Undefined variable "a"
4 Main> f 'a'
('a','a')
5 Main> f 'aa'
ERROR - Improperly terminated character constant
6 Main> f 'b'
('b','a')
7 Main> f a where a='a'
('a','a')
Letras
Maisculas
Letras
Minsculas
1
16
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
102
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
1
17
--- verifica se um dado smbolo letra
-letra x = (maiuscula x) || (minuscula x)
-maiuscula
x = pertence x ('A','Z')
minuscula
x = pertence x ('a','z')
pertence x (a,b) = (x >= a) && (x <= b)
Eis
mais
alguns
exemplos
de funes
com o tipo
char.
--
1
18
-- verifica se um smbolo uma letra vogal
-vogal x
= letra x && ocorre (caps x) vogais
where
vogais = ['A','E','I','O','U']
-ocorre x xs = or [x == y | y<- xs]
15.3. O TIPO STRING: Podemos agrupar tomos do tipo caracter (char) para
formar o que denominamos de cadeia de caracteres, usualmente chamadas de
"palavra". O mecanismo para agregar o construtor da lista. Podemos por
exemplo, escrever em HUGS a lista ['c','i','d','a','n','i','a'] para representar a palavra
cidadania.
Assim procedendo podemos escrever qualquer texto, uma vez que um texto
no nada mais nada menos que uma longa cadeia de smbolos envolvendo
letras e sinais de pontuao. A separao de palavras obtida pelo uso de um
caracter especial, denominado de espao, que tem representao interna igual a
32. Por exemplo, para representar a expresso "Vamos nessa!", usamos a lista:
['V','a','m','o','s',' ','n','e','s','s','a','!'].
1
19
Uma boa notcia que o HUGS nos proporciona uma maneira mais amistosa
para tratar com lista de caracteres. Em HUGS podemos representar uma lista de
caracteres, envolvendo a cadeia por aspas duplas, o que por certo, alm de mais
elegante e legvel, no poupa trabalho. Por exemplo, a cadeia acima representada
por ser tambm escrita na seguinte forma:
"Vamos nessa!"
uma lista de caracteres o HUGS associa um tipo sinnimo, denominado
string. Assim, as duas representaes acima so idnticas, conforme podemos
observar na avaliao abaixo:
Prelude> "Vamos nessa!" == ['V','a','m','o','s',' ','n','e','s','s','a','!']
True
(64 reductions, 102 cells)
1
20
Podemos observar que os smbolos usuais de separao (por exemplo, "," e
"!" so considerados como parte das palavras. Vamos agora construir uma funo
que considere os smbolos usuais de separao, alm do espao.
--- A funo palavras
-palavras xs = [ takeWhile letra x | x <- words xs]
---...
Main> palavras "Se temos que aprender a fazer, vamos aprender fazendo!"
["Se","temos","que","aprender","a","fazer","vamos","aprender","fazendo"]
(3869 reductions, 5444 cells)
Main> palavras "jose123 maria456 joana!!!"
["jose","maria","joana"]
(1445 reductions, 2081 cells)
Main> words "jose123 maria456 joana!!!"
["jose123","maria456","joana!!!"]
(951 reductions, 1423 cells)
Vamos construir uma nova funo ento onde isso possa ser resgatado.
--- A funo palavras1
-palavras1 xs = [ takeWhile alfa x | x <- words xs]
where alfa x = letra x || algarismo x
---...
Main> palavras1 "x123 y456 aux!!!"
["x123","y456","aux"]
1
21
Exerccios
Kjbkj
Kjn
Ono
Onoi
1
22
16. O PARADIGMA RECURSIVO
escada
escada
degrau
Figura 15.1 Uma escada
Fcil no ? Ser que isto basta? Onde est o truque? Parece que estamos
andando em crculo, no mesmo? Para entender melhor vamos discutir a seguir
alguns elementos necessrios para a utilizao correta da recurso na definio
de novas funes.
1
23
usaremos um que bastante familiar para alunos de cincias exatas. Estamos
falando da descrio do fatorial de um nmero. J vimos neste curso uma forma
de descrever este conceito dentro do HUGS quando estudamos o paradigma
aplicativo. Na oportunidade usamos a seguinte descrio:
n ! = 1 x 2 x 3 x ... x n
Em HUGS, como j vimos, teremos a seguinte definio:
--- definio (aplicativa) de fatorial
-fat n = product [1..n]
...
? fat 5
120
? fat 0
1
? fat 1
1
H uma outra forma de definir, tambm familiar aos alunos do primeiro ano
universitrio:
O Fatorial de um nmero natural n igual ao produto deste nmero pelo fatorial
de seu antecessor.
Novamente, sendo mais formal, podemos escrever:
n ! = n x (n - 1) !
E em HUGS, como ficaria? Que tal a definio a seguir?
--- definio recursiva de fatorial
-fat n = n * fat (n - 1)
1
24
Main> fat 5
(23967 reductions, 47955 cells)
ERROR: Control stack overflow
1
25
Pelo visto agora deu tudo certo.
16.3. ELEMENTOS DE UMA DESCRIO RECURSIVA: Em uma descrio
recursiva devemos ter em conta certo elementos importantes. fundamental que
todos eles sejam contemplados para que nossas descries estejam corretas. O
exemplo anteriormente apresentado suficiente para ilustrar todos eles. Vamos
ento discuti-los:
Definio geral : Toda definio recursiva tem duas partes, uma delas se
aplica a um valor qualquer do domnio do problema, denominamos de geral. Esta
tem uma caracterstica muito importante, o conceito que est sendo definido deve
ser utilizado. Por exemplo, para definir fatorial de n, usamos o fatorial do
antecessor de n. Observe aqui, entretanto que o mesmo conceito foi utilizado, mas
no para o mesmo valor. Aplicamos o conceito a um valor mais simples, neste
caso o antecessor de n.
Definio independente : A outra parte da definio destinada ao
tratamento de um valor to simples que a sua definio possa ser dada de forma
independente. Este elemento tambm conhecido como base da recurso. No
caso do fatorial, o valor considerado o zero.
Obteno de valores mais simples : Para aplicar o conceito a um valor
mais simples precisamos de uma funo que faa este papel. No caso do fatorial,
usamos a subtrao de n por 1, obtendo assim o antecessor de n. Em cada caso,
dependendo do domnio do problema e do problema em si, precisaremos
encontrar a funo apropriada.
Funo auxiliar : Na definio geral, para obter um valor usando o valor
considerado e o valor definido recursivamente, em geral faz-se necessrio o uso
de uma funo auxiliar. Algumas vezes esta funo pode ser originada a partir de
um conceito aplicvel a dois elementos e que desejamos estender aos elementos
de uma lista. Um exemplo o caso da somatria dos elementos de uma lista,
como veremos adiante. No caso do fatorial esta funo a multiplicao.
Garantia de atingir o valor independente : fundamental que a aplicao
sucessiva da funo que obtm valores mais simples garanta a determinao do
valor mais simples. Este valor tambm denominado de base da recurso. Por
exemplo, no caso do fatorial, sabemos que aplicando a subtrao sucessivas
vezes produziremos a seqncia:
n, (n-1), (n-2), ... 0
Esta condio fundamental para garantir que ao
avaliarmos uma expresso atingiremos a base da recurso.
Voltemos definio do fatorial para destacarmos os elementos acima
citados, como podemos observar no quadro esquemtico a seguir:
1
26
fat 5
passo
Reduo
Justificativa
1
27
0 fat 5
1 5 * fat 4
2 5*(4 * fat 3)
3 5*(4* (3 * fat 2))
4 5*(4*(3*(2 * fat 1)))
5 5*(4*(3*(2*(1 * fat 0)
6 5*(4*(3*(2*(1 * 1))))
7 5*(4*(3*(2*1)))
8 5*(4*(3*2)
9 5*(4*6)
10 5 * 24
11 120
expresso proposta
substituindo fat por sua definio
geral
Idem
Idem
Idem
Idem
usando a definio especfica
usando a primitiva de multiplicao
Idem
Idem
Idem
Idem
1
28
Esta natureza recursiva das listas nos oferece uma oportunidade para, com
certa facilidade, escrever definies recursivas. A tcnica consiste basicamente
em:
1. Obter a definio geral: isto consiste em identificar uma
operao binria simples que possa ser aplicada a dois
valores. O primeiro deles o primeiro (head) da lista e o
outro um valor obtido pela aplicao do conceito em
definio ao resto (tail) da lista;
2. Obter a definio independente, que se aplicar base da
recurso. Esta, em geral, a lista vazia;
3. Garantir que a aplicao sucessiva do tail levar base da
recurso.
Na Figura 15.2 ilustramos o processo recursivo de obter listas cada vez
menores, atravs da aplicao da funo tail. Ao final do processo obteremos a
lista vazia ([ ]).
[xo, x1, x2, x3, x4 ... xn-1]
head
tail
...
xn-1 [ ]
Figura 15.2 componentes recursivos de uma lista
Exemplo 01 - Descrever o somatrio dos elementos de uma lista.
Soluo - Podemos pensar da seguinte maneira: o
somatrio dos
elementos de uma lista igual soma do primeiro elemento da lista como o
somatrio do resto da lista. Alm disso, o somatrio dos elementos de uma lista
vazia igual a zero.
1
29
somat [xo, x1, x2, x3, x4 ... xn-1]
xo + somat [x1, x2, x3, x4 ... xn-1]
X0 + x1 + somat [x2, x3, x4 ... xn-1]
X0 + x1 + x2 + somat [x3, x4 ... xn-1]
X0 + x1 + x2 + x3 + somat [x4 ... xn-1]
X0 + x1 + x2 + x3 + somat [x4 ... xn-1]
... [... x ]
X0 + x1 + x2 + x3 + x4 + somat
n-1
X0 + x1 + x2 + x3 + x4 + ... + xn-1+ somat [ ]
X0 + x1 + x2 + x3 + x4 + ... + xn-1 + 0
Figura 15.2 desenvolvimento da computao de
somatrio dos elementos de uma lista
Vejamos ento a codificao:
--- definio recursiva da somatria dos
-- elementos de uma lista
-somat xs = if null xs
then 0
else head xs + somat (tail xs)
1
30
maximo [xo, x1, x2, x3, x4 ... xn-1]
maior( xo , maximo [x1, x2, x3, x4 ... xn-1] )
maior( xo , maior(x1, maximo [x2, x3, x4 ... xn-1])) ))
maior( xo , maior(x1, maior(x2, maximo [x3, x4 ... xn-1] )))
maior( xo , maior(x1, maior(x2, maior(x3, maximo [x4 ... xn-1] ))))
maior( xo , maior(x1, maior(x2, maior(x3, maior(x4, ... maximo[xn-2 , xn-1])))))
maior( xo , maior(x1, maior(x2, maior(x3, maior(x4, ... maior(xn-2 , maximo[ xn-1])))))
maior( x15.3
, maior(x
, maior(x2, maior(x3,da
maior(x
, ... maior(x
x ))))))
Figura
desenvolvimento
computao
don-2 elemento
mximo
o
1
4
, n-1
de
uma lista
1
31
Soluo : Podemos pensar da seguinte maneira: Um dado elemento k
ocorre em uma lista se ele igual ao primeiro elemento da lista ou se ele ocorre
no resto da lista. Em uma lista vazia no ocorrem elementos quaisquer (Figura
15.4).
E algumas submisses:
Main> ocorre 5 [8,65,46,23,99,35]
False
(71 reductions, 111 cells)
Main> ocorre 5 [8,65,46,5,23,99,35]
True
(47 reductions, 58 cells)
Main> ocorre 5 [ ]
False
(16 reductions, 30 cells)
1
32
Exemplo 04 - Descrever a funo que obtm de uma lista xs a sublista
formada pelos elementos que so menores que um dado k :
Soluo : Precisamos descrever uma nova lista, vamos denomin-la de
menores, em funo de xs e de k. Quem ser esta nova lista? Se o primeiro
elemento de xs for menor que k, ento ele participar da nova lista, que pode ser
descrita como sendo formada pelo primeiro elemento de xs seguido dos menores
que k no resto de xs. Se por outro lado o primeiro no menor que k, podemos
dizer que a lista resultante obtida pela aplicao de menores ao resto da lista.
Novamente a base da recurso definida pela lista vazia, visto que em uma lista
vazia no ocorrem elementos menores que qualquer k.
A codificao apresentada a seguir:
--- define a lista de menores que um dado elemento em
-- uma lista dada
-menores k xs = if null xs
then xs
else if head xs < k
then head xs : menores k (tail xs)
else menores k (tail xs)
1
33
1. O primeiro elemento da lista um nmero par, neste caso a sublista
resultante dada pela juno do primeiro com a sublista de pares existente
no resto da lista.
2. O primeiro no par. Neste caso a sublista de pares em xs obtida pela
seleo dos elementos pares do resto de xs.
Concluindo, tomemos como base da recurso a lista vazia, que obviamente
no contm qualquer nmero.
Eis a soluo em HUGS:
--- sublista de nmeros pares
-slpares xs = if null xs
then xs
else if even (head xs)
then head xs : slpares (tail xs)
else slpares (tail xs)
1
34
--- sublista de nmeros pares
-slpares xs = if null xs
then xs
else if even (head xs)
then head xs : slpares (tail xs)
else slpares (tail xs)
--- sublista de nmeros impares
-slimpar xs = if null xs
then xs
else if odd (head xs)
then head xs : slimpar (tail xs)
else slimpar (tail xs)
--- sublista de nmeros primos
-slprimo xs = if null xs
then xs
else if primo (head xs)
then head xs : slprimo (tail xs)
else slprimo (tail xs)
Isto nos sugere que a funo avaliadora pode ser um parmetro. Pois bem,
troquemos ento o nome da funo por um nome mais geral e adicionemos sua
interface mais uma parmetro. Este parmetro, como sabemos, dever ser do
tipo:
1
35
Main> sublista even [1..10]
[2,4,6,8,10]
Main> sublista odd [1..10]
[1,3,5,7,9]
Main> sublista (<5) [1..10]
[1,2,3,4]
Main> sublista (>=5) [1..10]
[5,6,7,8,9,10]
1
36
insord k Xs =
k < x0
k : Xs
1
37
E a seguir algumas aplicaes da soluo:
Main> insord 5 [0,2..10]
[0,2,4,5,6,8,10]
(230 reductions, 407 cells)
Main> insord 5 [10,15..50]
[5,10,15,20,25,30,35,40,45,50]
(248 reductions, 379 cells)
Main> insord 5 [-10,15..0]
[-10,5]
(92 reductions, 135 cells)
Main> insord 5 [-10,-5..0]
[-10,-5,0,5]
(154 reductions, 220 cells)
Main> insord 5 []
[5]
(23 reductions, 32 cells)
1
38
17.2 DIVISO E CONQUISTA (UMA TCNICA PODEROSA): Alguns problemas
possuem solues mais facilmente descritas, algumas at mais eficientes, quando
quebramos o problema em partes menores, descrevemos a soluo de cada parte
e depois combinamos as solues parciais para obter a soluo completa. Este
mtodo denominado de "diviso e conquista". Basicamente buscamos encontrar
instncias do problema onde a soluo seja imediata. . Nesta seo veremos
alguns exemplos desta abordagem. O primeiro deles, a pesquisa binria, trata da
busca de um elemento em uma lista ordenada. Os outros dois, mergesort e
quicksort, apresentam solues alternativas para a ordenao de uma lista.
17.2.1. PESQUISA BINRIA - Voltemos a um problema j apresentado
anteriormente, verificao da ocorrncia de um elemento a uma lista. Segundo a
definio que apresentamos para a funo ocorre, apresentada no exemplo 3 do
Captulo 16. Podemos constatar que para avaliar expresses onde o elemento
procurado no ocorre na lista, o avaliador de expresses precisar fazer uma
quantidade de comparaes igual ao comprimento da lista considerada. Na mdia
de um conjunto de avaliaes, considerando as avaliaes de expresses em que
o elemento procurado est na lista, e que a cada vez estaremos procurando por
um elemento distinto, teremos um nmero mdio de comparaes da ordem de
(n / 2). Se n for muito grande ficaremos assustados com o nmero de
comparaes. Por exemplo, para uma lista de 1000000 (um milho) de elementos,
em mdia teremos que fazer 500 mil comparaes.
Se pudermos garantir que a lista est ordenada, ento podemos fazer uso de
uma estratgia j discutida anteriormente para reduzir este nmero. Estamos
falando da rvore binria de pesquisa. A estratgia que usaremos consiste em, a
cada passo de reduo, abandonarmos metade da lista considerada a partir da
comparao de k com o elemento que se encontra na metade da lista. Se o
elemento buscado (k) for igual ao elemento central, ento o processo de avaliao
est encerrado. Quando isto no ocorre, devemos ento escolher em qual lista
devemos procur-lo. Quando ele menor que o elemento central devemos busclo na sublista que antecede o central, caso contrrio devemos busc-lo na sublista
dos seus sucessores. Novamente a base da recurso determinada pela lista
vazia.
Nesta abordagem, a cada escolha abandonamos metade da lista restante.
Desta forma, o nmero de comparaes dado pelo tamanho da seqncia:
n/1, n/2, n/4, ... , n/n
Para simplificar a anlise podemos escolher um n que seja potncia de 2.
Neste caso podemos assegurar que o comprimento da seqncia dado por:
Log n na base 2
1
39
Voltando ento ao nmero de comparaes necessrias para localizar um
elemento, podemos constatar que em uma lista com 1 milho de elementos, ao
invs das 500 mil comparaes da soluo anterior, precisaremos no pior caso, de
apenas 20 comparaes. Isso mesmo, apenas 20.
Vamos ento codificao em HUGS:
--- pesquisa binria
-pesqbin k xs = if null xs
then False
else if k == pivot
then True
else if k < pivot
then pesqbin k menores
else pesqbin k maiores
where
p
= div (length xs) 2
menores = take p xs
maiores = tail (drop p xs)
pivot
= head (drop p xs)
1
40
A codificao resultante pode ser observada a seguir:
--- Intercala duas listas em ordem no decrescente
-intercala xs ys = if (null xs) || (null ys)
then xs ++ ys
else if head xs <= head ys
then head xs : intercala (tail xs) ys
else head ys : intercala xs (tail ys)
1
41
1
42
Main> mergesort [1..10]
[1,2,3,4,5,6,7,8,9,10]
(1593 reductions, 2185 cells)
Main> mergesort [10,9..1]
[1,2,3,4,5,6,7,8,9,10]
(1641 reductions, 2236 cells)
1
43
1
44
Vejamos a avaliao de algumas instncias:
Main> quicksort [4,5,6,7,8,3,2,1]
[1,2,3,4,5,6,7,8]
(595 reductions, 755 cells)
Main> quicksort [1..10]
[1,2,3,4,5,6,7,8,9,10]
(1536 reductions, 1881 cells)
Main> quicksort [10,9..1]
[1,2,3,4,5,6,7,8,9,10]
(1541 reductions, 1952 cells)
Main> mergesort [10,9..1]
[1,2,3,4,5,6,7,8,9,10]
(1647 reductions, 2283 cells)
Main> mergesort xs == quicksort xs where xs = [1..10]
True
(2805 reductions, 3563 cells)
Main> mergesort [2,14,16,23,29,35,47,68,70,90]
[2,14,16,23,29,35,47,68,70,90]
(1414 reductions, 1922 cells)
Main> quicksort [2,14,16,23,29,35,47,68,70,90]
[2,14,16,23,29,35,47,68,70,90]
(1357 reductions, 1618 cells)
Main> ordena [2,14,16,23,29,35,47,68,70,90]
[2,14,16,23,29,35,47,68,70,90]
(236 reductions, 336 cells)
1
45
palndromo [x0, x1, x2, x3, x4, x5, ..., x n-1]
x0 = x n-1 & palndromo [x1, x2, x3, x4, x5, ..., ]
x0 = & (x1 = x n-1 & palndromo [ x2, x3, x4, x5, ..., ] )
x0 = & (x1 = x n-1 & ( X2 = Xn-2 & palndromo [x3, x4, x5, ..., ] ))
Figura 17.1 desenvolvimento da computao da funo
palndromo
1
46
Exemplo 02 - [Prefixo] Dadas duas cadeias de caracteres verifique se a
primeira idntica subcadeia formada pelos primeiros caracteres da segunda.
Por exemplo, "aba" prefixo da cadeia "abacaxi" e "pre" prefixo de "prefixo".
Soluo : De imediato podemos dizer que uma cadeia xs prefixo de uma
cadeia ys quando:
i)
ii)
iii)
1
47
Exemplo 03 - [Casamento de Padro] Verificar se uma cadeia satisfaz um
determinado padro um processamento muito til e constantemente realizado na
prtica da computao. Aqui nos ateremos a uma forma simplificada deste
problema que consiste em verificar se uma cadeia subcadeia de outra.
Soluo : Uma rpida inspeo nos leva constatao de que o problema
anterior parecido com este, exceto pelo fato de que a primeira cadeia pode
ocorrer em qualquer lugar da segunda. Podemos dizer ento que a primeira
cadeia ocorre na segunda se ela um prefixo da primeira ou se ela ocorre no
resto da segunda.
Vejamos como fica em HUGS:
--- Verifica se uma cadeia
-- de uma outra (ys)
-subcadeia xs ys = if null
then
else
xs subcadeia
ys || null (tail ys)
False
prefixo xs ys || subcadeia xs (tail ys)
Exerccios:
i)
ii)
iii)
iv)
v)
vi)
Jonoihoi
Ionoihno
Noinboiho
Oioho[
Oihnoihjo
Oinoihjpo
1
48
1
49
5. Dados trs nmeros inteiros distintos, calcule o quadrado do sucessor do maior
nmero.
6. Dados 3 pontos p1, p2 e p3, do plano cartesiano, determine se eles formam
um tringulo, e se for o caso,determine sua rea.
7. A empresa LucroCerto decidiu dar aos seus funcionrios um abono de Natal. A
gratificao ser baseada em dois critrios: o nmero de horas extras
trabalhadas e o nmero de horas que o empregado faltou ao trabalho. O
critrio estabelecido para calcular o prmio : subtrair dois tros das horas
que o empregado faltou de suas horas extras, obtendo um valor que determina
o nmero de pontos do funcionrio. A distribuio do prmio feita de acordo
com a tabela abaixo.
Pontos Obtidos
Prmio em R$
de
41
...
500,00
31
40
400,00
21
30
300,00
11
20
200,00
10
100,00
1
50
11. Dados o canto superior esquerdo e o canto inferior direito de um retngulo R,
paralelo aos eixos, determine quantos quadrantes so cobertos por ele.
12. Dados dois retngulos, paralelos aos eixos, determine se h ou no interseo
entre eles. Determine ainda, se for o caso, a rea de interseo entre dois
retngulos.
13. Considere um retngulo definido por seus cantos superior esquerdo e inferior
direito. Podemos traar um losango a partir de pontos localizados no ponto
mdio de cada um de seus lados. Definimos com isso seis regies.
i. fora do retngulo;
ii. o tringulo superior esquerdo;
iii. o tringulo superior direito;
iv. o tringulo inferior direito;
v. o tringulo inferior esquerdo;
vi. o interior do losango.
vii. Dado um ponto p, determine a sua localizao.
viii.
14. Dados 3 nmeros, determine se com os trs eu posso formar uma progresso
aitimtica (PA), onde dois deles quaisquer so termos consecutivos e um
terceiro a razo.
15. Dados 3 nmeros, determine se com os trs eu posso formar uma progresso
gepmtrica (PG), onde dois deles quaisquer so termos consecutivos e um
terceiro a razo.
16. Considere que o preo de uma passagem de avio em um trecho, pode variar
dependendo da idade do passageiro. Pessoas com 60 ou mais anos de idade
pagam apenas 60% do preo total. Crianas at 10 anos, pagam 50% e bebs
(abaixo de 2 anos) pagam apenas 10%. Escreva uma definio que tenha
como entrada o valor nominal da passagem e a idade do passageiro e produz
o valor a ser pago.
17. Dados dois nmeros inteiros, considere que eles possuem no mximo 5
algarismos. Determine em que quantidade de algarismos na mesma posio
eles so iguais.
?qalg 123 124
2
?qalg 1234 4321
0
1
51
18. Dados dois pontos p e q, no plano cartesiano, tome a origem dos eixos como o
eixo dos ponteiros de um relgio analgico, p como a posio da extremidade
do ponteiro maior e q como a do ponteiro menor. Determine a quantidade total
de minutos decorridos desde o incio do dia.
19. Dados trs nmeros a, b, c. Determine quais das seguintes relaes eles
mantm entre si: a) os trs so diferentes; b) apenas dois so iguais; c) os trs
so iguais.
20. Considere que um dado nmero inteiro est armazenando um valor v escrito
na base octal. Pede-se: a) verifique se realmente o nmero dado est na base
8; b) determine qual o valor deste nmero na base decimal.
21. Considere um tabuleiro de xadrez de dimenses infinitas, considere ainda que
a numerao das casas dada por um par de nmeros inteiros. Sabemos que
o cavalo possui oito movimentos conforme a figura 3.
m3
M3
m2
m4
m1
C
m5
m8
m6
m7
Escreva uma funo para determinar a nova posio obtida pela aplicao de
cada movimento posio X. O resultado dever ser produzido com um nmero
de 2 casas.
1
52
2. Um losango , com os seus eixos paralelos aos eixos cartesianos, dado pelas
coordenadas do vrtice esquerdo e do vrtice superior, como mostrado na
figura.
1
53
Y
Q
R3
y2
y1
R1
x1
R2
2
x2
R1
X
2. Dada uma reta descrita por dois pontos P (x1, y1) e Q (x2,y2), escreva uma
funo que determine o valor da coordenada no eixo dos y a partir de uma
coordenada fornecida no eixo dos x.
coordy x1 x2 y1 y2 x = ...
3. Considere a figura 2 e descreva uma funo para determinar cada uma das
reas das regies R1, R2 e R3. A funo tem como parmetros as
coordenadas dos pontos P e Q. Observe que um dos lados do tringulo
issceles coincide com o eixo dos x e que um dos seus vrtices a origem.
Observe ainda que os lados do retngulo so paralelos aos eixos.
1
54
Y
y1
R2
R11
y2
R3
x1
x2
5. Considere uma pea cilndrica com raio r e altura h. Considere ainda que esta
pea possui um furo em forma hexagonal de lado l, com centro no eixo da
pea. Descreva uma funo para determinar o volume da pea.
1
55
6. Considera a figura abaixo, onde est representada a regio R correspondente
a interseo de dois crculos de mesmo raio r. Escreva uma funo para
calcular a rea dessa regio, sabendo-se que dado o ngulo do setor do
crculo determinado pelos pontos de interseo das duas circunferncias.
r
R
7. Descreva uma funo que calcule a rea (representada pela cor cinza) de uma
flor formada por quatro crculos de mesmo raio r, cujos centros so os vrtices
de um quadrado, conforme ilustrado na figura a seguir. O miolo da flor um
crculo oco de raio r1.
1
56
b) Descrio da regio hachurada: seja E (x1, y1) o vrtice superior esquerdo
de um quadrado de lado a paralelo aos eixos cartesianos. Considere que as
ptalas da flor so formadas por semi-crculos de raio a/2 e centros no
ponto mdio de cada lado do quadrado e que o miolo formado por dois
crculos de raios a/4 e a/8.
E
a/2
a/8
a/4
1
57
2) Problemas de mapeamento de um ponto P (x,y) em sua regio de pertinncia,
utilizando descries condicionais, de forma adequada.
a) Sejam E (x1, y1) e S (x2, y2) os vrtices esquerdo e superior,
respectivamente, de um losango cujos eixos so paralelos aos eixos
cartesianos. Considere as regies descritas abaixo:
regio 1: regies hachuradas, externas
losango, no
crculo superior
regio 2 : regies hachuradas, interna
losango, no
crculo superior
regio 3 : no losango e fora dos ciculos
regio 4: regies hachuradas, externas
losango, no
crculo inferior
regio 5 : regies hachuradas, interna
losango, no
ao
ao
ao
ao
b) So dados os pontos E (x1, y1) e D (x2, y2) e sabe-se que o raio dos semicrculos extermos igual (y1 - y2 ) /2.
1
58
19. APLICAES
Neste captulo apresentamos uma srie temtica de exerccios, buscando dar ao
leitor uma viso mais ampla das possibilidades de uso da programao funcional.
A inteno apresentar vrios contextos onde precisamos programar
computadores. Em todos, o contexto descrito e vrios exerccios so
apresentados. Aos professores e estudantes, sugerimos que o contexto sirva de
pretexto para a formulao e resoluo de novos exerccios. Comeamos pelo
Domin Bar, onde, buscamos na ludicidade do jogo, apresentar as
necessidades de manipular informao. Na seqncia apresentamos uma srie de
problemas considerando as necessidades de informao de um Banco de
Sangue, o manuseio de mensagens de um Correio Eletrnico, a organizao de
uma Lista de Compras, um sistema de Passagens Areas, Gerncia
Acadmica, Agncia de Turismo e exerccios sobre Espetculos Teatrais.
19.1 O DOMIN BAR: O domin de nmeros uma coleo de pedras, utilizado
na maioria das vezes como um excelente passatempo. Das tantas formas de
utilizar o domin, destacamos uma, utilizada no Amazonas, principalmente em
Manaus, mas tambm em muitas praias pelo mundo afora onde existirem
amazonenses, em particular nas praias de Fortaleza. Os Amazonenses costumam
cham-la de domin bar", em homenagem a uma tribo que habitava a regio
onde foi fundada a cidade de Manaus. A maioria dos exerccios deste captulo
foram desenvolvidos em Manaus, no final da dcada de 80. De l pra c, vrios
outros foram acrescentados, mas a lista como um todo permanece indita.
A inteno desta seo apresentar alguns poucos exerccios resolvidos e propor
outros. A idia no desenvolver o jogo e sim, inspirar-se em situaes do jogo
para propor exerccios interessantes e desafiadores. Deixamos o desenvolvimento
do jogo completo como sugesto para o trabalho em grupos. Ao final do captulo
discutiremos um pouco sobre a programao do jogo.
Preliminares: O material do jogo um conjunto formado por 28 "peas", cada
uma delas com duas "pontas". Cada "ponta" representa um valor de 0 (zero) a
seis (6), perfazendo portanto 7 valores diferentes. Cada valor possui um nome
prprio: o Zero chama-se "branco", o um chama-se "s", o dois o "duque", o trs
chama-se "terno", o quatro a "quadra", o cinco a "quina" e o seis denomina-se
"sena". O nome de uma "pedra" dado pelo nome de suas "pontas", por exemplo,
"quina e terno", o nome da "pedra" que possui em uma ponta o valor 5 e na
outra o valor 3. As pedras que possuem o mesmo valor nas duas pontas so
denominadas de "carroa". Para cada tipo de valor existem 7 pedras, por exemplo,
para o "terno" teremos: terno e branco, terno e s, terno e duque, carroa de
terno, quadra e terno, quina e terno, sena e terno. O jogo , em geral, disputado
por duplas, ganhando a que fizer o maior numero de pontos, a partir de um
mnimo pr-estabelecido.
A seguir apresentamos em detalhes os vrios
elementos do jogo.
1
59
Peas do Jogo: Os elementos do jogo so (28) vinte e oito peas, cada uma com
duas pontas, na qual marcado um valor que varia de 0 a 6. Para jogar, as
"pedras" so embaralhadas e escolhidas pelos jogadores. A cada jogador cabem
7 pedras. Com o desenrolar do jogo a quantidade de pedras vai sendo decrescida,
at que, eventualmente chegue em zero.
Participantes: duas duplas (eventualmente pode ser jogado individualmente, com
2, 3 ou 4 jogadores).
Objetivo: atingir um total mnimo de 200 pontos. Vence o jogo a dupla que ao final
de uma rodada tiver o maior nmero de pontos.
Dinmica: o jogo se desenvolve em uma quantidade qualquer de eventos
menores denominados de rodada. A figura 18.1 ilustra um instante de jogo.
1
60
Pontuao: existem 4 formas para obter pontos:
1. Durante o jogo, a figura formada na mesa possui 1 (quando existe apenas
uma pea assentada), 2, 3 ou 4 pontas. soma dos valores dessas pontas
denomina-se de: os pontos da mesa. Quando essa soma produz um
mltiplo de 5, o jogador que sentou a ltima pedra pode requerer que eles
sejam anotados em favor de sua dupla. Veja que s o jogador que sentou a
pedra pode reivindicar os pontos e isto tem que ocorrer antes que o
prximo jogador sente a sua pedra;
2. Quando um jogador no possui pedra para colocar na mesa (ou seja, uma
que combine com uma das pontas), ele passa a vez, e a dupla adversria
ganha 10 pontos. Se um jogador percebe que com a colocao de sua
pea ele conseguir fazer com que todos os demais passem, inclusive o
seu parceiro, ele pode anunciar que deu um passe geral e com isso ganhar
de bnus 50 pontos.
3. Quando um jogador descarta sua ltima pea em uma rodada diz-se que
ele bateu, e, portanto ganhou a rodada. Com isso ele ganha de bnus 10
pontos e mais o mltiplo de 5 ligeiramente inferior soma dos valores
constantes nas peas que sobraram nas mos dos adversrios (garagem).
Se a batida for feita com uma carroa, o bnus de 20 pontos.
4. Quando ocorre uma situao onde nenhum dos jogadores consegue jogar,
embora estejam com peas na mo, diz-se que o jogo est fechado. Neste
caso ganha a rodada a dupla cuja soma dos valores das peas for o menor.
A soma das peas da dupla adversria computada em seu favor, como no
caso 3.
Posio dos Jogadores: Os membros de cada dupla so colocados em posies
alternadas, de forma que as jogadas (colocao de peas) seja feita de forma
alternada entre as duplas adversrias. Por exemplo, em um jogo presencial,
podemos usar, como suporte para colocao das peas, uma mesa de quatro
lugares, ficando os parceiros sentados frente-a-frente.
Distribuio das Peas: a distribuio das 28 peas entre os 4 jogadores deve
ser feita de forma aleatria. Na prtica, em um jogo com peas fsicas, viram-se as
peas de cara para baixo e mistura as peas com as mos. Cada jogador vai
retirando as suas prprias peas.
Quem comea uma rodada: Uma rodada sempre iniciada com a colocao de
uma carroa. Na primeira rodada do jogo, a carroa a ser utilizada de sena (6),
cabendo pois ao jogador que a tirou comear o jogo. As rodadas seguintes so
iniciadas pelo jogador que bateu a rodada anterior, com a carroa que ele preferir.
Se ele no possui carroa, ele passa e o jogador seguinte (da dupla adversria)
inicia o jogo, se este tambm no possuir, passa a frente.
Uma Jogada: Estando na sua vez de jogar, o jogador deve escolher uma das
pedras de sua mo, e coloca-la na mesa de jogo, combinando com alguma das
pontas abertas. A escolha da pea a ser jogada deve contribuir para o objetivo da
dupla que ganhar o jogo, isso significa, em linhas gerais, escolher uma pedra
1
61
que me permita fazer o maior nmero de pontos e, quando isso no for possvel,
escolher uma pedra que reduza o nmero de pontos que os adversrios possam
fazer com base em minha jogada. H, entretanto algumas nuances a serem
consideradas:
Quem abre uma rodada, bater a rodada a menos que passe. Tendo em
vista que ao ganhar uma rodada, h bnus para a dupla, posso deixar de
marcar ponto visando vencer a rodada;
Idem para tentar evitar que a dupla adversria ganhe a rodada (quando
foro a passada de um adversrio que comeou a rodada, a batida passa
para o meu parceiro).
1
62
Exemplos de uso:
1.
2.
3.
4.
maop [ ] True
maop [((-3), 4)] False
maop [(3,4)] True
maop [ (1,2), (1,5), (2,0), (2,4), (3,3), (1,1), (0,0), (4,0)] False
Soluo:
maop [ ]
= True
maop (x:xs) = (length xs <= 6) && pedrap x && maop xs
3. Escreva a funo carrocap que associe um par a True sss o par uma
"carroa" e False caso contrrio.
4. Escreva a funo tem_carroca_p que associe uma "mo" a True sss a
mo possuir pelo menos uma carroa e False caso contrrio.
5. Escreva a funo tem_carrocas que associe a uma "mo" a lista das
"carroas" nela contida.
Grupo II
Em vrios momentos do jogo faz-se necessrio saber a quantidade de pontos
associado uma coleo de pedras. Em particular, no final do jogo, quem
"sentou" a sua ltima pedra faz jus "garagem" que determinada a partir dos
pontos que restaram na(s) mo(s) dos adversrios.
6. Escreva a funo pontos que associe uma lista de "pedras" a soma dos
pontos das pedras nela contidos. Onde os pontos de uma pedra a soma
de suas pontas.
Soluo:
pontos [ ]
=0
pontos (x:xs) = ponto x + pontos xs
where
ponto (x,y) = x + y
7. Escreva a funo garagem que associe uma lista de "pedras" ao maior
mltiplo de 5 (cinco), menor ou igual soma dos pontos nela contidos.
8. Escreva a funo pedra_igual_p que associe dois pares de inteiros a True
sss representam a mesma pedra e False caso contrrio. bom lembrar
que a ordem das pontas irrelevante, assim (2,4) e (4,2) representam a
mesma pedra.
1
63
9. Escreva a funo ocorre_pedra_p que associe uma "pedra" e uma "mo" a
True sss a "pedra" ocorre na "mo" e False caso contrrio.
10. Escreva a funo ocorre_valor_p que associe um valor vlido para "ponta"
e uma "mo" e produza True sss o valor ocorre em alguma pedra da mo e
False caso contrrio.
11. Escreva a funo ocorre_pedra que associe a um valor e uma "mo", uma
lista contendo as pedras da "mo" que possuem o valor dado.
12. Escreva a funo pedra_maior que associe uma "mo" a pedra de maior
valor na "mo" dada. Uma pedra p1 maior que uma outra p2 sss a soma
das pontas de p1 for maior que a soma das pontas de p2.
13. Escreva a funo ocorre_valor_q que associe um valor e uma "mo" e
produza o nmero de pedras na mo que possuem o valor dado.
14. Escreva a funo ocorre_carroca_q queassocie uma mo quantidade de
carroas nela existentes.
15. Escreva a funo tira_maior que associe uma mo a uma lista similar
"mo" de onde foi extrada a pedra de maior ponto.
16. Escreva a funo tira_maior_v que associe um valor e uma "mo" lista
similar "mo" de onde se extraiu a pedra de maior pontos de um
determinado valor para ponta.
Grupo III
O jogo se desenvolve pela colocao, pelo Jogador da vez, de uma pedra que
combine com alguma das "pontas" da "mesa". Num momento genrico do jogo
temos quatro pontas disponveis para execuo de uma jogada. Uma ponta pode
ser simples ou uma carroa. As carroas so dispostas de tal forma que todos os
seus pontos estejam para "fora".
Chamaremos "mesa" lista de pontas disponveis para jogada. Pontas simples
sero representadas por listas de um elemento e carroas por uma lista com dois
elementos idnticos. Por exemplo, a "mesa" ilustrada na Figura 18.2
representada pela qudrupla ( [5,5], [5], [0],[4] ).
Uma ponta ainda no aberta representada por lista vazia. Dizemos que h
marcao de pontos em uma mesa quando a soma das pontas um mltiplo de 5.
Os pontos a serem marcados a soma das pontas, com as carroas contando em
1
64
dobro.
17. Escreva a funo mesap que associe uma qudrupla de listas a True sss a
qudrupla for uma descrio vlida de "mesa".
Soluo:
mesap (p1,p2,p3,p4) = vponta p1 && vponta p2 &&
vponta p3 && vponta p4
where
vponta (x:y:xs) = if not (null xs)
then False
else validap x && vponta (y:xs)
vponta (x :[ ] ) = validap x
validap x
= elem x [0..6]
18. Escreva a funo carroca_m_p que associe uma mesa a True sss pelo
menos uma das pontas for carroa.
19. Escreva a funo pontos_marcados que associe uma mesa ao o nmero
de pontos a serem marcados se a soma das pontas for mltiplo de cinco e
zero em caso contrrio.
1
65
20. Escreva a funo pode_jogas_p que associe uma "pedra" e uma "mesa" a
True sss a pedra possui uma ponta que combina com pelo menos uma das
pontas da mesa.
21. Escreva a funo marca_ponto_p que tenha como entrada uma "pedra" e
uma "mesa" e produza True sss a pedra pode ser jogada fazendo pontos
em uma das pontas da mesa. Lembre-se que as carroas devem ser
contadas pelas duas pontas da pedra.
22. Escreva a funo maior_ponto que tenha associa uma pedra e uma mesa
ao nmero da "ponta" da mesa onde pode ser marcado o maior valor de
ponto que ser marcado pela pedra. Considere que a em uma "mesa" as
pontas so numeradas a partir de zero, da esquerda para a direita.
23. Escreva a funo joga_pedra que associe uma "pedra", uma "mesa" e um
nmero de "ponta" da mesa a uma nova mesa obtida ao se jogar a "pedra"
na "ponta" indicada.
24. Escreva a funo jogap que associe uma "mo" e uma "mesa" e produza
True sss existe pelo menos uma pedra na mo que possa ser jogada em
pelo menos uma ponta da mesa. Caso contrrio produza False.
25. Escreva a funo jogada que associe uma "mo" e uma mesa ao nmero
da pedra na mo e nmero da ponta na mesa onde pode ser feita a jogada
que marque mais ponto. Considere inclusive jogada onde no h marcao
de ponto.
26. Escreva a funo faz_jogada que associe uma "mo" e uma "mesa" e
produza uma nova "mesa" obtida por se jogar marcando o maior nmero de
pontos possvel
19.2 Banco de Sangue: para facilitar o atendimento da demanda por transfuses
de sangue o sistema de sade criou os chamados Bancos de Sangue. Como
sabemos, cada transfuso s pode ser realizada usando tipos de sangue
apropriados. A adequao de um determinado tipo de sangue baseada em
estudos cientficos que identificou quatro tipos sangneos, denominados de A, B,
AB e O. Outros estudos identificaram ainda a existncia do chamado fator RH que
pode ser positivo (+) ou negativo (-), assim o sangue de qualquer indivduo
classificado de acordo com esses dois atributos. Por exemplo, dizemos que fulano
possui sangue tipo O e fator RH positivo, e abreviamos para O+. Em um dado
Banco de Sangue, diariamente, so feitas doaes por pessoas de diferentes tipos
sangneos, para as quais feito um registro contendo o nmero da carteira de
identidade do doador (RG), o sexo (S), a data da doao (DD), a data de
nascimento (DN), o tipo sangneo (TS), o fator RH (RH) e a quantidade doada
(QD) (250 ou 500 ml). O sangue doado guardado em recipientes com uma
capacidade fixa (250 ml). Tambm, diariamente so feitas requisies pelos
hospitais (H), cada requisio indica as caractersticas do sangue (tipo e fator RH)
e a quantidade solicitada (QS). Sabemos que homens e mulheres possuem
intervalos de tempo diferentes para fazer doaes. Para homens o intervalo
mnimo de 2 (dois) meses e para mulheres de 3 (trs). A idade mxima para
doadores 60 anos.
1
66
Sejam as seguintes estruturas
Doao
Requisio
1
67
estoque pode ser insuficiente para atender completamente todos os pedidos.
Determine o estoque atualizado aps o atendimento dos pedidos e produza
uma lista das requisies atendidas, constando a quantidade que foi de fato
fornecida.
12. No problema 11, considere que voc deseja atender cada hospital solicitante,
de forma proporcional ao seu pedido, considerando os pedidos de cada tipo
sangneo separadamente. Por exemplo, suponha que: o total de pedidos de
sangue O+ de 12.000 ml, que o hospital h1 solicitou 3.000 ml de sangue
O+ e que no estoque 8.000 ml. Podemos observar que o pedido para o sangue
O+ do hospital h1 representa 25 % do total. Neste caso o hospital h1 ser
atendido com 25 % de 8.000 ml que representa 2.000 ml. Produza uma lista
como os pedidos atendidos e outra com os pedidos pendentes.
13. Considere a poltica de atendimento do problema 12 mas leve em conta que
um dado pedido deve ser atendido completamente. Considere o exemplo do
problema anterior, e suponha que os pedidos do hospital h1 para o sangue
O+ so 4, (h1, O, +, 1.500), (h1, O, +, 1.000) e (h1, O, +, 250) e (h1, O,
+, 500). Neste caso, considerando que os pedidos esto em ordem de
prioridade, seriam atendidos os pedidos (h1, O, +, 1.500) e (h1, O, +, 250).
14. Modifique a poltica de atendimento do problema 14 para que o atendimento
seja tal que o hospital h1 use da melhor forma possvel a proporcionalidade
que lhe cabe. No caso do exemplo apresentado no problema 14, o pedido de
250 ml seria descartado visto que atendendo o pedido de 500 ml o hospital h1
estar usando melhor a parte que lhe cabe. (escolher a combinao mais
apropriada)
1
68
ocorrncias formada pela posio na lista de mensagens onde o remetente
ocorre.
Por exemplo:
[ (jose@inf.ufes.br, [1, 23]), (maria@inf.ufes.br, [10, 20, 50]), ...]
2. (consulta r p) Considere definidos um ndice por remetente, um ndice por
palavras constantes no assunto das mensagens e uma lista de mensagens.
Dados um remetente (r) e uma palavra(p), obtenha a lista de mensagens
enviadas por r onde a palavra p ocorre no assunto.
remetentes
palav_assunto
mensagens
5.
6. (releva msgs li lf) Dada uma lista de mensagens podemos obter uma lista de
palavras relevantes. Define-se como palavra relevante em uma lista
mensagens (msgs) aquelas cuja freqncia satisfazem um intervalo para o
qual so dados um limite superior (ls) e um limite inferior (li).
1
69
7.
8.
13. (insOrd indb msg) Dados um ndice (indb) no formato de rvore binria de
pesquisa e uma mensagem (msg), descreva a nova rvore obtida pela
insero das palavras das mensagem (msg), exceto as irrelevantes.
14. (perfil msg diret fga) Um diretrio uma lista de assuntos, cada um dos
quais associado a uma coleo de palavras. Dada uma mensagem e um
diretrio podemos atribuir mensagem um perfil que uma lista de valores
indicando o grau de aproximao (ga) dela com cada assunto. O ga de uma
mensagem com respeito a um assunto pode ser obtido com base na
freqncia com que as palavras a ele associadas ocorrem na mensagem.
1
70
Considere que a funo que calcula o ga fornecida e opera sobre uma lista
de inteiros.
Considere os seguintes formatos:
Diretrio
Perfil
1
71
19.5 Passagens areas: Considere que vrias companhias areas brasileiras
oferecem vos dirios para vrias regies do mundo. Devido a competitividade do
mercado, vrias so as ofertas promocionais de vos nacionais e internacionais.
Cada vo identificado pela companhia area, o nmero do vo, a rota, a tarifa
em reais e a data de partida. A rota descrita por uma lista onde o primeiro
elemento corresponde origem, o ltimo elemento corresponde ao destino e os
outros elementos correspondem s escalas do vo. Para escolher e reservar um
determinado vo, um passageiro deve fornecer as seguintes informaes: a
origem, o destino e a data de partida desejados. Um vo atende a um pedido de
reserva se, para a data de partida desejada, a origem requisitada coincide com a
origem definida na rota do vo e o destino requisitado coincide com alguma escala
ou com o destino da rota do vo. A tarifa a mesma, da origem para qualquer
escala ou destino da rota. Considere as seguintes definies:
vo
1
72
19.6 Gerncia Acadmica: Considere a gerncia acadmica dos cursos de
graduao de uma universidade. As disciplinas cursadas por um aluno so
registradas em seu histrico. O registro deve conter o cdigo da disciplina, o ano e
o semestre em que foi cursada e a nota obtida. Semestralmente o aluno deve
requerer matrcula em novas disciplinas. O pedido de matrcula realizado atravs
da apresentao das disciplinas desejadas pelo aluno. Um dos critrios para
conseguir se matricular em uma disciplina que o aluno tenha cumprido, com
aprovao, os pr-requisitos da disciplina. Um aluno aprovado em uma disciplina
se obtiver mdia superior ou igual a 5 (cinco). Cada curso possui uma grade
curricular que relaciona cada disciplina do curso com seus respectivos prrequisitos.
Considere as seguintes definies:
Histrico Escolar
Histrico
Escolar
Cadastro de
Disciplinas
Grade
Curricular
Lista de
disciplinas de
um curso,
apresentadas
por perodo
73
requisitos.
Formato: (curso, [(disciplina, [disciplina, disciplina,...]), ...])
Um par contendo o cdigo do curso e uma lista de pares, onde
cada par representa um perodo do curso e uma lista das
disciplinas do perodo.
Formato: (curso, [(perodo, [disciplina, disciplina,...])
2.
3.
4.
5.
6.
7.
8.
(divida) Obter a lista das disciplinas que foram cursadas por um dado aluno,
nas quais ele ainda no obteve aprovao.
9.
(reprova) Obter uma lista de reprovaes por perodo, para um dado aluno.
(crend) O coeficiente de rendimento (CR) de um dado aluno
determinado pela mdia ponderada das notas obtidas, tendo como peso, o
nmero de crditos das disciplinas. Determine o CR de um dado aluno.
10.
11.
12.
(dividas) Obter para um dado aluno, a lista de disciplinas que ele ainda
no cursou, com respeito a uma dada grade curricular.
13.
(sugestao) Obter para um dado aluno, a lista de disciplinas que ele est
apto a cursar, com respeito a uma dada grade curricular.
14.
1
74
(lcumprereq) Obter uma lista de pedidos de disciplinas para as quais os
pr-requisitos foram cumpridos.
15.
16.
17.
1
75
ocupao da platia, conforme as vendas dos ingressos. A platia est
representada por m filas numeradas de 1 a m, sendo que cada fila contm n
cadeiras tambm numeradas de 1 a n. Considere a seguinte representao para
os dados:
Lugar na platia (fila, cadeira), onde fila representada por um inteiro de 1 a m e
cadeira, por um inteiro de 1 a n.
Platia
Lista de duplas (lugar, situao) sendo que a situao : 1 para
indicar lugar ocupado e 0 para indicar lugar vago.
Lista de duplas (espetculo, platia) onde espetculo representado
Teatro
por um inteiro de 1 a p.
Exerccios: Escreva um script em HUGS, com funes que resolvam os
problemas abaixo. Nomes para cada uma das funes so sugeridos ao final do
enunciado de cada problema.
5. Dada uma platia pls, descreva a quantidade total de lugares ocupados
(totalOcup).
6. Dado um lugar lg e uma platia pls, verifique se o lugar lg est livre (estaLivre).
7. Dado um lugar lg e uma platia pls, verifique se existe algum vizinho lateral de
lg que est livre (vizinhoLivre).
8. Dada uma fila fl e uma platia pls, descreva a lista de cadeiras livres da fila fl
(cadeirasLivresFila).
9. Dada uma platia pls, descreva a lista de cadeiras livres para cada fila
(lugLivresFila)
10. Dada uma platia pls, descreva a(s) lista(s) com o maior nmero de cadeiras
livres (filaMaxLivre).
11. Dado um teatro trs e um espetculo ep, descreva a sua platia (plateiaEsp).
12. Dado um teatro trs, um espetculo ep e uma fila fl, descreva a lista de cadeiras
livres da fila fl (cadeirasLivresFilaEsp).
1
76
20. ENTRADA E SAIDA DE DADOS
20.1 INTRODUO:
Os programas que apresentamos e propusemos at ento, se basearam em um
padro especfico de interao entre o usurio e o sistema. O interpretador HUGS
est constantemente solicitando uma expresso, que em seguida avaliada por
ele e o resultado apresentado ao usurio. Vejamos o modelo ilustrado na figura
20.1. A avalio de uma expresso leva em conta as definies disponveis em
bibliotecas e as construdas pelos programadores.
expresso
scripts
usurio
Interpretado
r HUGS
resultado
1
77
Jogo encerrado
sim
valor
Valor fornecido
=
Nmero oculto
?
no
Fornea outro valor
1
78
jogo1 = do
putStrLn ">>fornea um nmero entre 0 e 10"
valor <- getLine
if valor == "5"
then do putStrLn "acertou - parabns!"
else do putStrLn "errou - tente outra vez!"
jogo1
1
79
E algumas interaes:
Main> jogo1
>>fornea um nmero
3
errou - tente outra
>>fornea um nmero
4
errou - tente outra
>>fornea um nmero
2
errou - tente outra
>>fornea um nmero
5
acertou - parabns!
entre 0 e 10
vez!
entre 0 e 10
vez!
entre 0 e 10
vez!
entre 0 e 10
valor getLine
5. Para indicar que desejamos continuar executando o programa podemos
fazer uma chamada a ele mesmo, como o fizemos em:
else do putStrLn "errou - tente outra vez!"
jogo1
1
80