Jump to content
lesiano

Factorial - Dúvida

Recommended Posts

lesiano

module Factorial where

fact :: Int -> Int
fact a = if a == 0 then 0 else fact(a-1) * a

Estou a pensar mal?

Share this post


Link to post
Share on other sites
Nazgulled

Acho que isto resolve o problema e é mais simples:

module Factorial where

fact :: Int -> Int
fact 1 = 1
fact x = fact(x-1) * x

(já não programo em Haskell há + de 1 ano)

Share this post


Link to post
Share on other sites
Rui Carlos

Estás pensar mal. Vê a definição matemática do factorial...

Repara que no código que tens, o factorial de um número vai sempre ser n*(n-1)*(n-2)*...*0. Resumindo, vai sempre dar 0 como resultado. O teu erro, é estares a considerar que o factorial de 0 é 0, quando, por definição, é 1.

A solução do Nazgulled funciona, só que não está definida para 0.

Assim, podes fazer, por exemplo:

fact :: Int -> Int
fact a = if a == 0 then 1 else fact(a-1) * a

ou

fact :: Int -> Int
fact 0 = 1
fact x = fact(x-1) * x

Share this post


Link to post
Share on other sites
Nazgulled

Eu ainda tenha o caso de paragem como 0, mas depois mudei para 1, mas não me perguntes porquê :X Mas assim à primeira vista o meu pensamento foi este, mas aviso desde já que foi muito à pressa:

Imagine-se que queremos o !5.

Minha solução:

5 x 4 x 3 x 2 x 1

Tua solução

5 x 4 x 3 x 2 x 1 x 1

Não é isto que vai acontecer? Fazendo a minha solução mais "lógica"?

Share this post


Link to post
Share on other sites
Rui Carlos

A diferença é que a minha funciona para o valor 0 e a tua não. E como o valor de 0! existe, a função deve estar preparada para devolver o resultado.

A alternativa seria fazer:

fact :: Int -> Int
fact 0 = 1
fact 1 = 1
fact x = fact(x-1) * x

Share this post


Link to post
Share on other sites
lesiano

Malta, muito obrigado.  :P

Acabei por fazer este código antes de vocês me explicarem a cena:

module Factorial where

fact :: Integer -> Integer
fact 0 = 1
fact 1 = 1
fact a = if a == 0 then a else fact(a-1) * a

Ainda acho q ñ percebi bem esta liguagem. :S

Esta função faz:

fact 5 = fact(4) * 5 * fact(3) * 5 * fact(2) * 5 * fact(1) * 5?

Qd fiz a função estava a fazer sentido, mas ñ estou a perceber mt bem. :)

Share this post


Link to post
Share on other sites
Rui Carlos

fact(5)=fact(4)*5

fact(4)=fact(3)*4

fact(3)=fact(2)*3

fact(2)=fact(1)*2

fact(1)=1

substituindo, fica:

fact(2)=fact(1)*2=1*2

fact(3)=fact(2)*3=1*2*3

fact(4)=fact(3)*4=1*2*3*4

fact(5)=fact(4)*5=1*2*3*4*5

Share this post


Link to post
Share on other sites
Betovsky

a-1


"Give a man a fish and he will eat for a day; Teach a man to fish and he will eat for a lifetime. The moral? READ THE MANUAL !"

Sign on a computer system consultant's desk

Share this post


Link to post
Share on other sites
lesiano

fact a = if a == 0 then a else fact(a-1) * a

O "a" a negrito é decrementado pela instrução a sublinado?

Share this post


Link to post
Share on other sites
Betovsky

Não.

Primeiro porque Haskell é uma linguagem pura, não há side-effects, logo essa pergunta nem se coloca.

Segundo, tu nessa instrução não estás a atribuir nenhum valor ao 'a'. Mesmo se fosse numa linguagem não pura, por exemplo C, o valor de 'a' não seria decrementado, porque não é nenhuma atribuição.

O que é decrementado é o valor que a função 'fact' recebe como parâmetro. Pensa em Haskell como se tudo fosse constantes.


"Give a man a fish and he will eat for a day; Teach a man to fish and he will eat for a lifetime. The moral? READ THE MANUAL !"

Sign on a computer system consultant's desk

Share this post


Link to post
Share on other sites
lesiano

module Factorial where

fact :: Integer -> Integer
fact 0 = 1
fact 1 = 1
fact a = fact(a-1) * a

Funciona e percebe-se melhor. Percebi o programa fazendo um esquema e percebi q detesto esta linguagem.  😳

Obg.  ;)

Share this post


Link to post
Share on other sites
lesiano

module Fibonacci where

fibo :: Integer -> Integer --Apenas recebe um Integer pq ñ se pode colocar Int -> Integer. Devolve um Integer pq a certa algura os números ficam mt grandes.
fibo 0 = 0
fibo 1 = 1
fibo n = fibo(n-2) + fibo(n-1)

Fiz este em dois segundos, sem if's percebe-se melhor. Btw, o integer/int impede q o n assuma valores negativos?

Obg.

Share this post


Link to post
Share on other sites
Baderous

Btw, o integer/int impede q o n assuma valores negativos?

Não.

Um elemento do tipo Integer não tem qualquer limite (por isso se diz tratar-se de números inteiros de precisão infinita); no caso dos elementos do tipo Int, a sua gama está limitada entre um limite inferior (designado por primMinInt) e por um limite superior (designado por primMaxInt).

Share this post


Link to post
Share on other sites
Betovsky

--Apenas recebe um Integer pq ñ se pode colocar Int -> Integer. Devolve um Integer pq a certa algura os números ficam mt grandes.

Claro que podes.

fibo :: Int -> Integer
fibo 0 = 0
fibo 1 = 1
fibo n = fibo (n-2) + fibo (n-1)

Isto funciona perfeitamente.

Percebi o programa fazendo um esquema e percebi q detesto esta linguagem.  😳

Isso é impossível. Ainda não estás é bem entrosado com a dita. Depois não queres outra coisa  :)

"Give a man a fish and he will eat for a day; Teach a man to fish and he will eat for a lifetime. The moral? READ THE MANUAL !"

Sign on a computer system consultant's desk

Share this post


Link to post
Share on other sites
Nazgulled

Funciona e percebe-se melhor. Percebi o programa fazendo um esquema e percebi q detesto esta linguagem.  😳

Eu disse o mesmo nas minhas primeiras aulas... Depois fui-lhe apanhando o jeito e a perceber como é que a dita funcionava e comecei a gostar mais. Não está no topo das minhas preferidas, mas também já não a detesto como detestava quando a vi pela primeira vez.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.