2012-03-11 15 views
12

Mam trzy słowa na liście ["a", "b", "c"]. chcę, aby znaleźć wszystkie możliwe kombinacje w zestawie 5,6 itdKombinacje Haskella i permutacja

na przykład do zestawu 5 bym

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

AAAAAA powyżej będzie w istocie być „a”, „a”, „a” „a”, „a” ....

+0

Pracuję nad tym od wczoraj. nie poszło znacznie dalej. jeśli mogę uzyskać jakiś pomysł, to będę w stanie to zrobić. – Waqas

+2

@ user1115751: Aby rozpocząć, wyszukaj "[produkt kartezjański haskell] (http://stackoverflow.com/search?q=haskell+article+product&submit=search)". – kennytm

Odpowiedz

20

replicateM robi to, co chcesz:

> 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

oczywiście, odpowiedź nanothief daje najkrótszą rozwiązanie, ale może to być pouczające i zabawne zrobić to sam .

Istnieje wiele sposobów na napisanie funkcji dla produktu kartezjańskiego. Na przykład. można użyć wyrażeń listowych:

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

Gdzie (++) :: [a] -> [a] -> [a] - patrz Data.List. Inną możliwością jest użycie instancji Applicative z listy:

import Control.Applicative 

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

teraz trzeba zastosować tę operację wielokrotnie. Fałd może to zrobić, np .:

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

Zrozumienie tego rozwiązania mogą być bardziej wartościowe niż biorąc skróty replicateM. To powiedziawszy, możesz łatwo znaleźć to drugie przy użyciu Hoogle.

-

Więcej informacji na temat funktorów i aplikacyjnych patrz definicje fmap (<$>) i ap (<*>). Functors, Applicatives, And Monads In Pictures może również być dobrym źródłem informacji.

+0

To nie kompiluje się. Musi istnieć ograniczenie typu dla operandów przekazanych do '++' – dopatraman

+0

Próbowałem tego w GHCi, tam działa bez ograniczeń. – Landei

+0

Jak zmieniłbyś to na przykład w liczbach? Lub jakikolwiek inny typ? – dopatraman