Haskell List Comprehensions listA listB - > listC

问题描述:

我有两个List元素ListA([String])和样本位置ListB([Int])如何使用列表解析创建新的ListC([String])?Haskell List Comprehensions listA listB - > listC

例如:

左边数总是更多的权利(见数组listB)

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 

更多的模板:

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 

这个功能是产生有效的数字序列(注意每左边的元素,它比前一个更多,至少每1个,即头是最大的元素)

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张牌组成的牌,你随机拿一张牌将它扔到桌子上,然后把它扔到桌子上,然后是最后一张桌子,现在桌子上有一堆混乱的牌,最后一张牌被扔出的新甲板头。这就像https://en.wikipedia.org/wiki/Fisher-Yates_shuffle –

+2

你到目前为止尝试过什么?这对我来说有点像家庭作业要求。 –

+0

已更新为完整的代码,我正在写一个扑克服务器,它将是开源 –

您选择了一种复杂的方式来创建排列,但也许这就是问题域的规定。

,所需的置换不能列表内涵被创建,但可以通过一些简单的实用功能

先写一降元件的功能被写入

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

现在用这个你自己采摘功能

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

尽管给你相反的顺序,但通过反向运行

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

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