[英]Haskell functions to randomly order a list not working properly (Homework) beginner
Only began using Haskell a couple of weeks ago - I am attempting to randomly shuffle a list of type Card by splitting the list into two at a random point int eh list (depending on an array of random integers produced by the randomList function) and swapping the order of these two parts a number of times, but the output is not at all random, and the parse only seems to be happening once, pretty desperate as I need it working and the deadline is tonight! 几周前才开始使用Haskell - 我试图通过将列表分成两个随机点列表(取决于randomList函数生成的随机整数数组)并交换,随机地随机洗牌类型Card列表这两个部分的顺序很多次,但输出完全不是随机的,而且解析似乎只发生过一次,非常绝望,因为我需要它工作,截止日期是今晚!
randomList :: (Random a) => (a,a) -> Int -> StdGen -> [a]
randomList bnds n = take n . randomRs bnds
randomise :: [Int] -> [Card] -> [Card]
randomise [] p = p
randomise (x : xs) p = do
randomise xs ((drop x p) ++ (take x p))
shuffle :: Int -> [Card] -> [Card]
shuffle r p = do
let g = mkStdGen r
randomise(randomList (1, (length p)-1) 500 g :: [Int]) p
You can just make a random number of permutations on your list. 您可以在列表中随机排列一些排列。 You can do it like: 你可以这样做:
import System.Random
import Data.List
shuffle xs = do
gen <- getStdGen
let (permNum,newGen) = randomR (0,fac (length xs) -1) gen
return $ permutation permNum xs
permutation
makes n
permutations on the (assumed sorted) list xs
. permutation
在(假定排序的)列表xs
上进行n
个排列。 When randomizing, xs
need not be sorted however. 随机化时,不需要对xs
进行排序。
fac
is just an implementation of the factorial function. fac
只是阶乘函数的一个实现。
shuffle
makes a random number and applies that many permutations to xs
. shuffle
产生一个随机数并将这许多排列应用于xs
。
It's a bit different from what you are trying to do, but it works wonders. 它与你想要的东西有点不同,但它可以创造奇迹。 I assumed you didn't need to explicitly use your proposed method. 我假设您不需要明确使用您提出的方法。 You will have to implement permutation
and fac
yourself though. 你必须自己实现permutation
和fac
。
For help on permutation
, you could look here . 有关permutation
帮助,你可以看看这里 。 It's a description to solve a Project Euler Problem, but you could use the same procedure to make n
permutations. 这是解决项目欧拉问题的描述,但您可以使用相同的过程来进行n
个排列。
EDIT: I don't know if anyone cares anymore, but I found another way to do it WAY easier: 编辑:我不知道是否有人关心,但我发现另一种方式做到更容易:
import System.Random
randPerm :: StdGen -> [a] -> [a]
randPerm _ [] = []
randPerm gen xs = let (n,newGen) = randomR (0,length xs -1) gen
front = xs !! n
in front : randPerm newGen (take n xs ++ drop (n+1) xs)
Quite late to the party, but a small improvement over the suggested solution is to use splitAt instead of take & drop: 聚会很晚,但对建议的解决方案的一个小改进是使用splitAt而不是take&drop:
shuffle :: [a] -> StdGen -> [a]
shuffle [] _ = []
shuffle list generator = let (index,newGenerator) = randomR (0,length list -1) generator
(listUntilIndex, element:listAfterIndex) = splitAt index list
in element : shuffle (listUntilIndex ++ listAfterIndex) newGenerator
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.