• Nenhum resultado encontrado

Programação Recursiva

N/A
N/A
Protected

Academic year: 2021

Share "Programação Recursiva"

Copied!
17
0
0

Texto

(1)

Programa¸c˜

ao Recursiva

Ricardo Silva

2001/02

1

a

Aula Pr´

atica

Sintaxe e Semˆ

antica da Linguagem Scheme

1. (Exerc.: 2.2.1)

Converta as seguintes express˜oes aritm´eticas em express˜oes Scheme e avalie-as: a) 1.2 x (2- 1/3) + -8.7

b) (2/3 + 4/9)/(5/11 - 4/3) c) 1 + 1/(2 + 1/(1 + 1/2)) d) 1 x -2 x 3 x -4 x 5 x -6 x 7 2. (Exerc.: 1.2)

Traduza a seguinte express˜ao para nota¸c˜ao prefixa:

5 + 4 + (2 − (3 − (6 +45))) 3(6 − 2)(2 − 7) 3. (Exerc.: 1.3)

Defina um procedimento que tome trˆes n´umeros como argumentos e devolva a soma dos quadrados dos dois maiores.

4. (Exerc.: 1.4)

Observe que o nosso modelo de avalia¸c˜ao permite combina¸c˜oes cujos operadores sejam express˜oes compostas. Use esta observa¸c˜ao para descrever o comporta-mento do seguinte procedicomporta-mento:

(define (a-mais-abs-b a b) ((if (> b 0) + -) a b)) 5. (Exerc.: 1.5)

O Bruno inventou um teste para descobrir se o interpretador de Scheme que est´a a usar avalia as express˜oes de acordo com a estrat´egia de redu¸c˜ao normal ou aplicativa. Ele define os dois procedimentos seguintes:

(define (p) (p)) (define (teste x y)

(if (= x 0) 0 y))

(2)

Em seguida avalia a express˜ao (teste 0 (p))

Qual o resultado de avaliar a express˜ao se o interpretador usar a estrat´egia de avalia¸c˜ao aplicativa? E se usar a normal? Explique a sua resposta. (Assuma que a regra de avalia¸c˜ao para a forma especial if ´e independente da estrat´egia utilizada. O predicado ´e avaliado em primeiro lugar e o resultado determina se se avalia o consequente ou a express˜ao alternativa).

(3)

2

a

Aula Pr´

atica

Exemplos de Programa¸

ao em Scheme

1. (Exerc.: 1.6)

A Alice n˜ao percebe porque ´e que o if tem de ser considerado como uma forma especial. ”Porque ´e que n˜ao o definimos como um procedimento normal a partir do cond?”, pergunta ela. Eva, amiga da Alice afirma que realmente ´e poss´ıvel fazˆe-lo e define uma nova vers˜ao do if :

(define (novo-if predicado ent~ao sen~ao) (cond (predicado ent~ao)

(else sen~ao)))

A Eva mostra `a Alice que o programa funciona: (novo-if (= 2 3) 0 5)

5

(novo-if (= 1 1) 0 5) 0

Encantada, Alice usa o novo-if para reescrever o programa das ra´ızes quadradas: (define (raiz-iter aproxima¸c~ao x)

(novo-if (pr´oximo? aproxima¸c~ao x) aproxima¸c~ao

(raiz-iter (melhora aproxima¸c~ao x) x)))

O que acontece quando a Alice tentar calcular ra´ızes usando o novo progra-ma? Porquˆe?

2. (Exerc.: 1.7)

O teste pr´oximo? usado no c´alculo das ra´ızes quadradas n˜ao ´e muito eficiente para calcular as ra´ızes quadradas de n´umeros muito pequenos (em valor abso-luto). Al´em disso, as opera¸c˜oes aritm´eticas s˜ao sempre efectuadas com precis˜ao limitada, o que torna o nosso teste inadequado para n´umeros demasiado grandes. Explique estas afirma¸c˜oes, com exemplos mostrando como o teste falha em am-bos os casos. Uma estrat´egia alternativa para implementar pr´oximo? consiste em observar a altera¸c˜ao da aproxima¸c˜ao entre duas itera¸c˜oes e para quando essa altera¸c˜ao for uma pequena frac¸c˜ao da aproxima¸c˜ao.

Defina um procedimento raiz-quadrada que use este tipo de teste. O no-vo procedimento funciona melhor para os n´umeros extremamente grandes e os extremamente pequenos?

3. (Exerc.: 1.8)

O m´etodo de Newton para ra´ızes c´ubicas baseia-se no facto de que se y ´e uma aproxima¸c˜ao da raiz c´ubica de x, ent˜ao ´e poss´ıvel encontrar uma melhor aprox-ima¸c˜ao dada pelo valor

(x/y2+ 2y) 3

Use esta f´ormula para implementar um procedimento raiz-c´ubica semelhante ao procedimento raiz-quadrada.

(4)

4. (Exerc.: 2.4.2)

Determine o valor da seguinte express˜ao. Explique como obteve esse valor. (let ((x 9))

(* x

(let ((x (/ x 3))) (+ x x)))) 5. (Exerc.: 2.4.3 )

Reescreva as seguintes express˜oes de forma a que n˜ao haja conflitos de so-breposi¸c˜ao das vari´aveis, ou seja, de forma a que uma vari´avel ocorra sempre no ˆambito de um ´unico let ou lambda

a)

(let ((x 7) (y 3))

(+ (let ((x 2))(* x y)) (let ((y 5))(* x y)))) b) (let ((x (/ (expt a b) 4))) (* (let ((x (sqrt x))) (* 2 x)) (let ((x (* 4 x))) (expt (let ((x (sqrt x))) (sqrt x)) (/ (let ((x (* 4 x))) x) (* 2 x)))))) 6. (Exerc.: 1.34 )

Suponha que definimos o procedimento (define (f g) (g 2)) Ent˜ao temos (f quadrado) 4 (f (lambda (z) (* z (+ 1 z)))) 6

O que acontece se (perversamente) pedirmos ao interpretador para avaliar

(5)

3

a

Aula Pr´

atica

Recurs˜

ao e Itera¸

ao

1. (Exerc.: 1.9)

Cada um dos seguintes dois procedimentos define um m´etodo para adicionar dois inteiros positivos em termos dos procedimentos inc, que incrementa uma unidade ao seu argumento, e dec, que decrementa uma unidade ao seu argu-mento. (define (+ a b) (if (= a 0) b (inc (+ (dec a) b)))) (define (+ a b) (if (= a 0) b (+ (dec a) (inc b))))

Ilustre o processo de avalia¸c˜ao da express˜ao (+ 5 4) por cada um destes procedimentos. S˜ao processos iterativos ou recursivos?

2. (Exerc.: 1.11)

Seja f a fun¸c˜ao definida pela regra

f (n)=n, se n < 3 e

f (n)=f (n - 1) + 2 f (n - 2) + 3 f (n - 3), se n> 3.

Escreva um procedimento que calcule f por meio de um processo recursivo, e outro que calcule f por meio de um processo iterativo.

3. (Exerc.: 1.12)

O seguinte padr˜ao de n´umeros ´e chamado triˆangulo de Pascal. 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 . . .

Os n´umeros fronteiros do triˆangulo s˜ao todos 1, e cada n´umero no interior do triˆangulo ´e a soma dos dois n´umeros acima dele. Escreva um procedimento que calcule os elementos do triˆangulo de Pascal recursivamente.

4. (Exerc.: 1.16)

Escreva um procedimento que calcule a exponencia¸c˜ao iterativamente e que use quadrados suessivos para obter um n´umero de passos logaritmico, como faz exp-rapida.

5. (Exerc.: 1.17)

Os algoritmos de exponencia¸c˜ao que vimos s˜ao baseados na ideia de calcular a exponencia¸c˜ao atrav´es da repeti¸c˜ao da multiplica¸c˜ao. De forma an´aloga, pode-se calcular a multiplica¸c˜ao inteira repetindo a adi¸c˜ao. O seguinte procedimento para a multiplica¸c˜ao ´e an´alogo ao procedimento exp.

(6)

(define (* a b) (if (= b 0)

0

(+ a (* a (- b 1)))))

O n´umero de passos deste algoritmo ´e linear em b. Suponhamos agora, que para al´em da adi¸c˜ao, faz´ıamos uso das opera¸c˜oes dobro, que duplica o valor dum inteiro, e metade, que divide um inteiro (par) por 2. Defina ent˜ao um procedimento para a multiplica¸c˜ao an´alogo a exp-rapida, com um n´umero de passos logar´ıtmico.

6. (Exerc.: 1.18)

Usando os resultados dos dois exerc´ıcios anteriores, crie um procedimento iter-ativo para multiplicar dois inteiros em termos da adi¸c˜ao, duplica¸c˜ao e divis˜ao por 2.

(7)

4

a

Aula Pr´

atica

Fun¸

oes de ordem superior

1. (Exerc.: 1.30)

O procedimento somatorio gera uma recurs˜ao linear. Este procedimento pode ser reescrito para que a soma seja efectuada iterativamente. Mostre como fazˆe-lo preenchendo as express˜oes que faltam na seguinte defini¸c˜ao:

(define (somatorio express~ao a seguinte b) (define (iter a resultado)

(if <??> <??>

(iter <??> <??>))) (iter <??> <??>))

2. (Exerc.: 1.31)

O procedimento somatorio ´e apenas o exemplo mais simples de um grande n´umero de abstrac¸c˜oes semelhantes que podem ser descritas como procedimen-tos de ordem superior. Escreva um procedimento produtorio que devolve o produto dos valores de uma fun¸c˜ao calculados num conjunto de valores dado. Mostre como definir factorial em fun¸c˜ao de produtorio. Use ainda produto-rio para aproximar π usando a f´ormula:

π

4 =

2 · 4 · 4 · 6 · 6 · 8 · ·· 3 · 3 · 5 · 5 · 7 · 7 · ·· Fa¸ca vers˜oes recursiva e iterativa deste procedimento. 3. (Exerc.: 1.32)

Mostre que somatorio e produtorio s˜ao casos particulares de uma no¸c˜ao ainda mais geral que denotaremos acumula que combina uma colec¸c˜ao de termos, usando uma fun¸c˜ao de acumula¸c˜ao qualquer:

(acumula combinador valor-nulo expressao a seguinte b)

acumula toma como argumentos as mesmas especifica¸c˜oes que somatorio e produtorio, juntamente com um procedimento combinador que especifi-ca como o corrente termo deve ser combinado com a acumula¸c˜ao dos termos precedentes, e um valor-nulo que indica qual o valor base a usar quando a fun¸c˜ao ´e invocada sem termos. Escreva acumula e mostre como somatorio e produtorio podem ser definidos a partir de acumula.

Fa¸ca vers˜oes recursiva e iterativa deste procedimento. 4. (Exerc.: 1.33)

Podemos obter uma vers˜ao ainda mais geral de acumula (exerc´ıcio anterior) introduzindo a no¸c˜ao de um filtro nos termos a ser combinados. Isto ´e, combi-namos apenas os termos que satisfazem uma condi¸c˜ao especifica. A abstrac¸c˜ao resultante,acumula-filtrado,tem os mesmos argumentos de acumula, junta-mente com um predicado un´ario adicional, que funciona como filtro. Escreva o procedimento acumula-filtrado. Use este procedimento para expressar: a) a soma dos quadrados dos n´umeros primos no intervalo de a a b (assu-mindo a existˆencia de um predicado primo? )

b) o produto de todos os inteiros positivos menores que n que s˜ao primos entre si com n (isto ´e, todos os inteiros positivos i < n tais que MDC(i,n)=1 ).

(8)

5.

Defina a fun¸c˜ao quadrado usando o procedimento

(define exp-curry (lambda (x) (lambda (y) (exp y x)))) 6. (Exerc.: 1.37)

Uma frac¸c˜ao cont´ınua infinita ´e uma express˜ao da forma

f = N1 D1+ N2

D2+D3+···N3

Como exemplo, podemos referir que a expans˜ao infinita em frac¸c˜ao cont´ınua com todos os Ni e os Di iguais a 1 produz 1/φ, onde φ ´e a raz˜ao de ouro. Uma

forma de aproximar uma frac¸c˜ao cont´ınua infinita ´e truncar a expans˜ao ap´os um certo n´umero de termos. Ficamos assim com aquilo a que se chama uma frac¸c˜ao cont´ınua k-termos finita, com a forma:

N1

D1+ N2 . ..+N3

Dk

Suponhamos que n e d s˜ao procedimentos de um argumento (o ´ındice i) que devolvem os Ni e os Di dos termos das frac¸c˜ao cont´ınua. Defina um

procedi-mento frac-cont tal que avaliar (frac-cont n d k) calcule o valor da frac¸c˜ao cont´ınua k-termos finita. Verifique se o procedimento est´a correcto aproximando 1/φ usando

(frac-cont (lambda (i) 1.0) (lambda (i) 1.0) k)

para sucessivos valores de k. Qual o menor k necess´ario para que se obten-ha uma aproxima¸c˜ao correcta at´e 4 casas decimais? Fa¸ca vers˜oes recursiva e iterativa deste procedimento frac-cont.

7. (Exerc.: 1.38)

Em 1737, o matem´atico sui¸co Leonhard Euler publicou De Fractionibus

Con-tinuis, que incluia uma expans˜ao em frac¸c˜ao cont´ınua de e-2, onde e ´e a base dos logaritmos naturais. Nesta frac¸c˜ao, os Niao todos 1, e os Dis˜ao sucessivamente

1,2,1,1,4,1,1,6,1,1,8,... Escreva um programa que use o procedimento frac-cont do exerc´ıcio anterior para aproximar e, baseado na expans˜ao de Euler.

8. (Exerc.: 1.39)

Uma representa¸c˜ao em frac¸c˜ao cont´ınua da fun¸c˜ao tangente foi publicada em 1770 pelo matem´atico alem˜ao J.H.Lambert:

tanx = x

1 −3−x2x2 5−...

onde x est´a em radianos. Defina um procedimento (tan-fc x k) que com-puta uma aproxima¸c˜ao da fun¸c˜ao tangente baseada na f´ormula de Lambert. k especifica o n´umero de termos a ter em conta, como no exerc´ıcio 5.

(9)

9. (Exerc.: 1.40)

Defina um procedimento cubica que possa ser usado conjuntamente com meto-do-newton em express˜oes da forma

(metodo-newton (cubica a b c) 1)

para aproximar zeros da fun¸c˜ao c´ubica x3+ ax2+ bx + c. 10. (Exerc.: 1.41)

Defina um procedimento duplica que toma como argumento um procedimento un´ario e devolve um procedimento que aplica o procedimento original duas vezes. Por exemplo, se inc ´e um procedimento que adiciona 1 ao seu argumento, ent˜ao (duplica inc) ´e um procedimento que adiciona 2 ao seu argumento. Qual ´e o valor devolvido por

(((duplica (duplica duplica)) inc) 5) 11. (Exerc.: 1.42)

Sejam f e g duas fun¸c˜oes un´arias. A composi¸c˜ao f ap´os g ´e a fun¸c˜ao x 7→

f (g(x)). Defina um procedimento composicao que implementa a composi¸c˜ao. Por exemplo,

((composicao quadrado inc) 6) 49

12. (Exerc.: 1.43)

Escreva um procedimento repete que toma como argumentos uma fun¸c˜ao un´ a-ria e um inteiro positivo e devolve a fun¸c˜ao que consiste em n aplica¸c˜oes suces-sivas de f. Por exemplo,

((repete quadrado 2) 5) 625

Pista: Pode ser ´util usar o procedimento do exerc´ıcio anterior. 13. (Exerc.: 1.46)

V´arios dos m´etodos num´ericos descritos neste cap´ıtulo s˜ao instˆancias de uma estrat´egia computacional extremamente geral conhecida como refinamento iter-ativo. Refinamento iterativo significa que para calcular alguma coisa, come¸co com um palpite inicial para a resposta, testo se a resposta ´e suficientemente boa, se n˜ao for melhoro a resposta e continuo o processo, agora com a nova resposta. Escreva um procedimento refinamento-iterativo que toma dois procedimen-tos como argumenprocedimen-tos: um para verificar se uma resposta ´e boa, outro para melhorar uma resposta. refinamento-iterativo deve devolver um procedi-mento que toma uma resposta inicial como arguprocedi-mento e melhora a solu¸c˜ao at´e ser boa. Reescreva os procedimentos raiz-quadrada e ponto-fixo em termos de refinamento-iterativo.

(10)

5

a

Aula Pr´

atica

Estruturas de dados e programa¸

ao por camadas

1. (Exerc.: 2.1)

Defina uma vers˜ao alternativa de make-racional que funcione para argumentos positivos e negativos. O novo procedimento deve normalizar o sinal de forma a que se o n´umero racional for positivo, tanto o numerador como o denomi-nador devem ter sinais positivos, e se o n´umero racional for negativo apenas o numerador deve ter sinal negativo.

2. (Exerc.: 2.3)

Implemente uma representa¸c˜ao de rectˆangulos no plano. Crie procedimentos que calculem o per´ımetro e a ´area de um dado rectˆangulo, em termos dos con-strutores e selectores usados na representa¸c˜ao dos rectˆangulos. Implemente ago-ra uma representa¸c˜ao diferente dos rectˆangulos. Consegue conceber um sistema para que os mesmos procedimentos de c´alculo da ´area e do per´ımetro funcionem para ambas as representa¸c˜oes?

3. (Exerc.: 2.5)

Mostre que ´e poss´ıvel representar pares de inteiros n˜ao-negativos usando apenas n´umeros e opera¸c˜oes aritm´eticas se representarmos o par a e b como o inteiro 2a3b. Quais s˜ao neste caso as defini¸c˜oes correspondentes aos procedimentos

cons, car e cdr? 4. (Exerc.: 2.6)

Caso a representa¸c˜ao de pares como procedimentos n˜ao tenha sido suficien-temente confusa, reparemos que numa linguagem com a capacidade de ma-nipular procedimentos, n˜ao necessitamos de n´umeros (pelo menos inteiros n˜ ao-negativos) pois podemos implementar o zero e a opera¸c˜ao de acrescentar 1 como (define zero (lambda (f) (lambda (x) x)))

(define (soma-1 n)

(lambda (f) (lambda (x) (f ((n f) x)))))

Esta represent¸c˜ao ´e conhecida como os numerais de Church, em homenagem a Alonzo Church, o inventor do c´alculo λ. Defina um e dois directamente (n˜ao em termos de zero e soma-1). Dˆe uma defini¸c˜ao directa de soma (n˜ao em termos da aplica¸c˜ao repetida de soma-1).

(11)

6

a

Aula Pr´

atica

Listas e opera¸

oes sobre listas

1. (Exerc.: 2.20)

Os procedimentos +, * e list tomam um n´umero arbitr´ario de argumentos. Uma forma de definir este g´enero de procedimentos ´e atrav´es da nota¸c˜ao ”dotted-tail”. Na defini¸c˜ao de um procedimento, uma lista de parˆametros com um ponto antes do nome do ´ultimo parˆametro indica que, quando o procedimento ´e chamado, os parˆametros iniciais (se existirem) ter˜ao como valores os primeiros argumentos, como usual, mas o valor do ´ultimo parˆametro ser´a uma lista dos restantes argumentos. Por exemplo, dada a defini¸c˜ao

(define (f x y . z) <corpo>)

o procedimento f pode ser chamado com 2 ou mais argumentos. Se avaliar-mos

(f 1 2 3 4 5 6)

ent˜ao no corpo de f, x toma o valor 1, y toma o valor 2, e z a lista (3 4 5 6) . Use esta nota¸c˜ao para escrever uma fun¸c˜ao mesma-paridade que toma um ou mais inteiros e devolve a lista de todos os argumentos que tˆem a mesma paridade do primeiro argumento. Por exemplo,

(mesma-paridade 1 2 3 4 5 6 7) (1 3 5 7) (mesma-paridade 2 3 4 5 6 7) (2 4 6) 2. (Exerc.: 2.21)

O procedimento lista-quadrados toma uma lista de n´umeros e devolve os seus quadrados.

(lista-quadrados (list 1 2 3 4)) (1 4 9 16)

Apresentamos em seguida duas defini¸c˜oes diferentes de lista-quadrados. Complete-as preenchendo as express˜oes assinaladas com ¡??¿.

(define (lista-quadrados elementos) (if (null? elementos)

null

(cons <??> <??>)))

(define (lista-quadrados elementos) (map <??> <??>))

3. (Exerc.: 2.22)

O Lu´ıs tentou reescrever o primeiro procedimento lista-quadrados do exerc´ıcio anterior de forma torn´a-lo iterativo.

(define (lista-quadrados elementos) (define (iter coisas resultado)

(if (null? coisas) resultado

(iter (cdr coisas)

(cons (quadrado (car coisas)) resultado))))

(12)

Infelizmente, definir lista-quadrados desta forma faz com que a lista de resposta fique na ordem contr´aria `a desejada. Porquˆe?

Lu´ıs tenta corrigir esta falha trocando os argumentos do cons: (define (lista-quadrados elementos)

(define (iter coisas resultado) (if (null? coisas)

resultado

(iter (cdr coisas) (cons resultado

(square (car coisas)))))) (iter elementos null))

Esta vers˜ao tamb´em n˜ao funciona. Explique porquˆe. 4. (Exerc.: 2.23)

O procedimento for-each ´e semelhante a map. Toma como argumentos um procedimento e uma lista de elementos. Contudo, ao inv´es de formar uma lista de resultados, for-each aplica o procedimento a cada um dos elementos se-quencialmente. Os valores devolvidos por aplicar o procedimento a cada um dos elementos n˜ao s˜ao usados. for-each ´e usado com procedimentos que exe-cutam uma ac¸c˜ao, como imprimir para o ecr˜a. Por exemplo,

(for-each (lambda (x) (newline) (display x)) (list 57 321 88))

57 321 88

Fa¸ca uma implementa¸c˜ao de for-each. 5. (Exerc.: 2.27)

Modifique o procedimento reverse para produzir o procedimento deep-reverse que toma uma lista como argumento e devolve a lista com os seus elementos por ordem inversa e com todas as suas sub-listas invertidas tamb´em. Por exemplo, (define x (list (list 1 2) (list 3 4)))

x ((1 2) (3 4)) (reverse x) ((3 4) (1 2)) (deep-reverse x) ((4 3) (2 1)) 6. (Exerc.: 2.28)

Escreva um procedimento folhas que tem como argumento uma ´arvore e devolve uma lista das folhas da ´arvore, ordenadas da esquerda para a direita. Como exemplo,

(define x (list (list 1 2) (list 3 4))) (folhas x) (1 2 3 4)

(13)

7. (Exerc.: 2.29)

Um m´obil bin´ario consiste em dois ramos, um ramo direito e um ramo esquerdo. Cada ramo ´e uma haste com um certo comprimento, da qual est´a suspenso um peso ou ent˜ao outro m´obil bin´ario. Podemos representar um m´obil bin´ario contruindo-o a pertir de dois ramos:

(define (make-mobile left right) (list left right))

Um ramo ´e constru´ıdo a partir de um comprimento (que ´e um n´umero) juntamente com uma estrutura, que pode ser um n´umero (representando um peso) ou outro m´obil.

(define (make-branch length structure) (list length structure))

Escreva os correspondentes selectores ramo-esquerdo e ramo-direito, que devolvem os ramos de um m´obil, e comprimento-ramo e estrutura-ramo que devolvem os componentes de um ramo. Usando os selectores que definiu, defina um procedimento peso-total que devolve o peso total de um m´obil. Um m´obil diz-se equilibrado se as for¸cas de tors˜ao aplicadas pelos seus ramos direito e esquerdo s˜ao iguais (isto ´e, se o comprimento da haste esquerda multiplicado pelo suspenso dessa haste ´e igual ao produto correspondente para a haste direita) e se cada um dos subm´oveis suspensos dos seus ramos estiver equilibrado. Construa um predicado que testa se um m´obil est´a equilibrado. Suponha que alteramos a representa¸c˜ao de m´oveis para que os construtores sejam

(define (make-mobile left right) (cons left right))

(define (make-branch length structure) (cons length structure))

O que ´e necess´ario alterar aos programas j´a escritos para funcionarem de acordo com esta representa¸c˜ao?

8. (Exerc.: 2.30)

Defina um procedimento ´arvore-quadrados, an´alogo a lista-quadrados, ou seja, ´arvore-quadrados deve comportar-se como se segue:

(´arvore-quadrados (list 1

(list 2 (list 3 4) 5) (list 6 7)))

(1 (4 (9 16) 25) (36 49))

Defina ´arvore-quadrados directamente (sem usar procedimentos de ordem superior). Redefina a fun¸c˜ao recorrendo a map.

9. (Exerc.: 2.31)

Na continua¸c˜ao do exerc´ıcio anterior, escreva um procedimento ´arvore-map com a propriedade de ´arvore-quadrados poder ser definido como:

(14)

10. (Exerc.: 2.32)

Podemos representar um conjunto como uma lista de elementos distintos, e podemos representar o conjunto dos subconjuntos de um conjunto dado como uma lista de listas. Por exemplo, se conjunto ´e (1 2 3), ent˜ao o conjunto dos seus subconjuntos ´e (() (1) (2) (3) (1 2) (1 3) (2 3) (1 2 3)). Complete a seguinte defini¸c˜ao de um procedimento que gera o conjunto dos subconjuntos de um conjunto dado.

(define (subconjuntos s) (if (null? s)

(list null)

(let ((resto (subconjuntos (cdr s)))) (append resto (map <??> resto))))) 11. (Exerc.: 2.33)

Complete as seguintes defini¸c˜oes: (define (map p sequencia)

(acumula (lambda (x y) <??>) null sequencia)) (define (append seq1 seq2)

(acumula cons <??> <??>)) (define (length sequencia)

(acumula <??> 0 sequencia)) 12. (Exerc.: 2.34)

A avalia¸c˜ao dum polin´omio pode ser formulada como uma acumula¸c˜ao. Avaliamos o polin´omio

anxn+ an−1xn−1+ ... + a1x + a0

usando um algoritmo conhecido, dito regra de Horner, que estrutura o c´alculo na forma

(...(anx + an−1)x + ... + a1)x + a0)

Por outras palavras, come¸camos com an, multiplicamos por x, somamos an−1,

multiplicamos por x, e assim sucessivamente at´e chegarmos a a0. Complete o seguinte procedimento de forma a que avalie um polin´omio de acordo com a regra de Horner. Assuma que os coeficientes do polin´omio est˜ao ordenados de

a0 a an.

(define (horner-eval x sequencia-coeficientes)

(acumula (lambda (este-coeficiente termos-superiores) <??>) 0

sequencia-coeficientes))

Por exemplo, para calcular 1 + 3x + 5x3+ x5para x = 2 avaliar´ıamos: (horner-eval 2 (list 1 3 0 5 0 1))

13. (Exerc.: 2.35)

Redefina conta-folhas como uma acumula¸cao: (define (count-leaves t)

(15)

14. (Exerc.: 2.36)

O procedimento acumula-n ´e semelhante a acumula excepto que tem como terceiro argumento uma sequˆencia de sequˆencias, que se assume terem o mes-mo n´umero de elementos. Aplica o procedimento de acumula¸c˜ao a todos os primeiros elementos das sequˆencias, depois a todos os segundos elementos, e devolve a sequˆencia dos resultados. Tomemos como exemplo uma sequˆencia s que tem quatro sequencias, ((1 2 3)(4 5 6)(7 8 9)(10 11 12)); ent˜ao o valor de (accumulate-n + 0 s) deve ser a sequˆencia (22 26 30). Acabe a defini¸c˜ao de acumula-n.

(define (acumula-n op init seqs) (if (null? (car seqs))

null

(cons (acumula op init <??>) (acumula-n op init <??>)))) 15. (Exerc.: 2.37)

Suponha que representamos vectores v = (vi), como sequˆencias de n´umeros, e

matrizes m = (mij) como sequˆencias de vectores (as colunas da matriz). Por

exemplo, a matriz   1 2 3 4 4 5 6 6 6 7 8 9  

´e representada como a sequˆencia ((1 2 3 4)(4 5 6 6)(6 7 8 9)). Com esta representa¸c˜ao podemos usar opera¸c˜oes sobre sequˆencias para exprimir concisa-mente as opera¸c˜oes b´asicas sobre vectores e matrizes. Estas opera¸c˜oes (descritas em qualquer livo de ´algebra linear) s˜ao:

(produto-interno v w ) devolve a somaPiviwi

(matriz-*-vector m v ) devolve o vector t, com ti=Pjmijvj

(matriz-*-matriz m n) devolve a matriz p, com pij =Pkmiknkj

(transposta m) devolve a matriz n onde nij = mji.

podemos definir o produto interno como: (define (produto-interno v w)

(acumula + 0 (map * v w)))

Complete os seguintes procedimentos para calcular as restantes oper¸c˜oes sobre matrizes:

(define (matriz-*-vector m v) (map <??> m))

(define (transposta mat) (acumula-n <??> <??> mat)) (define (matriz-*-matriz m n)

(let ((cols (transposta n))) (map <??> m)))

16. (Exerc.: 2.38)

O procedimento acumula tamb´em ´e conhecido como fold-right, porque com-bina o primeiro elemento da sequˆencia com o resultado de combinar todos os elementos `a direita. Tamb´em existe um fold-left, an´alogo a fold-right, mas que combina os elementos na ordem contr´aria.

(16)

(define (fold-left op inicial sequencia) (define (iter resultado resto)

(if (null? resto) resultado

(iter (op resultado (car resto)) (cdr resto))))

(iter inicial sequencia)) Quais os resultados de

(fold-right / 1 (list 1 2 3)) (fold-left / 1 (list 1 2 3))

(fold-right list null (list 1 2 3)) (fold-left list null (list 1 2 3))

Que condi¸c˜ao deve satisfazer op, para que fold-right e fold-left produzam o mesmo resultado?

17. (Exerc.: 2.39)

Complete a seguinte defini¸c˜ao do procedimento reverse `a custa de fold-right e fold-left:

(define (reverse sequence)

(fold-right (lambda (x y) <??>) null sequencia)) (define (reverse sequence)

(fold-left (lambda (x y) <??>) null sequencia)) 18. (Exerc.: 2.40)

Defina um procedimento pares-unicos que, dado um inteiro n, gera a sequˆencia de pares (i,j) com 16 i < j 6 n. Use pares-unicos para simplificar a defini¸c˜ao da fun¸c˜ao soma-pares-primos.

19. (Exerc.: 2.41)

Escreva um procedimento para encontrar todos os triplos ordenados de inteiros positivos distintos i,j e k menores ou iguais a um dado inteiro n e cuja soma totaliza um dado inteiro s.

20. (Exerc.: 2.42)

O problema das oito rainhas consiste em colocar oito rainhas num tabuleiro de xadrez de forma a que nenhuma rainha esteja em cheque por parte de outra (ou seja, garantindo que n˜ao h´a 2 rainhas na mesma linha, coluna ou diagonal). Uma forma de resolver o problema ´e percorrer o tabuleiro colocando uma rainha em cada coluna. Uma vez colocadas k-1 rainhas, temos de colocar a k-´esima numa posi¸c˜ao em que n˜ao ponha em xeque nenhuma das rainhas que j´a estavam no tabuleiro. Podemos formular esta estrat´egia recursivamente: assumindo que ger´amos a sequˆencia de todas as formas v´alidas de colocar k-1 rainhas nas primeiras k-1 colunas. Para cada uma destas hip´oteses, geramos um conjunto colocando um rainha em cada linha da k-´esima coluna. Finalmente filtramos as novas posi¸c˜oes mantendo apenas aquelas em que a nova rainha n˜ao coloca em xeque nenhuma das restantes. Isto produz a sequˆencia de todas as formas v´alidas de colocar k rainhas nas primeiras k colunas do tabuleiro. Continuando este processo encontramos n˜ao apenas uma solu¸c˜ao, mas todas as solu¸c˜oes para o problema.

(17)

sequˆencia de todas as solu¸c˜oes do problema de colocar n rainhas num tab-uleiro n × n. rainhas tem um pocedimento interno rainhas-cols que devolve a sequˆencia de todas as formas de colocar rainhas nas primeiras k colunas do tabuleiro.

(define (rainhas tamanho-tabuleiro) (define (rainhas-cols k)

(if (= k 0)

(list tabuleiro-vazio) (filter

(lambda (posicoes) (ok? k posicoes)) (flatmap

(lambda (resto-das-rainhas) (map (lambda (nova-linha)

(junta-posicao nova-linha k resto-das-rainhas)) (enumerate-interval 1 tamanho-tabuleiro))) (rainhas-cols (- k 1)))))) (rainhas-cols tamanho-tabuleiro))

Neste procedimento resto-das-rainhas ´e uma forma de colocar k-1 rain-has nas primeiras k-1 colunas, e nova-linha ´e a linha em que vamos colocar a rainha da k-´esima coluna. Complete o programa implementando uma rep-resenta¸c˜ao para conjuntos de posi¸c˜oes do tabuleiro, incluindo o procedimento junta-posicao, que acrescenta uma nova posi¸c˜ao linha-coluna a um conjunto de posi¸c˜oes, e tabuleiro-vazio que representa um conjunto vazio de posi¸c˜oes. Escreva tamb´em o procedimento ok?, que para um dado conjunto de posi¸c˜oes determina se a rainha da k-´esima posi¸c˜ao est´a ou n˜ao em xeque e devolve #t caso n˜ao esteja.

Referências

Documentos relacionados

Desta forma, além de retardar a oxidação lipídica, o preparado desenvolvido apresentou benefícios como estabilização da cor e manutenção das características sensoriais

Almanya'da olduğu gibi, burada da bu terimin hiçbir ayrım gütmeden, modern eğilimleri simgeleyen tüm sanatçılar için geçerli olduğu anlaşılıyor.. SSCB'de ilk halk

[r]

É perceptível, desta forma, o constante aumento do aprofundamento dos personagens: os “príncipes” têm agora não só nome e falas, mas personalidades bem desenvolvidas,

a) Seleciona um par de cromossomos genitores dentro da população atual, com a probabilidade de seleção sendo diretamente proporcional à sua adaptação. O mesmo

Contribuições/Originalidade: A identificação dos atributos que conferem qualidade ao projeto habitacional e das diretrizes de projeto que visam alcançá-los, são de fundamental

Código Descrição Atributo Saldo Anterior D/C Débito Crédito Saldo Final D/C. Este demonstrativo apresenta os dados consolidados da(s)

Ainda que não se utilizem diretamente suas obras, os fundamentos por ele expostos – há mais de um século – ainda permanecem vivos nas discussões tributárias