• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

lesiano

Factorial - Dúvida

18 mensagens neste tópico

module Factorial where

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

Estou a pensar mal?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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"?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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. :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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.  ;)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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).
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

--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  :)
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora