我必须在haskell中实现这个功能:
insertRandomNumber :: RandomGen g => [[Int]] -> g -> ([[Int]], g)
该函数在我的矩阵中的随机位置插入一个随机数。我只能在有0的位置插入。矩阵大小为4 x 4。我有这个:
insertRandomNumber :: RandomGen g => [[Int]] -> g -> ([[Int]], g)
insertRandomNumber mat g =
let (pos,_) = randomR (1,16) g
ok = free (pos `div` 4) (pos `mod` 4) mat
in if ok == True
then newmatrix pos mat
else insertRandomNumber mat g
问题是,如果第一个位置不是免费的,我的程序将阻止其他位置。 我希望你能给我一个如何使用randomgen将随机数插入免费随机位置的例子。
答案 0 :(得分:2)
您需要保留新的随机数生成器并传递它而不是旧的生成器。如果不这样做,则意味着您将始终在每次迭代中生成相同的pos
并永远循环。
在代码中:
let (pos,_) = randomR (1,16) g
在这里,您明确忽略了新的RNG状态。代替:
let (pos,newGen) = randomR (1,16) g
然后您传递了旧生成器,它将生成完全相同的pos
:
in if ok == True then newmatrix pos mat else insertRandomNumber mat g
相反,您应该传递新的生成器状态:
in if ok == True then newmatrix pos mat else insertRandomNumber mat newGen
答案 1 :(得分:0)
您可以将此问题分为三个部分:枚举包含0的所有索引,从中选择随机索引,并在所选索引处插入随机数。所以像这样:
insertRandomNumber :: RandomGen g => [[Int]] -> g -> ([[Int]], g)
insertRandomNumber mat g0 = case validPositions mat of
[] -> (mat, g0)
xs -> let (i,g1) = randomR (0, length xs - 1) g0
(v, g2) = randomR (1,100 :: Int) g1
in (replaceAt mat (xs !! i) v, g2)
我将让您编写函数validPositions
和replaceAt
。