2012-03-11 71 views
12

Tengo tres palabras en una lista ["a", "b", "c"]. quiero encontrar todas las combinaciones posibles de establecer etc. 5,6Combinaciones Haskell y permutación

por ejemplo para el conjunto de 5 Me hubiera

**[ [aaaaa],[aaaab],[aaaac], [aaabc] , ..... ]** etc 3^5 = 243 combinations 

aaaaaa anterior, básicamente, "un", "una", "a" , "un", "una" ....

+0

estoy trabajando en esto desde ayer. no fue mucho más allá. si puedo tener una idea, entonces podría ser capaz de hacerlo. – Waqas

+2

@ user1115751: Para comenzar, busque "[producto cartesiano de haskell] (http://stackoverflow.com/search?q=haskell+cartesian+product&submit=search)". – kennytm

Respuesta

20

replicateM hace lo que quiere:

> import Control.Monad 
> replicateM 5 ["a", "b", "c"] 
[["a","a","a","a","a"],["a","a","a","a","b"],["a","a","a","a","c"],["a","a","a","b","a"],["a","a","a","b","b"],["a","a","a","b","c"],["a","a","a","c","a"],["a","a","a","c","b"],["a","a","a","c","c"],["a","a","b","a","a"],["a","a","b","a","b"],["a","a","b","a","c"],["a","a","b","b","a"],["a","a","b","b","b"],["a","a","b","b","c"]...] 
20

Por supuesto, la respuesta de nanothief da la solución más corta, pero podría ser instructiva y divertida de hágalo usted mismo .

Hay muchas maneras de escribir una función para el producto cartesiano. P.ej. puede utilizar las listas por comprensión:

prod :: [[a]] -> [[a]] -> [[a]] 
prod as bs = [a ++ b | a <- as, b <- bs] 

Dónde (++) :: [a] -> [a] -> [a] - ver Data.List. Otra posibilidad es utilizar el Applicative instancia de lista:

import Control.Applicative 

prod as bs = (++) <$> as <*> bs 

Ahora es necesario aplicar esta operación varias veces. A veces se puede hacer esto, por ejemplo .:

rep :: Int -> [[a]] -> [[a]] 
rep n as = foldr1 prod $ replicate n as 

rep 3 ['a','b','c'] 
--["aaa","aab","aac","aba","abb","abc","aca","acb","acc","baa","bab", 
--"bac","bba","bbb","bbc","bca","bcb","bcc","caa","cab","cac","cba", 
--"cbb","cbc","cca","ccb","ccc"] 

La comprensión de esta solución podría ser más valioso que tomar el atajo replicateM. Dicho esto, podría haber encontrado el último fácilmente usando Hoogle.

-

Para más información sobre Functors y Aplicativo ver definiciones fmap (<$>) y ap (<*>). Functors, Applicatives, And Monads In Pictures también puede ser un buen recurso.

+0

Esto no se compila. Debe haber una restricción de tipo para los operandos pasados ​​a '++' – dopatraman

+0

Intenté esto en GHCi, allí funciona sin restricciones. – Landei

+0

¿Cómo modificar esto para los números, por ejemplo? O cualquier otro tipo? – dopatraman

Cuestiones relacionadas