terça-feira, 5 de abril de 2011

Olá!

Alguns desavios foram dados em sala de aula. Entre eles há o dos números primos. Nesse desavio, precisamos fazer duas funções: uma que me diga se um número x dado é primo, e outra que dado um index n, diz qual é o enéssimo número primo.

Observamos que para solucionar a segunda função necessitamos ter a lista de números primos e para construir essa lista será necessário verificar quais números são primos, logo depende da primeira função.

Focando nessa primeira função, verificamos que usaríamos listas infinitas. E tivemos problemas para avaliar a "parada" da lista de números primos. Para solucionar isso, relembramos o uso do takewhile.

Dessas discussões fiz o seguinte código:

serPrimo x xs = [x| y<-xs, mod x y == 0] == []
primos= 2:[x|x<-[3,5..], serPrimo x (primeirosPrimos x primos)]
primeirosPrimos x xs = takeWhile (<sqrt(x)) xs

Porém, tive problemas com o primeiro parâmetro do takeWhile.
O resultado do sqrt é floating, e esse parâmetro deve ser inteiro.
Para resolver isso, coloquei o "truncate".
Apesar dessa minha atitude, o erro persistiu, e descobri que isso era devido a erros de hierarquia de tipos, pois o truncate é aplicado ao tipo RealFrac e não Floating.
Para solucionar isso fizemos a conversão de x com o fromIntegral. Dessa maneira, os tipos foram ajustados e a hierarquia respeitada. Assim, o meu código ficaria:

serPrimo x xs = [x| y<-xs, mod x y == 0] == []
primos= 2:[x|x<-[3,5..], serPrimo x (primeirosPrimos x primos)]
primeirosPrimos x xs = takeWhile (<truncate(sqrt(fromIntegral x))) xs

Outro erro estava acontecendo, mas dessa vez relacionado a função serPrimo. Ele ainda não foi totalmente esclarecido. Os resultados estavam incluindo valores que não são primos, como 15, 25, 35, etc. Continuarei a verificar isso.

Em sala de aula o professor apresentou a solução recursiva para esse erro:

serPrimo x [] = TRUE
serPrimo x (y:xs) = not(mod x y ==0) || serPrimo x xs

Portanto, a solução para a primeira função foi:

serPrimo x [] = TRUE
serPrimo x (y:xs) = not(mod x y ==0) || serPrimo x xs
primos= 2:[x|x<-[3,5..], serPrimo x (primeirosPrimos x primos)]
primeirosPrimos x xs = takeWhile (<truncate(sqrt(fromInteger x))) xs

A segunda função será dada por:

primo n = primos!!n

Simples assim!

Té+!

Nenhum comentário:

Postar um comentário