2012-03-11 3 views
12

J'ai trois mots dans une liste ["a", "b", "c"]. Je veux trouver toutes les combinaisons possibles dans le jeu 5,6 etc.Combinaisons Haskell et permutation

par exemple pour voir 5 j'aurais

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

aaaaaa ci-dessus sera essentiellement « un », « a », « a » , « un », « a » ....

+0

Je travaille sur ce sujet depuis hier. n'est pas allé beaucoup plus loin. Si je peux avoir une idée alors je pourrais être capable de le faire. – Waqas

+2

@ utilisateur1115751: Pour commencer, recherchez "[produit cartésien haskell] (http://stackoverflow.com/search?q=haskell+cartesian+product&submit=search)". – kennytm

Répondre

20

replicateM fait ce que vous voulez:

> 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

Bien sûr, la réponse de nanothief donne la plus courte solution, mais il pourrait être instructif et amusant de le faire vous-même .

Il existe plusieurs façons d'écrire une fonction pour le produit cartésien. Par exemple. vous pouvez utiliser la liste compréhensions:

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

(++) :: [a] -> [a] -> [a] - voir Data.List. Une autre possibilité est d'utiliser l'instance Applicative de la liste:

import Control.Applicative 

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

Maintenant, vous devez appliquer cette opération à plusieurs reprises. Un pli peut faire, par exemple .:

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

Comprendre cette solution pourrait être plus utile que de prendre le raccourci replicateM. Cela dit, vous auriez pu trouver ce dernier facilement en utilisant Hoogle.

-

Pour en savoir plus sur Foncteurs et Applicative voir les définitions fmap (<$>) et ap (<*>). Functors, Applicatives, And Monads In Pictures peut également être une bonne ressource.

+0

Cela ne compile pas. Il doit y avoir une contrainte de type pour les opérandes passées à '++' – dopatraman

+0

J'ai essayé ceci dans GHCi, là ça fonctionne sans contraintes. – Landei

+0

Comment modifieriez-vous ceci pour les nombres, par exemple? Ou tout autre type? – dopatraman