2016-03-21 12 views
0

ListA ([String]) ve örnek konumlar ListB ([Int]) öğelerini içeren iki liste var liste anlamalarını kullanarak yeni bir ListC ([String]) nasıl oluşturulur?Haskell List Anlaşılır listeA listB -> listC

sol numarası (ListB bakınız) daima

Step 1: get elem 1, add the head of the ListC 
     ListC = ["a"] 
Step 2: get elem 2, add the head of the ListC 
     ListC = ["c","a"] 
Step 3: get elem 1, add the head of the ListC 
     ListC = ["b","c","a"] 

so the full chain: 
a b c -> 1 2 1 -> a -> c a -> b c a 

daha şablonları daha haklı:: Örneğin

ListA::[String] 
ListB::[int] 
ListC::[String] 

ListA ListB ListC 
a b c -> 3 2 1 -> a b c 
a b c -> 2 2 1 -> a c b 
a b c -> 3 1 1 -> b a c 
a b c -> 1 2 1 -> b c a 
a b c -> 2 1 1 -> c a b 
a b c -> 1 1 1 -> c b a 

bu fonksiyon (her not geçerli bir sayısal dizileri üretmektir sol eleman, bir öncekinden daha fazla, en az 1, yani baş en büyük elementtir)

module Main (main) where 

import System.Random 

main :: IO() 

randomList :: Int -> [Int] -> StdGen -> [Int] 
randomList 0 xlist _ = reverse xlist 
randomList n xlist gen = randomList (n-1) (randomVal : xlist) gen' 
    where (randomVal, gen') = randomR (1,n) gen 

shuffle :: [Int] -> [String] -> [String] -> [String] 
shuffle [] _ deckB = deckB 
shuffle pl deckA deckB = shuffle (tail pl) (hs ++ tail ts) (head ts : deckB) 
    where (hs, ts) = splitAt (pos-1) deckA 
      pos = head pl 

ranks = ["2","3","4","5","6","7","8","9","T","J","Q","K","A"] 
suits = ["C","D","H","S"] 
deck = [rank ++ suit | suit <- suits, rank <- ranks] 

main = do 
    gen <- newStdGen 
    let len = 52 :: Int 
    let permutationList = randomList len [] gen 
    let newDeck = shuffle permutationList deck [] 
    print permutationList 
    print deck 
    print "-------------------------------------" 
    print newDeck 
+0

3 parçadan oluşan bir kart destesi tuttuğunuzu hayal edin, rastgele bir kart alıp masanın üzerine atın, sonra diğerine ve sonuncusu, şimdi tablonun bir araya getirilmiş kart listesi var, Yeni bir güverte kafası son kart atılır. https://en.wikipedia.org/wiki/Fisher-Yates_shuffle –

+2

Şimdiye kadar neler denediniz? Bu bana ev ödevi isteği gibi biraz okuyor. –

+0

kodun tamamı için güncellenmiş, bir poker sunucusu yazacağım opensource –

cevap

1

Permütasyonları oluşturmak için karmaşık bir yol seçtiniz, ancak sorun alanının gerektirdiği şey bu olabilir.

gerekli permütasyon listesi comprehensions tarafından oluşturulamaz ama bir damla eleman fonksiyonunu yazma

ilk olarak bazı basit yarar fonksiyonları ile yazılabilir

dropAt :: Int -> [a] -> [a] 
dropAt _ [] = [] 
dropAt n x = let (h,t) = splitAt n x in (init h) ++ t 

şimdi bu kendi toplama işlevini

pickAt :: [Int] -> [a] -> [a] 
pickAt _ [] = [] 
pickAt [] _ = [] 
pickAt (n:ns) xs = xs!!(n-1) : pickAt ns (dropAt n xs) 
kullanarak

, tersi sırada tersi sırasını verir, ters yönde çalıştır

> reverse $ pickAt [2,1,1] ['a','b','c'] 
"cab" 

> reverse $ pickAt [1,1,1] ['a','b','c'] 
"cba"