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

nram

Alterar uma lista

7 mensagens neste tópico

Bem, tenho mais uma dúvida em listas.

Tenho uma lista +- assim: [J1,Nulo,Nulo,Nulo]

e pretendo fazer uma função para alterar o 1º nulo que aparecer para J1 ou J2. Eu fiz a seguinte função mas está a dar erro.

data Valores  = Nulo
              | J1
              | J2
   deriving (Show,Eq)

alteraC :: [Valores] -> Valores -> [Valores]
alteraC [] val = []
alteraC (x:xs) val | (Nulo == x) = val ++  xs
                   | otherwise   = x: (alteraC xs val)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

alteraC (x:xs) val | (Nulo == x) = val ++  xs

O teu val não é uma lista, logo não podes fazer ++ como estás a fazer.

Tens 2 hipoteses, a primeira é a mais correcta.

alteraC (x:xs) val | Nulo == x = val : xs
-- ou
alteraC (x:xs) val | Nulo == x = [val] ++ xs

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Antes de mais obrigado. eu tinha feito isso direito, mas como me estava a dar um erro pensei que fosse dessa funçao. mas não era.

Agora ando preso á horas para tentar juntar matrizes na diagonal.

ou seja: [[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20]]

e fique assim:

[[1,],[2,6],[3,7,11],[4,8,12,16],[5,9,13,17],[10,14,18],[15,19],[20]]

ou assim:

[[0,0,0,1,],[0,0,2,6],[0,3,7,11],[4,8,12,16],[5,9,13,17],[0,10,14,18],[0,0,15,19],[0,0,0,20]]

....

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Isso é simples. Poderás fazer algo tipo isto (o código poderá ser melhorado, mas a ideia deverá andar a volta disto)

diagonal [] _ = ([],[])
diagonal ([]:t) n = diagonal t (n-1)
diagonal ((x:xs):t) 0 = ([x],xs:t)
diagonal ((x:xs):t) n = let (x',m') = diagonal t (n-1)
                        in (x:x', xs:m')

diagonais = reverse . diagonais'
diagonais' matriz = fst $ foldl fun ([],matriz) [0..(length matriz)*2-1]
  where fun (r,m) i = let (r', m') = diagonal m i
                      in (r':r, m')

main = print $ diagonais [[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20]]

-- Ou com zeros
daZeros [] = []
daZeros (x:xs) = x : daZeros (map (0:) xs)

diagonais = fill . transpose . reverse . daZeros 

fill (x:xs) = x: map fun xs
  where len = length x
        fun l = (replicate (len - (length l)) 0) ++ l

main = print $ diagonais [[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20]]

No caso da versão dos zeros, fica mais simples já que podemos aproveitar os zeros para alinhar as colunas e depois o transpose faz o resto do trabalho por nós. Senão temos que ser nós a fazer o trabalho manualmente que é o caso da função diagonal. De qualquer forma, isto é um código um pouco feito em cima do joelho, certamente optimizações/melhoramentos poderão ser feitos.

Penso que o código funcione para qualquer tamanho de matriz desde que quadrada. Se o tamanho for fixo, o código pode ser optimizado..

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas Noites,

Antes de mais é a minha primeira contribuiçao, mas descobri a pouco tempo este forum. Os meus parabéns aos fundadores.

Por acaso também andava a tentar fazer essa da diagonal  e a primeira versão do Betovsky é porreira porque tambem funciona para matrizes nao quadradas, mas tenho algumas questoes acerca da sintaxe:

Como funciona o $ em: "fst $ foldl fun ([],matriz) [0..(length matriz)*2-1]"?

Obrigado por qualquer explicaçao.

Cumprimentos

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

f$x é equivalente a f x ou f (x). neste caso concreto, fst $ foldl fun ([],matriz) [0..(length matriz)*2-1] é equivalente a fst (foldl fun ([],matriz) [0..(length matriz)*2-1]).

A utilização do $ por vezes tem a vantagem de dar menos trabalho com os parêntesis.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas,

Muito obrigado pela explicação e pelo tempo dispendido.

Cumprimentos

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